/
setupNetwork.ts
102 lines (89 loc) · 3.4 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
import { setupMUDV2Network } from "@latticexyz/std-client";
import { createFastTxExecutor, createFaucetService, getSnapSyncRecords } from "@latticexyz/network";
import { getNetworkConfig } from "./getNetworkConfig";
import { defineContractComponents } from "./contractComponents";
import { world } from "./world";
import { Contract, Signer, utils } from "ethers";
import { JsonRpcProvider } from "@ethersproject/providers";
import { IWorld__factory } from "contracts/types/ethers-contracts/factories/IWorld__factory";
import { getTableIds } from "@latticexyz/common/deprecated";
import storeConfig from "contracts/mud.config";
export type SetupNetworkResult = Awaited<ReturnType<typeof setupNetwork>>;
export async function setupNetwork() {
const contractComponents = defineContractComponents(world);
const networkConfig = await getNetworkConfig();
const result = await setupMUDV2Network<typeof contractComponents, typeof storeConfig>({
networkConfig,
world,
contractComponents,
syncThread: "main",
storeConfig,
worldAbi: IWorld__factory.abi,
});
// Request drip from faucet
const signer = result.network.signer.get();
if (networkConfig.faucetServiceUrl && signer) {
const address = await signer.getAddress();
console.info("[Dev Faucet]: Player address -> ", address);
const faucet = createFaucetService(networkConfig.faucetServiceUrl);
const requestDrip = async () => {
const balance = await signer.getBalance();
console.info(`[Dev Faucet]: Player balance -> ${balance}`);
const lowBalance = balance?.lte(utils.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);
}
const provider = result.network.providers.get().json;
const signerOrProvider = signer ?? provider;
// Create a World contract instance
const worldContract = IWorld__factory.connect(networkConfig.worldAddress, signerOrProvider);
if (networkConfig.snapSync) {
const currentBlockNumber = await provider.getBlockNumber();
const tableRecords = await getSnapSyncRecords(
networkConfig.worldAddress,
getTableIds(storeConfig),
currentBlockNumber,
signerOrProvider
);
console.log(`Syncing ${tableRecords.length} records`);
result.startSync(tableRecords, currentBlockNumber);
} else {
result.startSync();
}
// Create a fast tx executor
const fastTxExecutor =
signer?.provider instanceof JsonRpcProvider
? await createFastTxExecutor(signer as Signer & { provider: JsonRpcProvider })
: null;
// TODO: infer this from fastTxExecute signature?
type BoundFastTxExecuteFn<C extends Contract> = <F extends keyof C>(
func: F,
args: Parameters<C[F]>,
options?: {
retryCount?: number;
}
) => Promise<ReturnType<C[F]>>;
function bindFastTxExecute<C extends Contract>(contract: C): BoundFastTxExecuteFn<C> {
return async function (...args) {
if (!fastTxExecutor) {
throw new Error("no signer");
}
const { tx } = await fastTxExecutor.fastTxExecute(contract, ...args);
return await tx;
};
}
return {
...result,
worldContract,
worldSend: bindFastTxExecute(worldContract),
fastTxExecutor,
};
}