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(world-modules): add callWithSignature #2592

Merged
merged 14 commits into from
Apr 3, 2024
2 changes: 1 addition & 1 deletion e2e/packages/contracts/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default defineWorld({
},
modules: [
{
name: "Unstable_DelegationWithSignatureModule",
name: "Unstable_CallWithSignatureModule",
root: true,
args: [],
},
Expand Down
108 changes: 0 additions & 108 deletions e2e/packages/sync-test/data/callRegisterDelegationWithSignature.ts

This file was deleted.

37 changes: 37 additions & 0 deletions e2e/packages/sync-test/data/callWithSignature.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Page } from "@playwright/test";
import { GetContractReturnType, PublicClient, WalletClient } from "viem";
import { AbiParametersToPrimitiveTypes, ExtractAbiFunction, ExtractAbiFunctionNames } from "abitype";
import CallWithSignatureAbi from "@latticexyz/world-modules/out/Unstable_CallWithSignatureSystem.sol/Unstable_CallWithSignatureSystem.abi.json";

type CallWithSignatureAbi = typeof CallWithSignatureAbi;

type WorldContract = GetContractReturnType<CallWithSignatureAbi, PublicClient, WalletClient>;

type WriteMethodName = ExtractAbiFunctionNames<CallWithSignatureAbi>;
type WriteMethod<TMethod extends WriteMethodName> = ExtractAbiFunction<CallWithSignatureAbi, TMethod>;
type WriteArgs<TMethod extends WriteMethodName> = AbiParametersToPrimitiveTypes<WriteMethod<TMethod>["inputs"]>;

export function callWithSignature(page: Page, args?: WriteArgs<"callWithSignature">) {
return page.evaluate(
([_args, _CallWithSignatureAbi]) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const walletClient = (window as any).walletClient as WalletClient;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const worldContract = (window as any).worldContract as WorldContract;

return walletClient
.writeContract({
address: worldContract.address,
abi: _CallWithSignatureAbi,
functionName: "callWithSignature",
args: _args,
})
.then((tx) => window["waitForTransaction"](tx))
.catch((error) => {
console.error(error);
throw new Error([`Error executing callWithSignature with args:`, JSON.stringify(_args), error].join("\n\n"));
});
},
[args, CallWithSignatureAbi],
);
}
1 change: 1 addition & 0 deletions e2e/packages/sync-test/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@latticexyz/store-sync": "link:../../../packages/store-sync",
"@latticexyz/utils": "link:../../../packages/utils",
"@latticexyz/world": "link:../../../packages/world",
"@latticexyz/world-modules": "link:../../../packages/world-modules",
"@viem/anvil": "^0.0.6",
"abitype": "1.0.0",
"chalk": "^5.2.0",
Expand Down
40 changes: 21 additions & 19 deletions e2e/packages/sync-test/registerDelegationWithSignature.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,22 @@ import { deployContracts, startViteServer, startBrowserAndPage, openClientWithRo
import { rpcHttpUrl } from "./setup/constants";
import { waitForInitialSync } from "./data/waitForInitialSync";
import { createBurnerAccount, resourceToHex, transportObserver } from "@latticexyz/common";
import { http, createWalletClient, ClientConfig } from "viem";
import { http, createWalletClient, ClientConfig, encodeFunctionData } from "viem";
import { mudFoundry } from "@latticexyz/common/chains";
import { encodeEntity } from "@latticexyz/store-sync/recs";
import { callPageFunction } from "./data/callPageFunction";
import worldConfig from "@latticexyz/world/mud.config";
import { worldToV1 } from "@latticexyz/world/config/v2";
import { delegationWithSignatureTypes } from "@latticexyz/world/internal";
import { callWithSignatureTypes } from "@latticexyz/world/internal";
import { getWorld } from "./data/getWorld";
import { callRegisterDelegationWithSignature } from "./data/callRegisterDelegationWithSignature";
import { callWithSignature } from "./data/callWithSignature";
import IWorldAbi from "../contracts/out/IWorld.sol/IWorld.abi.json";

const DELEGATOR_PRIVATE_KEY = "0x67bbd1575ecc79b3247c7d7b87a5bc533ccb6a63955a9fefdfaf75853f7cd543";

const worldConfigV1 = worldToV1(worldConfig);

describe("registerDelegationWithSignature", async () => {
describe("callWithSignature", async () => {
const asyncErrorHandler = createAsyncErrorHandler();
let webserver: ViteDevServer;
let browser: Browser;
Expand Down Expand Up @@ -60,38 +61,39 @@ describe("registerDelegationWithSignature", async () => {
});

const worldContract = await getWorld(page);
const systemId = resourceToHex({ type: "system", namespace: "", name: "Registration" });

// Declare delegation parameters
const delegatee = "0x7203e7ADfDF38519e1ff4f8Da7DCdC969371f377";
const delegationControlId = resourceToHex({ type: "system", namespace: "", name: "unlimited" });
const initCallData = "0x";

const callData = encodeFunctionData({
abi: IWorldAbi,
functionName: "registerDelegation",
args: [delegatee, delegationControlId, initCallData],
});

const nonce = 0n;

// Sign registration message
// Sign registration call message
const signature = await delegatorWalletClient.signTypedData({
domain: {
chainId: delegatorWalletClient.chain.id,
verifyingContract: worldContract.address,
},
types: delegationWithSignatureTypes,
primaryType: "Delegation",
types: callWithSignatureTypes,
primaryType: "Call",
message: {
delegatee,
delegationControlId,
initCallData,
delegator: delegator.address,
signer: delegator.address,
systemId,
callData,
nonce,
},
});

// Register the delegation
await callRegisterDelegationWithSignature(page, [
delegatee,
delegationControlId,
initCallData,
delegator.address,
signature,
]);
// Register a delegation
await callWithSignature(page, [delegator.address, systemId, callData, signature]);

// Expect delegation to have been created
const value = await callPageFunction(page, "getComponentValue", [
Expand Down
3 changes: 3 additions & 0 deletions e2e/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions packages/cli/src/utils/defaultModuleContracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import KeysWithValueModuleData from "@latticexyz/world-modules/out/KeysWithValue
import KeysInTableModuleData from "@latticexyz/world-modules/out/KeysInTableModule.sol/KeysInTableModule.json" assert { type: "json" };
import UniqueEntityModuleData from "@latticexyz/world-modules/out/UniqueEntityModule.sol/UniqueEntityModule.json" assert { type: "json" };
// eslint-disable-next-line max-len
import Unstable_DelegationWithSignatureModuleData from "@latticexyz/world-modules/out/Unstable_DelegationWithSignatureModule.sol/Unstable_DelegationWithSignatureModule.json" assert { type: "json" };
import Unstable_CallWithSignatureModuleData from "@latticexyz/world-modules/out/Unstable_CallWithSignatureModule.sol/Unstable_CallWithSignatureModule.json" assert { type: "json" };
import { Abi, Hex, size } from "viem";
import { findPlaceholders } from "./findPlaceholders";

Expand Down Expand Up @@ -30,10 +30,10 @@ export const defaultModuleContracts = [
deployedBytecodeSize: size(UniqueEntityModuleData.deployedBytecode.object as Hex),
},
{
name: "Unstable_DelegationWithSignatureModule",
abi: Unstable_DelegationWithSignatureModuleData.abi as Abi,
bytecode: Unstable_DelegationWithSignatureModuleData.bytecode.object as Hex,
placeholders: findPlaceholders(Unstable_DelegationWithSignatureModuleData.bytecode.linkReferences),
deployedBytecodeSize: size(Unstable_DelegationWithSignatureModuleData.deployedBytecode.object as Hex),
name: "Unstable_CallWithSignatureModule",
abi: Unstable_CallWithSignatureModuleData.abi as Abi,
bytecode: Unstable_CallWithSignatureModuleData.bytecode.object as Hex,
placeholders: findPlaceholders(Unstable_CallWithSignatureModuleData.bytecode.linkReferences),
deployedBytecodeSize: size(Unstable_CallWithSignatureModuleData.deployedBytecode.object as Hex),
},
];
8 changes: 4 additions & 4 deletions packages/world-modules/gas-report.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
[
{
"file": "test/DelegationWithSignatureModule.t.sol",
"file": "test/CallWithSignatureModule.t.sol",
"test": "testInstallRoot",
"name": "install delegation module",
"gasUsed": 689194
"gasUsed": 687912
},
{
"file": "test/DelegationWithSignatureModule.t.sol",
"file": "test/CallWithSignatureModule.t.sol",
"test": "testRegisterDelegationWithSignature",
"name": "register an unlimited delegation with signature",
"gasUsed": 117588
"gasUsed": 133222
},
{
"file": "test/ERC20.t.sol",
Expand Down
8 changes: 4 additions & 4 deletions packages/world-modules/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,9 @@ export default defineWorld({
* REGISTER DELEGATION WITH SIGNATURE MODULE
*
************************************************************************/
UserDelegationNonces: {
schema: { delegator: "address", nonce: "uint256" },
key: ["delegator"],
CallWithSignatureNonces: {
schema: { signer: "address", nonce: "uint256" },
key: ["signer"],
codegen: {
outputDirectory: "modules/delegation/tables",
},
Expand All @@ -291,6 +291,6 @@ export default defineWorld({
"PuppetFactorySystem",
"ERC20System",
"ERC721System",
"Unstable_DelegationWithSignatureSystem",
"Unstable_CallWithSignatureSystem",
],
});
2 changes: 1 addition & 1 deletion packages/world-modules/src/index.sol
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ import { Owners } from "./modules/erc721-puppet/tables/Owners.sol";
import { TokenApproval } from "./modules/erc721-puppet/tables/TokenApproval.sol";
import { OperatorApproval } from "./modules/erc721-puppet/tables/OperatorApproval.sol";
import { ERC721Registry } from "./modules/erc721-puppet/tables/ERC721Registry.sol";
import { UserDelegationNonces } from "./modules/delegation/tables/UserDelegationNonces.sol";
import { CallWithSignatureNonces } from "./modules/delegation/tables/CallWithSignatureNonces.sol";

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,25 @@ import { IBaseWorld } from "@latticexyz/world/src/codegen/interfaces/IBaseWorld.
import { Module } from "@latticexyz/world/src/Module.sol";
import { revertWithBytes } from "@latticexyz/world/src/revertWithBytes.sol";

import { UserDelegationNonces } from "./tables/UserDelegationNonces.sol";
import { Unstable_DelegationWithSignatureSystem } from "./Unstable_DelegationWithSignatureSystem.sol";
import { CallWithSignatureNonces } from "./tables/CallWithSignatureNonces.sol";
import { Unstable_CallWithSignatureSystem } from "./Unstable_CallWithSignatureSystem.sol";

import { DELEGATION_SYSTEM_ID } from "./constants.sol";

contract Unstable_DelegationWithSignatureModule is Module {
Unstable_DelegationWithSignatureSystem private immutable delegationWithSignatureSystem =
new Unstable_DelegationWithSignatureSystem();
contract Unstable_CallWithSignatureModule is Module {
Unstable_CallWithSignatureSystem private immutable callWithSignatureSystem = new Unstable_CallWithSignatureSystem();

function installRoot(bytes memory encodedArgs) public {
requireNotInstalled(__self, encodedArgs);

IBaseWorld world = IBaseWorld(_world());

// Register table
UserDelegationNonces._register();
CallWithSignatureNonces._register();

// Register system
(bool success, bytes memory data) = address(world).delegatecall(
abi.encodeCall(world.registerSystem, (DELEGATION_SYSTEM_ID, delegationWithSignatureSystem, true))
abi.encodeCall(world.registerSystem, (DELEGATION_SYSTEM_ID, callWithSignatureSystem, true))
);
if (!success) revertWithBytes(data);

Expand All @@ -35,8 +34,8 @@ contract Unstable_DelegationWithSignatureModule is Module {
world.registerRootFunctionSelector,
(
DELEGATION_SYSTEM_ID,
"registerDelegationWithSignature(address,bytes32,bytes,address,bytes)",
"registerDelegationWithSignature(address,bytes32,bytes,address,bytes)"
"callWithSignature(address,bytes32,bytes,bytes)",
"callWithSignature(address,bytes32,bytes,bytes)"
)
)
);
Expand Down
Loading
Loading