Skip to content

Commit

Permalink
fix(world): dedupe functions in getWorldAbi result (#3025)
Browse files Browse the repository at this point in the history
  • Loading branch information
karooolis authored Aug 13, 2024
1 parent 0783717 commit 5cee9a0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
12 changes: 9 additions & 3 deletions packages/world/ts/functionSignatureToAbiItem.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { AbiItem, parseAbiItem } from "viem";
import { AbiFunction, parseAbiItem } from "viem";

export function functionSignatureToAbiItem(functionSignature: string): AbiItem {
export function functionSignatureToAbiItem(functionSignature: string): AbiFunction {
const formattedSignature = `function ${functionSignature}`;
return parseAbiItem(formattedSignature);
const abiItem = parseAbiItem(formattedSignature);

if (abiItem.type !== "function") {
throw new Error(`Expected function signature, got ${abiItem.type}`);
}

return abiItem;
}
51 changes: 51 additions & 0 deletions packages/world/ts/getWorldAbi.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { describe, expect, it, vi } from "vitest";
import { createTestClient, http } from "viem";
import { getWorldAbi } from "./getWorldAbi";
import { foundry } from "viem/chains";

vi.mock("./getFunctions", () => {
const mockGetFunctionsResult = [{ signature: "setNumber(bool)" }, { signature: "batchCall((bytes32,bytes)[])" }];
const getFunctions = vi.fn();
getFunctions.mockResolvedValue(mockGetFunctionsResult);

return {
getFunctions,
};
});

describe("World ABI", () => {
it("should concat base and world ABI", async () => {
const client = createTestClient({
chain: foundry,
mode: "anvil",
transport: http(),
});

const abi = await getWorldAbi({
client,
worldAddress: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB",
fromBlock: 0n,
toBlock: 0n,
});

expect(abi).toContainEqual({
inputs: [
{
type: "bool",
},
],
name: "setNumber",
outputs: [],
stateMutability: "nonpayable",
type: "function",
});

expect(abi).not.toContainEqual({
name: "batchCall",
type: "function",
stateMutability: "nonpayable",
inputs: [{ type: "tuple[]", components: [{ type: "bytes32" }, { type: "bytes" }] }],
outputs: [],
});
});
});
11 changes: 9 additions & 2 deletions packages/world/ts/getWorldAbi.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Client, Abi, Address, getAddress } from "viem";
import { Client, Abi, AbiItem, AbiFunction, Address, getAddress, toFunctionSelector } from "viem";
import IBaseWorldAbi from "../out/IBaseWorld.sol/IBaseWorld.abi.json";
import { functionSignatureToAbiItem } from "./functionSignatureToAbiItem";
import { getFunctions } from "./getFunctions";

function isAbiFunction(abiItem: AbiItem): abiItem is AbiFunction {
return abiItem.type === "function";
}

export async function getWorldAbi({
client,
worldAddress,
Expand All @@ -20,7 +24,10 @@ export async function getWorldAbi({
fromBlock,
toBlock,
});
const worldFunctionsAbi = worldFunctions.map((func) => functionSignatureToAbiItem(func.signature));
const baseFunctionSelectors = (IBaseWorldAbi as Abi).filter(isAbiFunction).map(toFunctionSelector);
const worldFunctionsAbi = worldFunctions
.map((func) => functionSignatureToAbiItem(func.signature))
.filter((abiItem) => !baseFunctionSelectors.includes(toFunctionSelector(abiItem)));
const abi = [...IBaseWorldAbi, ...worldFunctionsAbi];

return abi;
Expand Down

0 comments on commit 5cee9a0

Please sign in to comment.