-
Notifications
You must be signed in to change notification settings - Fork 174
/
setupNetwork.ts
131 lines (117 loc) · 4.02 KB
/
setupNetwork.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
* The MUD client code is built on top of viem
* (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,
getContract,
} from "viem";
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, transportObserver, ContractWrite } from "@latticexyz/common";
import { transactionQueue, writeObserver } from "@latticexyz/common/actions";
import { Subject, share } from "rxjs";
/*
* Import our MUD config, which includes strong types for
* our tables and other config options. We use this to generate
* things like RECS components and get back strong types for them.
*
* See https://mud.dev/templates/typescript/contracts#mudconfigts
* for the source of this information.
*/
import mudConfig from "contracts/mud.config";
export type SetupNetworkResult = Awaited<ReturnType<typeof setupNetwork>>;
export async function setupNetwork() {
const networkConfig = await getNetworkConfig();
/*
* Create a viem public (read only) client
* (https://viem.sh/docs/clients/public.html)
*/
const clientOptions = {
chain: networkConfig.chain,
transport: transportObserver(fallback([webSocket(), http()])),
pollingInterval: 1000,
} as const satisfies ClientConfig;
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>();
/*
* Create a temporary wallet and a viem client for it
* (see https://viem.sh/docs/clients/wallet.html).
*/
const burnerAccount = createBurnerAccount(networkConfig.privateKey as Hex);
const burnerWalletClient = createWalletClient({
...clientOptions,
account: burnerAccount,
})
.extend(transactionQueue())
.extend(writeObserver({ onWrite: (write) => write$.next(write) }));
/*
* Create an object for communicating with the deployed World.
*/
const worldContract = getContract({
address: networkConfig.worldAddress as Hex,
abi: IWorldAbi,
client: { public: publicClient, wallet: burnerWalletClient },
});
/*
* Sync on-chain state into RECS and keeps our client in sync.
* Uses the MUD indexer if available, otherwise falls back
* to the viem publicClient to make RPC calls to fetch MUD
* events from the chain.
*/
const { tables, useStore, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToZustand({
config: mudConfig,
address: networkConfig.worldAddress as Hex,
publicClient,
startBlock: BigInt(networkConfig.initialBlockNumber),
});
/*
* If there is a faucet, request (test) ETH if you have
* less than 1 ETH. Repeat every 20 seconds to ensure you don't
* run out.
*/
if (networkConfig.faucetServiceUrl) {
const address = burnerAccount.address;
console.info("[Dev Faucet]: Player address -> ", address);
const faucet = createFaucetService(networkConfig.faucetServiceUrl);
const requestDrip = async () => {
const balance = await publicClient.getBalance({ address });
console.info(`[Dev Faucet]: Player balance -> ${balance}`);
const lowBalance = balance < parseEther("1");
if (lowBalance) {
console.info("[Dev Faucet]: Balance is low, dripping funds to player");
// Double drip
await faucet.dripDev({ address });
await faucet.dripDev({ address });
}
};
requestDrip();
// Request a drip every 20 seconds
setInterval(requestDrip, 20000);
}
return {
tables,
useStore,
publicClient,
walletClient: burnerWalletClient,
latestBlock$,
storedBlockLogs$,
waitForTransaction,
worldContract,
write$: write$.asObservable().pipe(share()),
};
}