Skip to content

Commit 26d2e3a

Browse files
karooolisfrolic
andauthored
feat(explorer): fetch deprecated world ABI (#3654)
Co-authored-by: Kevin Ingersoll <kingersoll@gmail.com>
1 parent ca7a36a commit 26d2e3a

4 files changed

Lines changed: 81 additions & 14 deletions

File tree

.changeset/old-carrots-listen.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
"@latticexyz/store-sync": patch
3+
---
4+
5+
`getWorldAbi()` now returns an ABI that is a combination of:
6+
7+
- base World ABI
8+
- system ABIs stored onchain with metadata module during deploy
9+
- world functions

packages/store-sync/src/world/getWorldAbi.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
import { createTestClient, http, parseAbi } from "viem";
22
import { foundry } from "viem/chains";
33
import { describe, expect, it, vi } from "vitest";
4-
import { mockError, mockMetadata, mockWorldFn } from "./test/mocks";
4+
import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json" assert { type: "json" };
5+
import { mockError, mockMetadata, mockWorldFn, mockWorldFn2 } from "./test/mocks";
6+
7+
vi.doMock("./getFunctions", () => {
8+
const mockGetFunctionsResult = [{ signature: "setNumber(bool)" }, { signature: "batchCall((bytes32,bytes)[])" }];
9+
const getFunctions = vi.fn();
10+
getFunctions.mockResolvedValue(mockGetFunctionsResult);
11+
12+
return {
13+
getFunctions,
14+
};
15+
});
516

617
vi.doMock("../getRecords", () => ({
718
getRecords: vi.fn().mockResolvedValue({
@@ -26,6 +37,6 @@ describe("World ABI", () => {
2637
toBlock: 0n,
2738
});
2839

29-
expect(abi).toEqual(parseAbi([mockWorldFn, mockError]));
40+
expect(abi).toEqual([...IBaseWorldAbi, ...parseAbi([mockWorldFn, mockError, mockWorldFn2])]);
3041
});
3142
});
Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
import { Client, Abi, Address, hexToString, parseAbi, stringToHex } from "viem";
1+
import {
2+
Client,
3+
Abi,
4+
Address,
5+
AbiItem,
6+
AbiFunction,
7+
getAddress,
8+
toFunctionSelector,
9+
hexToString,
10+
parseAbi,
11+
stringToHex,
12+
} from "viem";
13+
import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json" assert { type: "json" };
214
import metadataConfig from "@latticexyz/world-module-metadata/mud.config";
15+
import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem";
16+
import { isDefined } from "@latticexyz/common/utils";
17+
import { getFunctions } from "./getFunctions";
318
import { getRecords } from "../getRecords";
419

20+
function isAbiFunction(abiItem: AbiItem): abiItem is AbiFunction {
21+
return abiItem.type === "function";
22+
}
23+
524
export async function getWorldAbi({
625
client,
726
worldAddress,
@@ -17,19 +36,46 @@ export async function getWorldAbi({
1736
readonly indexerUrl?: string;
1837
readonly chainId?: number;
1938
}): Promise<Abi> {
20-
const { records } = await getRecords({
21-
table: metadataConfig.tables.metadata__ResourceTag,
22-
worldAddress,
23-
chainId,
24-
indexerUrl,
25-
client,
26-
fromBlock,
27-
toBlock,
28-
});
39+
const [worldFunctions, { records }] = await Promise.all([
40+
getFunctions({
41+
client,
42+
worldAddress: getAddress(worldAddress),
43+
fromBlock,
44+
toBlock,
45+
indexerUrl,
46+
chainId,
47+
}),
48+
getRecords({
49+
table: metadataConfig.tables.metadata__ResourceTag,
50+
worldAddress,
51+
chainId,
52+
indexerUrl,
53+
client,
54+
fromBlock,
55+
toBlock,
56+
}),
57+
]);
2958

30-
const abi = records
59+
const metadataAbi = records
3160
.filter(({ tag }) => tag === stringToHex("worldAbi", { size: 32 }))
3261
.flatMap(({ value }) => (value === "0x" ? [] : parseAbi(hexToString(value).split("\n"))));
3362

34-
return abi;
63+
const metadataFunctionSelectors = metadataAbi.filter(isAbiFunction).map(toFunctionSelector);
64+
const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector);
65+
const worldFunctionsAbi = worldFunctions
66+
.map((func) => {
67+
try {
68+
return functionSignatureToAbiItem(func.signature);
69+
} catch (error) {
70+
console.error(error);
71+
}
72+
})
73+
.filter(isDefined)
74+
.filter(
75+
(abiItem) =>
76+
!baseFunctionSelectors.includes(toFunctionSelector(abiItem)) &&
77+
!metadataFunctionSelectors.includes(toFunctionSelector(abiItem)),
78+
);
79+
80+
return [...(IBaseWorldAbi as Abi), ...metadataAbi, ...worldFunctionsAbi];
3581
}

packages/store-sync/src/world/test/mocks.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const mockSystem3Id = stringToHex("system3", { size: 32 });
77
export const mockSystem1Fn = "function systemFn(uint256 arg1, bool arg2) pure returns (uint256)";
88
export const mockSystem2Fn = "function systemFn2(uint256 arg1, bool arg2) pure returns (uint256)";
99
export const mockWorldFn = "function test_WorldFunction(uint256 arg1, bool arg2) pure returns (uint256)";
10+
export const mockWorldFn2 = "function setNumber(bool)";
1011
export const mockError = "error Error(string message)";
1112

1213
export const mockMetadata = [

0 commit comments

Comments
 (0)