Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(common): add viem actions that work the same as the current wrappers #2347

Merged
merged 20 commits into from
Feb 29, 2024
Merged
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/common/package.json
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
"type": "module",
"exports": {
".": "./dist/index.js",
"./actions": "./dist/actions.js",
"./chains": "./dist/chains.js",
"./codegen": "./dist/codegen.js",
"./errors": "./dist/errors.js",
@@ -23,6 +24,9 @@
"index": [
"./src/index.ts"
],
"actions": [
"./src/actions/index.ts"
],
"chains": [
"./src/chains/index.ts"
],
2 changes: 2 additions & 0 deletions packages/common/src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./transactionQueue";
export * from "./writeObserver";
14 changes: 14 additions & 0 deletions packages/common/src/actions/transactionQueue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import type { Transport, Chain, Account, WalletActions, WalletClient } from "viem";
import { writeContract as mud_writeContract } from "../writeContract";
import { sendTransaction as mud_sendTransaction } from "../sendTransaction";

export const transactionQueue = <TChain extends Chain, TAccount extends Account>(): ((
holic marked this conversation as resolved.
Show resolved Hide resolved
client: WalletClient<Transport, TChain, TAccount>
) => Pick<WalletActions<TChain, TAccount>, "writeContract" | "sendTransaction">) => {
return (client) => ({
// Applies to: `client.writeContract`, `getContract(client, ...).write`
writeContract: (args) => mud_writeContract(client, args),
// Applies to: `client.sendTransaction`
sendTransaction: (args) => mud_sendTransaction(client, args),
holic marked this conversation as resolved.
Show resolved Hide resolved
});
};
34 changes: 34 additions & 0 deletions packages/common/src/actions/writeObserver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type {
WriteContractParameters,
Transport,
Chain,
Account,
WalletActions,
WalletClient,
WriteContractReturnType,
} from "viem";
import { getAction } from "viem/utils";
import { writeContract } from "viem/actions";
import { type ContractWrite } from "../getContract";

type WriteObserverParameters = { onWrite: (write: ContractWrite) => void };

export const writeObserver = <TChain extends Chain, TAccount extends Account>({
onWrite,
}: WriteObserverParameters): ((
client: WalletClient<Transport, TChain, TAccount>
) => Pick<WalletActions<TChain, TAccount>, "writeContract">) => {
let nextWriteId = 0;

return (client) => ({
// Applies to: `client.writeContract`, `getContract(client, ...).write`
writeContract: (args): Promise<WriteContractReturnType> => {
const result = getAction(client, writeContract, "writeContract")(args);

const id = `${client.chain.id}:${client.account.address}:${nextWriteId++}`;
onWrite({ id, request: args as WriteContractParameters, result });

return result;
},
});
};
32 changes: 22 additions & 10 deletions templates/react/packages/client/src/mud/setupNetwork.ts
Original file line number Diff line number Diff line change
@@ -3,12 +3,23 @@
* (https://viem.sh/docs/getting-started.html).
* This line imports the functions we need from it.
*/
import { createPublicClient, fallback, webSocket, http, createWalletClient, Hex, parseEther, ClientConfig } from "viem";
import {
createPublicClient,
fallback,
webSocket,
http,
createWalletClient,
Hex,
parseEther,
ClientConfig,
getContract,
} from "viem";
holic marked this conversation as resolved.
Show resolved Hide resolved
import { createFaucetService } from "@latticexyz/services/faucet";
import { syncToZustand } from "@latticexyz/store-sync/zustand";
import { getNetworkConfig } from "./getNetworkConfig";
import IWorldAbi from "contracts/out/IWorld.sol/IWorld.abi.json";
import { createBurnerAccount, getContract, transportObserver, ContractWrite } from "@latticexyz/common";
import { createBurnerAccount, transportObserver, ContractWrite } from "@latticexyz/common";
import { transactionQueue, writeObserver } from "@latticexyz/common/actions";
import { Subject, share } from "rxjs";

/*
@@ -38,6 +49,12 @@ export async function setupNetwork() {

const publicClient = createPublicClient(clientOptions);

/*
* Create an observable for contract writes that we can
* pass into MUD dev tools for transaction observability.
*/
const write$ = new Subject<ContractWrite>();
holic marked this conversation as resolved.
Show resolved Hide resolved

/*
* Create a temporary wallet and a viem client for it
* (see https://viem.sh/docs/clients/wallet.html).
@@ -46,13 +63,9 @@ export async function setupNetwork() {
const burnerWalletClient = createWalletClient({
...clientOptions,
account: burnerAccount,
});

/*
* Create an observable for contract writes that we can
* pass into MUD dev tools for transaction observability.
*/
const write$ = new Subject<ContractWrite>();
})
.extend(transactionQueue())
.extend(writeObserver({ onWrite: (write) => write$.next(write) }));
holic marked this conversation as resolved.
Show resolved Hide resolved

/*
* Create an object for communicating with the deployed World.
@@ -61,7 +74,6 @@ export async function setupNetwork() {
address: networkConfig.worldAddress as Hex,
abi: IWorldAbi,
client: { public: publicClient, wallet: burnerWalletClient },
onWrite: (write) => write$.next(write),
});

/*