diff --git a/.changeset/smart-account-package.md b/.changeset/smart-account-package.md new file mode 100644 index 00000000000..215a74ddeb1 --- /dev/null +++ b/.changeset/smart-account-package.md @@ -0,0 +1,25 @@ +--- +"@towns-protocol/smart-account": patch +--- + +Introduced ERC-4337 modular smart account SDK with viem integration, account type detection, batch operations support, and ReplaySafeHash signature protection. + +```typescript +import { createBundlerClient } from "viem/account-abstraction"; +import { toModularSmartAccount } from "@towns-protocol/smart-account/create2"; + +const account = await toModularSmartAccount({ + client: publicClient, + owner: localAccount, +}); + +const bundlerClient = createBundlerClient({ + client: publicClient, + transport: http("https://your-bundler-url.com"), +}); + +const userOpHash = await bundlerClient.sendUserOperation({ + account, + calls: [{ to: recipient, value: parseEther("0.1") }], +}); +``` diff --git a/bun.lock b/bun.lock index 863b153af0f..423a593aad1 100644 --- a/bun.lock +++ b/bun.lock @@ -43,7 +43,7 @@ }, "packages/bot": { "name": "@towns-protocol/bot", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@bufbuild/protobuf": "^2.9.0", "@connectrpc/connect-node": "^2.1.0", @@ -53,6 +53,7 @@ "@towns-protocol/proto": "workspace:^", "@towns-protocol/sdk": "workspace:^", "@towns-protocol/sdk-crypto": "workspace:^", + "@towns-protocol/smart-account": "workspace:^", "@towns-protocol/utils": "workspace:^", "@towns-protocol/web3": "workspace:^", "ethers": "^5.8.0", @@ -87,7 +88,7 @@ }, "packages/contracts": { "name": "@towns-protocol/contracts", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@erc6900/reference-implementation": "github:erc6900/reference-implementation#v0.8.0", "@ethereum-attestation-service/eas-contracts": "^1.8.0", @@ -120,7 +121,7 @@ }, "packages/create-towns-protocol-app": { "name": "create-towns-protocol-app", - "version": "0.0.455", + "version": "1.0.3", "bin": "index.js", "dependencies": { "jsonc-parser": "^3.3.1", @@ -147,7 +148,7 @@ }, "packages/encryption": { "name": "@towns-protocol/encryption", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@bufbuild/protobuf": "^2.9.0", "@towns-protocol/olm": "3.2.28", @@ -177,7 +178,7 @@ }, "packages/eslint-config": { "name": "@towns-protocol/eslint-config", - "version": "0.0.455", + "version": "1.0.3", }, "packages/examples/bot-quickstart": { "name": "@towns-protocol/example-bot-quickstart", @@ -204,7 +205,7 @@ }, "packages/generated": { "name": "@towns-protocol/generated", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@ethersproject/abi": "^5.8.0", "@ethersproject/providers": "^5.8.0", @@ -311,7 +312,7 @@ }, "packages/prettier-config": { "name": "@towns-protocol/prettier-config", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "prettier-plugin-solidity": "^1.4.2", }, @@ -321,7 +322,7 @@ }, "packages/proto": { "name": "@towns-protocol/proto", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@bufbuild/protobuf": "^2.9.0", }, @@ -338,7 +339,7 @@ }, "packages/react-sdk": { "name": "@towns-protocol/react-sdk", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@towns-protocol/proto": "workspace:^", "@towns-protocol/sdk": "workspace:^", @@ -373,7 +374,7 @@ }, "packages/rpc-connector": { "name": "@towns-protocol/rpc-connector", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@connectrpc/connect": "^2.1.0", }, @@ -403,7 +404,7 @@ }, "packages/sdk": { "name": "@towns-protocol/sdk", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@bufbuild/protobuf": "^2.9.0", "@connectrpc/connect": "^2.1.0", @@ -450,7 +451,7 @@ }, "packages/sdk-crypto": { "name": "@towns-protocol/sdk-crypto", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@towns-protocol/encryption": "workspace:^", "@towns-protocol/proto": "workspace:^", @@ -471,6 +472,19 @@ "vitest": "^3.2.3", }, }, + "packages/smart-account": { + "name": "@towns-protocol/smart-account", + "version": "0.0.1", + "dependencies": { + "viem": "^2.29.3", + }, + "devDependencies": { + "@towns-protocol/generated": "workspace:^", + "permissionless": "^0.2.57", + "typescript": "~5.8.3", + "vitest": "^3.2.3", + }, + }, "packages/stream-metadata": { "name": "@towns-protocol/stream-metadata", "version": "0.0.0", @@ -588,7 +602,7 @@ }, "packages/towns-bot-cli": { "name": "towns-bot", - "version": "0.0.455", + "version": "1.0.3", "bin": "index.js", "dependencies": { "@bufbuild/protobuf": "^2.9.0", @@ -622,7 +636,7 @@ }, "packages/utils": { "name": "@towns-protocol/utils", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@bufbuild/protobuf": "^2.9.0", "@ethereumjs/util": "^10.0.0", @@ -645,7 +659,7 @@ }, "packages/web3": { "name": "@towns-protocol/web3", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@isaacs/ttlcache": "^1.4.1", "@towns-protocol/generated": "workspace:^", @@ -674,7 +688,7 @@ }, "packages/xchain-monitor": { "name": "@towns-protocol/xchain-monitor", - "version": "0.0.455", + "version": "1.0.3", "dependencies": { "@towns-protocol/generated": "workspace:^", "@towns-protocol/web3": "workspace:^", @@ -727,27 +741,27 @@ "@aws-crypto/util": ["@aws-crypto/util@5.2.0", "", { "dependencies": { "@aws-sdk/types": "^3.222.0", "@smithy/util-utf8": "^2.0.0", "tslib": "^2.6.2" } }, "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ=="], - "@aws-sdk/client-cloudfront": ["@aws-sdk/client-cloudfront@3.965.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.965.0", "@aws-sdk/credential-provider-node": "3.965.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.965.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.965.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-DKkh7TaOhETwoJrZ6Z2Es57oPD2IAIr1JkAwUtYFt+HMN0s4FL/EuZrN78N3DUJCFFeDCR3PaBHEvJ4mGEmJIw=="], + "@aws-sdk/client-cloudfront": ["@aws-sdk/client-cloudfront@3.966.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.966.0", "@aws-sdk/credential-provider-node": "3.966.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.966.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.966.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.1", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.2", "@smithy/middleware-retry": "^4.4.18", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.17", "@smithy/util-defaults-mode-node": "^4.2.20", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/util-waiter": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-SFaV3NJmedINeJYjJ8Kxwjbq5nyjSeZeL4na/RKMQjyaFZzzVNdGEsgvRf9NF+meVc5Ba8ov9oIS/rAJzfWDtQ=="], - "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.965.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.965.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.965.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.965.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-iv2tr+n4aZ+nPUFFvG00hISPuEd4DU+1/Q8rPAYKXsM+vEPJ2nAnP5duUOa2fbOLIUCRxX3dcQaQaghVHDHzQw=="], + "@aws-sdk/client-sso": ["@aws-sdk/client-sso@3.966.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.966.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.966.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.966.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.1", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.2", "@smithy/middleware-retry": "^4.4.18", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.17", "@smithy/util-defaults-mode-node": "^4.2.20", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-hQZDQgqRJclALDo9wK+bb5O+VpO8JcjImp52w9KPSz9XveNRgE9AYfklRJd8qT2Bwhxe6IbnqYEino2wqUMA1w=="], - "@aws-sdk/core": ["@aws-sdk/core@3.965.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@aws-sdk/xml-builder": "3.965.0", "@smithy/core": "^3.20.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/signature-v4": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-aq9BhQxdHit8UUJ9C0im9TtuKeK0pT6NXmNJxMTCFeStI7GG7ImIsSislg3BZTIifVg1P6VLdzMyz9de85iutQ=="], + "@aws-sdk/core": ["@aws-sdk/core@3.966.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@aws-sdk/xml-builder": "3.965.0", "@smithy/core": "^3.20.1", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/signature-v4": "^5.3.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-QaRVBHD1prdrFXIeFAY/1w4b4S0EFyo/ytzU+rCklEjMRT7DKGXGoHXTWLGz+HD7ovlS5u+9cf8a/LeSOEMzww=="], - "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-mdGnaIjMxTIjsb70dEj3VsWPWpoq1V5MWzBSfJq2H8zgMBXjn6d5/qHP8HMf53l9PrsgqzMpXGv3Av549A2x1g=="], + "@aws-sdk/credential-provider-env": ["@aws-sdk/credential-provider-env@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-sxVKc9PY0SH7jgN/8WxhbKQ7MWDIgaJv1AoAKJkhJ+GM5r09G5Vb2Vl8ALYpsy+r8b+iYpq5dGJj8k2VqxoQMg=="], - "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/node-http-handler": "^4.4.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-YuGQel9EgA/z25oeLM+GYYQS750+8AESvr7ZEmVnRPL0sg+K3DmGqdv+9gFjFd0UkLjTlC/jtbP2cuY6UcPiHQ=="], + "@aws-sdk/credential-provider-http": ["@aws-sdk/credential-provider-http@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/node-http-handler": "^4.4.7", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-VTJDP1jOibVtc5pn5TNE12rhqOO/n10IjkoJi8fFp9BMfmh3iqo70Ppvphz/Pe/R9LcK5Z3h0Z4EB9IXDR6kag=="], - "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/credential-provider-env": "3.965.0", "@aws-sdk/credential-provider-http": "3.965.0", "@aws-sdk/credential-provider-login": "3.965.0", "@aws-sdk/credential-provider-process": "3.965.0", "@aws-sdk/credential-provider-sso": "3.965.0", "@aws-sdk/credential-provider-web-identity": "3.965.0", "@aws-sdk/nested-clients": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-xRo72Prer5s0xYVSCxCymVIRSqrVlevK5cmU0GWq9yJtaBNpnx02jwdJg80t/Ni7pgbkQyFWRMcq38c1tc6M/w=="], + "@aws-sdk/credential-provider-ini": ["@aws-sdk/credential-provider-ini@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/credential-provider-env": "3.966.0", "@aws-sdk/credential-provider-http": "3.966.0", "@aws-sdk/credential-provider-login": "3.966.0", "@aws-sdk/credential-provider-process": "3.966.0", "@aws-sdk/credential-provider-sso": "3.966.0", "@aws-sdk/credential-provider-web-identity": "3.966.0", "@aws-sdk/nested-clients": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-4oQKkYMCUx0mffKuH8LQag1M4Fo5daKVmsLAnjrIqKh91xmCrcWlAFNMgeEYvI1Yy125XeNSaFMfir6oNc2ODA=="], - "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/nested-clients": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-43/H8Qku8LHyugbhLo8kjD+eauhybCeVkmrnvWl8bXNHJP7xi1jCdtBQJKKJqiIHZws4MOEwkji8kFdAVRCe6g=="], + "@aws-sdk/credential-provider-login": ["@aws-sdk/credential-provider-login@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/nested-clients": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-wD1KlqLyh23Xfns/ZAPxebwXixoJJCuDbeJHFrLDpP4D4h3vA2S8nSFgBSFR15q9FhgRfHleClycf6g5K4Ww6w=="], - "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.965.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.965.0", "@aws-sdk/credential-provider-http": "3.965.0", "@aws-sdk/credential-provider-ini": "3.965.0", "@aws-sdk/credential-provider-process": "3.965.0", "@aws-sdk/credential-provider-sso": "3.965.0", "@aws-sdk/credential-provider-web-identity": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-cRxmMHF+Zh2lkkkEVduKl+8OQdtg/DhYA69+/7SPSQURlgyjFQGlRQ58B7q8abuNlrGT3sV+UzeOylZpJbV61Q=="], + "@aws-sdk/credential-provider-node": ["@aws-sdk/credential-provider-node@3.966.0", "", { "dependencies": { "@aws-sdk/credential-provider-env": "3.966.0", "@aws-sdk/credential-provider-http": "3.966.0", "@aws-sdk/credential-provider-ini": "3.966.0", "@aws-sdk/credential-provider-process": "3.966.0", "@aws-sdk/credential-provider-sso": "3.966.0", "@aws-sdk/credential-provider-web-identity": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-7QCOERGddMw7QbjE+LSAFgwOBpPv4px2ty0GCK7ZiPJGsni2EYmM4TtYnQb9u1WNHmHqIPWMbZR0pKDbyRyHlQ=="], - "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-gmkPmdiR0yxnTzLPDb7rwrDhGuCUjtgnj8qWP+m0gSz/W43rR4jRPVEf6DUX2iC+ImQhxo3NFhuB3V42Kzo3TQ=="], + "@aws-sdk/credential-provider-process": ["@aws-sdk/credential-provider-process@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-q5kCo+xHXisNbbPAh/DiCd+LZX4wdby77t7GLk0b2U0/mrel4lgy6o79CApe+0emakpOS1nPZS7voXA7vGPz4w=="], - "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.965.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.965.0", "@aws-sdk/core": "3.965.0", "@aws-sdk/token-providers": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-N01AYvtCqG3Wo/s/LvYt19ity18/FqggiXT+elAs3X9Om/Wfx+hw9G+i7jaDmy+/xewmv8AdQ2SK5Q30dXw/Fw=="], + "@aws-sdk/credential-provider-sso": ["@aws-sdk/credential-provider-sso@3.966.0", "", { "dependencies": { "@aws-sdk/client-sso": "3.966.0", "@aws-sdk/core": "3.966.0", "@aws-sdk/token-providers": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-Rv5aEfbpqsQZzxpX2x+FbSyVFOE3Dngome+exNA8jGzc00rrMZEUnm3J3yAsLp/I2l7wnTfI0r2zMe+T9/nZAQ=="], - "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/nested-clients": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-T4gMZ2JzXnfxe1oTD+EDGLSxFfk1+WkLZdiHXEMZp8bFI1swP/3YyDFXI+Ib9Uq1JhnAmrCXtOnkicKEhDkdhQ=="], + "@aws-sdk/credential-provider-web-identity": ["@aws-sdk/credential-provider-web-identity@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/nested-clients": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-Yv1lc9iic9xg3ywMmIAeXN1YwuvfcClLVdiF2y71LqUgIOupW8B8my84XJr6pmOQuKzZa++c2znNhC9lGsbKyw=="], "@aws-sdk/middleware-host-header": ["@aws-sdk/middleware-host-header@3.965.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-SfpSYqoPOAmdb3DBsnNsZ0vix+1VAtkUkzXM79JL3R5IfacpyKE2zytOgVAQx/FjhhlpSTwuXd+LRhUEVb3MaA=="], @@ -755,13 +769,13 @@ "@aws-sdk/middleware-recursion-detection": ["@aws-sdk/middleware-recursion-detection@3.965.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@aws/lambda-invoke-store": "^0.2.2", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-6dvD+18Ni14KCRu+tfEoNxq1sIGVp9tvoZDZ7aMvpnA7mDXuRLrOjRQ/TAZqXwr9ENKVGyxcPl0cRK8jk1YWjA=="], - "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@smithy/core": "^3.20.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-RBEYVGgu/WeAt+H/qLrGc+t8LqAUkbyvh3wBfTiuAD+uBcWsKnvnB1iSBX75FearC0fmoxzXRUc0PMxMdqpjJQ=="], + "@aws-sdk/middleware-user-agent": ["@aws-sdk/middleware-user-agent@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@smithy/core": "^3.20.1", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-MvGoy0vhMluVpSB5GaGJbYLqwbZfZjwEZhneDHdPhgCgQqmCtugnYIIjpUw7kKqWGsmaMQmNEgSFf1zYYmwOyg=="], - "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.965.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.965.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.965.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.965.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.0", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.1", "@smithy/middleware-retry": "^4.4.17", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.16", "@smithy/util-defaults-mode-node": "^4.2.19", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-muNVUjUEU+/KLFrLzQ8PMXyw4+a/MP6t4GIvwLtyx/kH0rpSy5s0YmqacMXheuIe6F/5QT8uksXGNAQenitkGQ=="], + "@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.966.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.966.0", "@aws-sdk/middleware-host-header": "3.965.0", "@aws-sdk/middleware-logger": "3.965.0", "@aws-sdk/middleware-recursion-detection": "3.965.0", "@aws-sdk/middleware-user-agent": "3.966.0", "@aws-sdk/region-config-resolver": "3.965.0", "@aws-sdk/types": "3.965.0", "@aws-sdk/util-endpoints": "3.965.0", "@aws-sdk/util-user-agent-browser": "3.965.0", "@aws-sdk/util-user-agent-node": "3.966.0", "@smithy/config-resolver": "^4.4.5", "@smithy/core": "^3.20.1", "@smithy/fetch-http-handler": "^5.3.8", "@smithy/hash-node": "^4.2.7", "@smithy/invalid-dependency": "^4.2.7", "@smithy/middleware-content-length": "^4.2.7", "@smithy/middleware-endpoint": "^4.4.2", "@smithy/middleware-retry": "^4.4.18", "@smithy/middleware-serde": "^4.2.8", "@smithy/middleware-stack": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/node-http-handler": "^4.4.7", "@smithy/protocol-http": "^5.3.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.17", "@smithy/util-defaults-mode-node": "^4.2.20", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-FRzAWwLNoKiaEWbYhnpnfartIdOgiaBLnPcd3uG1Io+vvxQUeRPhQIy4EfKnT3AuA+g7gzSCjMG2JKoJOplDtQ=="], "@aws-sdk/region-config-resolver": ["@aws-sdk/region-config-resolver@3.965.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@smithy/config-resolver": "^4.4.5", "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-RoMhu9ly2B0coxn8ctXosPP2WmDD0MkQlZGLjoYHQUOCBmty5qmCxOqBmBDa6wbWbB8xKtMQ/4VXloQOgzjHXg=="], - "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.965.0", "", { "dependencies": { "@aws-sdk/core": "3.965.0", "@aws-sdk/nested-clients": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-aR0qxg0b8flkXJVE+CM1gzo7uJ57md50z2eyCwofC0QIz5Y0P7/7vvb9/dmUQt6eT9XRN5iRcUqq2IVxVDvJOw=="], + "@aws-sdk/token-providers": ["@aws-sdk/token-providers@3.966.0", "", { "dependencies": { "@aws-sdk/core": "3.966.0", "@aws-sdk/nested-clients": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/property-provider": "^4.2.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-8k5cBTicTGYJHhKaweO4gL4fud1KDnLS5fByT6/Xbiu59AxYM4E/h3ds+3jxDMnniCE3gIWpEnyfM9khtmw2lA=="], "@aws-sdk/types": ["@aws-sdk/types@3.965.0", "", { "dependencies": { "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-jvodoJdMavvg8faN7co58vVJRO5MVep4JFPRzUNCzpJ98BDqWDk/ad045aMJcmxkLzYLS2UAnUmqjJ/tUPNlzQ=="], @@ -771,11 +785,11 @@ "@aws-sdk/util-user-agent-browser": ["@aws-sdk/util-user-agent-browser@3.965.0", "", { "dependencies": { "@aws-sdk/types": "3.965.0", "@smithy/types": "^4.11.0", "bowser": "^2.11.0", "tslib": "^2.6.2" } }, "sha512-Xiza/zMntQGpkd2dETQeAK8So1pg5+STTzpcdGWxj5q0jGO5ayjqT/q1Q7BrsX5KIr6PvRkl9/V7lLCv04wGjQ=="], - "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.965.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.965.0", "@aws-sdk/types": "3.965.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-kokIHUfNT3/P55E4fUJJrFHuuA9BbjFKUIxoLrd3UaRfdafT0ScRfg2eaZie6arf60EuhlUIZH0yALxttMEjxQ=="], + "@aws-sdk/util-user-agent-node": ["@aws-sdk/util-user-agent-node@3.966.0", "", { "dependencies": { "@aws-sdk/middleware-user-agent": "3.966.0", "@aws-sdk/types": "3.965.0", "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" }, "peerDependencies": { "aws-crt": ">=1.0.0" }, "optionalPeers": ["aws-crt"] }, "sha512-vPPe8V0GLj+jVS5EqFz2NUBgWH35favqxliUOvhp8xBdNRkEjiZm5TqitVtFlxS4RrLY3HOndrWbrP5ejbwl1Q=="], "@aws-sdk/xml-builder": ["@aws-sdk/xml-builder@3.965.0", "", { "dependencies": { "@smithy/types": "^4.11.0", "fast-xml-parser": "5.2.5", "tslib": "^2.6.2" } }, "sha512-Tcod25/BTupraQwtb+Q+GX8bmEZfxIFjjJ/AvkhUZsZlkPeVluzq1uu3Oeqf145DCdMjzLIN6vab5MrykbDP+g=="], - "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.2", "", {}, "sha512-C0NBLsIqzDIae8HFw9YIrIBsbc0xTiOtt7fAukGPnqQ/+zZNaq+4jhuccltK0QuWHBnNm/a6kLIRA6GFiM10eg=="], + "@aws/lambda-invoke-store": ["@aws/lambda-invoke-store@0.2.3", "", {}, "sha512-oLvsaPMTBejkkmHhjf09xTgk71mOqyr/409NKhRIL08If7AhVfUsJhVsx386uJaqNd42v9kWamQ9lFbkoC2dYw=="], "@axelar-network/axelar-gmp-sdk-solidity": ["@axelar-network/axelar-gmp-sdk-solidity@5.10.0", "", {}, "sha512-s8SImALvYB+5AeiT3tbfWNBI2Mhqw1x91i/zM3DNpVUCnAR2HKtsB9T84KnUn/OJjOVgb4h0lv7q9smeYniRPw=="], @@ -883,7 +897,7 @@ "@changesets/write": ["@changesets/write@0.4.0", "", { "dependencies": { "@changesets/types": "^6.1.0", "fs-extra": "^7.0.1", "human-id": "^4.1.1", "prettier": "^2.7.1" } }, "sha512-CdTLvIOPiCNuH71pyDu3rA+Q0n65cmAbXnwWH84rKGiFumFzkmHNT8KHTMEchcxN+Kl8I54xGUhJ7l3E7X396Q=="], - "@coinbase/cdp-sdk": ["@coinbase/cdp-sdk@1.41.0", "", { "dependencies": { "@solana-program/system": "^0.10.0", "@solana-program/token": "^0.9.0", "@solana/kit": "^5.1.0", "@solana/web3.js": "^1.98.1", "abitype": "1.0.6", "axios": "^1.12.2", "axios-retry": "^4.5.0", "jose": "^6.0.8", "md5": "^2.3.0", "uncrypto": "^0.1.3", "viem": "^2.21.26", "zod": "^3.24.4" } }, "sha512-9EhtD9XvnIYoS5LAQfVh3w9Rnp2gqh7tQvjwWwmPXLSeqYefS/13r6XzV+o/3M12LQIrQ4PaWmQ4+jXiFgQw2A=="], + "@coinbase/cdp-sdk": ["@coinbase/cdp-sdk@1.43.0", "", { "dependencies": { "@solana-program/system": "^0.10.0", "@solana-program/token": "^0.9.0", "@solana/kit": "^5.1.0", "@solana/web3.js": "^1.98.1", "abitype": "1.0.6", "axios": "^1.12.2", "axios-retry": "^4.5.0", "jose": "^6.0.8", "md5": "^2.3.0", "uncrypto": "^0.1.3", "viem": "^2.21.26", "zod": "^3.24.4" } }, "sha512-Fre1tvoIi4HAoC8/PgBoLsuZ9mt7K0R50EEC6i+6FaipW7oO3MABCx+vGAcM7EpcbVa7E6hTFe2/a0UdoajvYQ=="], "@coinbase/wallet-sdk": ["@coinbase/wallet-sdk@4.3.6", "", { "dependencies": { "@noble/hashes": "1.4.0", "clsx": "1.2.1", "eventemitter3": "5.0.1", "idb-keyval": "6.2.1", "ox": "0.6.9", "preact": "10.24.2", "viem": "^2.27.2", "zustand": "5.0.3" } }, "sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA=="], @@ -991,7 +1005,7 @@ "@cspell/dict-node": ["@cspell/dict-node@5.0.8", "", {}, "sha512-AirZcN2i84ynev3p2/1NCPEhnNsHKMz9zciTngGoqpdItUb2bDt1nJBjwlsrFI78GZRph/VaqTVFwYikmncpXg=="], - "@cspell/dict-npm": ["@cspell/dict-npm@5.2.28", "", {}, "sha512-tjnBjpIJsgYMTqNSrL5YlvFcXdtc7gkrL1ZI+MPSJSYOoJ78yeegS5UrIIbH3VrQtbNYSS8YhlEVF+xN0G4E8Q=="], + "@cspell/dict-npm": ["@cspell/dict-npm@5.2.29", "", {}, "sha512-ZAef8JpYmbuHFT1zekj/YyImLPvZevjECw663EmG5GPePyNo4AfH8Dd2fFhaOyQ3P5I5LrkAhGwypnOfUxcssw=="], "@cspell/dict-php": ["@cspell/dict-php@4.1.1", "", {}, "sha512-EXelI+4AftmdIGtA8HL8kr4WlUE11OqCSVlnIgZekmTkEGSZdYnkFdiJ5IANSALtlQ1mghKjz+OFqVs6yowgWA=="], @@ -1005,13 +1019,13 @@ "@cspell/dict-ruby": ["@cspell/dict-ruby@5.1.0", "", {}, "sha512-9PJQB3cfkBULrMLp5kSAcFPpzf8oz9vFN+QYZABhQwWkGbuzCIXSorHrmWSASlx4yejt3brjaWS57zZ/YL5ZQQ=="], - "@cspell/dict-rust": ["@cspell/dict-rust@4.1.0", "", {}, "sha512-ysFxxKc3QjPWtPacbwxzz8sDOACHNShlhQpnBsDXAHN3LogmuBsQtfyuU30APqFjCOg9KwGciKYC/hcGxJCbiA=="], + "@cspell/dict-rust": ["@cspell/dict-rust@4.1.1", "", {}, "sha512-fXiXnZH0wOaEVTKFRNaz6TsUGhuB8dAT0ubYkDNzRQCaV5JGSOebGb1v2x5ZrOSVp+moxWM/vdBfiNU6KOEaFQ=="], "@cspell/dict-scala": ["@cspell/dict-scala@5.0.9", "", {}, "sha512-AjVcVAELgllybr1zk93CJ5wSUNu/Zb5kIubymR/GAYkMyBdYFCZ3Zbwn4Zz8GJlFFAbazABGOu0JPVbeY59vGg=="], "@cspell/dict-shell": ["@cspell/dict-shell@1.1.2", "", {}, "sha512-WqOUvnwcHK1X61wAfwyXq04cn7KYyskg90j4lLg3sGGKMW9Sq13hs91pqrjC44Q+lQLgCobrTkMDw9Wyl9nRFA=="], - "@cspell/dict-software-terms": ["@cspell/dict-software-terms@5.1.19", "", {}, "sha512-3leJLYvibbOnPsIUV/60WcSPxzRmgrx6/0QkqRi8cSsEuRY5/cbUU8Jc0/hKYCIhWJlnIWh5yx34Ep2s8QSIBw=="], + "@cspell/dict-software-terms": ["@cspell/dict-software-terms@5.1.20", "", {}, "sha512-TEk1xHvetTI4pv7Vzje1D322m6QEjaH2P6ucOOf6q7EJCppQIdC0lZSXkgHJAFU5HGSvEXSzvnVeW2RHW86ziQ=="], "@cspell/dict-sql": ["@cspell/dict-sql@2.2.1", "", {}, "sha512-qDHF8MpAYCf4pWU8NKbnVGzkoxMNrFqBHyG/dgrlic5EQiKANCLELYtGlX5auIMDLmTf1inA0eNtv74tyRJ/vg=="], @@ -1271,7 +1285,7 @@ "@hapi/topo": ["@hapi/topo@5.1.0", "", { "dependencies": { "@hapi/hoek": "^9.0.0" } }, "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg=="], - "@hono/node-server": ["@hono/node-server@1.19.7", "", { "peerDependencies": { "hono": "^4" } }, "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw=="], + "@hono/node-server": ["@hono/node-server@1.19.8", "", { "peerDependencies": { "hono": "^4" } }, "sha512-0/g2lIOPzX8f3vzW1ggQgvG5mjtFBDBHFAzI5SFAi2DzSqS9luJwqg9T6O/gKYLi+inS7eNxBeIFkkghIPvrMA=="], "@hookform/resolvers": ["@hookform/resolvers@3.10.0", "", { "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-79Dv+3mDF7i+2ajj7SkypSKHhl1cbln1OGavqrsF7p6mbUv11xpqpacPsGDCTRvCSjEEIez2ef1NveSVL3b0Ag=="], @@ -1837,7 +1851,7 @@ "@smithy/config-resolver": ["@smithy/config-resolver@4.4.5", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "@smithy/util-config-provider": "^4.2.0", "@smithy/util-endpoints": "^3.2.7", "@smithy/util-middleware": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-HAGoUAFYsUkoSckuKbCPayECeMim8pOu+yLy1zOxt1sifzEbrsRpYa+mKcMdiHKMeiqOibyPG0sFJnmaV/OGEg=="], - "@smithy/core": ["@smithy/core@3.20.1", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.8", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-wOboSEdQ85dbKAJ0zL+wQ6b0HTSBRhtGa0PYKysQXkRg+vK0tdCRRVruiFM2QMprkOQwSYOnwF4og96PAaEGag=="], + "@smithy/core": ["@smithy/core@3.20.2", "", { "dependencies": { "@smithy/middleware-serde": "^4.2.8", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-stream": "^4.5.8", "@smithy/util-utf8": "^4.2.0", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-nc99TseyTwL1bg+T21cyEA5oItNy1XN4aUeyOlXJnvyRW5VSK1oRKRoSM/Iq0KFPuqZMxjBemSZHZCOZbSyBMw=="], "@smithy/credential-provider-imds": ["@smithy/credential-provider-imds@4.2.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-CmduWdCiILCRNbQWFR0OcZlUPVtyE49Sr8yYL0rZQ4D/wKxiNzBNS/YHemvnbkIWj623fplgkexUd/c9CAKdoA=="], @@ -1851,9 +1865,9 @@ "@smithy/middleware-content-length": ["@smithy/middleware-content-length@4.2.7", "", { "dependencies": { "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-GszfBfCcvt7kIbJ41LuNa5f0wvQCHhnGx/aDaZJCCT05Ld6x6U2s0xsc/0mBFONBZjQJp2U/0uSJ178OXOwbhg=="], - "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.2", "", { "dependencies": { "@smithy/core": "^3.20.1", "@smithy/middleware-serde": "^4.2.8", "@smithy/node-config-provider": "^4.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-middleware": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-mqpAdux0BNmZu/SqkFhQEnod4fX23xxTvU2LUpmKp0JpSI+kPYCiHJMmzREr8yxbNxKL2/DU1UZm9i++ayU+2g=="], + "@smithy/middleware-endpoint": ["@smithy/middleware-endpoint@4.4.3", "", { "dependencies": { "@smithy/core": "^3.20.2", "@smithy/middleware-serde": "^4.2.8", "@smithy/node-config-provider": "^4.3.7", "@smithy/shared-ini-file-loader": "^4.4.2", "@smithy/types": "^4.11.0", "@smithy/url-parser": "^4.2.7", "@smithy/util-middleware": "^4.2.7", "tslib": "^2.6.2" } }, "sha512-Zb8R35hjBhp1oFhiaAZ9QhClpPHdEDmNDC2UrrB2fqV0oNDUUPH12ovZHB5xi/Rd+pg/BJHOR1q+SfsieSKPQg=="], - "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.18", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/service-error-classification": "^4.2.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-E5hulijA59nBk/zvcwVMaS7FG7Y4l6hWA9vrW018r+8kiZef4/ETQaPI4oY+3zsy9f6KqDv3c4VKtO4DwwgpCg=="], + "@smithy/middleware-retry": ["@smithy/middleware-retry@4.4.19", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/protocol-http": "^5.3.7", "@smithy/service-error-classification": "^4.2.7", "@smithy/smithy-client": "^4.10.4", "@smithy/types": "^4.11.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-retry": "^4.2.7", "@smithy/uuid": "^1.1.0", "tslib": "^2.6.2" } }, "sha512-QtisFIjIw2tjMm/ESatjWFVIQb5Xd093z8xhxq/SijLg7Mgo2C2wod47Ib/AHpBLFhwYXPzd7Hp2+JVXfeZyMQ=="], "@smithy/middleware-serde": ["@smithy/middleware-serde@4.2.8", "", { "dependencies": { "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-8rDGYen5m5+NV9eHv9ry0sqm2gI6W7mc1VSFMtn6Igo25S507/HaOX9LTHAS2/J32VXD0xSzrY0H5FJtOMS4/w=="], @@ -1877,7 +1891,7 @@ "@smithy/signature-v4": ["@smithy/signature-v4@5.3.7", "", { "dependencies": { "@smithy/is-array-buffer": "^4.2.0", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-hex-encoding": "^4.2.0", "@smithy/util-middleware": "^4.2.7", "@smithy/util-uri-escape": "^4.2.0", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-9oNUlqBlFZFOSdxgImA6X5GFuzE7V2H7VG/7E70cdLhidFbdtvxxt81EHgykGK5vq5D3FafH//X+Oy31j3CKOg=="], - "@smithy/smithy-client": ["@smithy/smithy-client@4.10.3", "", { "dependencies": { "@smithy/core": "^3.20.1", "@smithy/middleware-endpoint": "^4.4.2", "@smithy/middleware-stack": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-EfECiO/0fAfb590LBnUe7rI5ux7XfquQ8LBzTe7gxw0j9QW/q8UT/EHWHlxV/+jhQ3+Ssga9uUYXCQgImGMbNg=="], + "@smithy/smithy-client": ["@smithy/smithy-client@4.10.4", "", { "dependencies": { "@smithy/core": "^3.20.2", "@smithy/middleware-endpoint": "^4.4.3", "@smithy/middleware-stack": "^4.2.7", "@smithy/protocol-http": "^5.3.7", "@smithy/types": "^4.11.0", "@smithy/util-stream": "^4.5.8", "tslib": "^2.6.2" } }, "sha512-rHig+BWjhjlHlah67ryaW9DECYixiJo5pQCTEwsJyarRBAwHMMC3iYz5MXXAHXe64ZAMn1NhTUSTFIu1T6n6jg=="], "@smithy/types": ["@smithy/types@4.11.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-mlrmL0DRDVe3mNrjTcVcZEgkFmufITfUAPBEA+AHYiIeYyJebso/He1qLbP3PssRe22KUzLRpQSdBPbXdgZ2VA=="], @@ -1893,9 +1907,9 @@ "@smithy/util-config-provider": ["@smithy/util-config-provider@4.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YEjpl6XJ36FTKmD+kRJJWYvrHeUvm5ykaUS5xK+6oXffQPHeEM4/nXlZPe+Wu0lsgRUcNZiliYNh/y7q9c2y6Q=="], - "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.17", "", { "dependencies": { "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-dwN4GmivYF1QphnP3xJESXKtHvkkvKHSZI8GrSKMVoENVSKW2cFPRYC4ZgstYjUHdR3zwaDkIaTDIp26JuY7Cw=="], + "@smithy/util-defaults-mode-browser": ["@smithy/util-defaults-mode-browser@4.3.18", "", { "dependencies": { "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.4", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-Ao1oLH37YmLyHnKdteMp6l4KMCGBeZEAN68YYe00KAaKFijFELDbRQRm3CNplz7bez1HifuBV0l5uR6eVJLhIg=="], - "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.20", "", { "dependencies": { "@smithy/config-resolver": "^4.4.5", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.3", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-VD/I4AEhF1lpB3B//pmOIMBNLMrtdMXwy9yCOfa2QkJGDr63vH3RqPbSAKzoGMov3iryCxTXCxSsyGmEB8PDpg=="], + "@smithy/util-defaults-mode-node": ["@smithy/util-defaults-mode-node@4.2.21", "", { "dependencies": { "@smithy/config-resolver": "^4.4.5", "@smithy/credential-provider-imds": "^4.2.7", "@smithy/node-config-provider": "^4.3.7", "@smithy/property-provider": "^4.2.7", "@smithy/smithy-client": "^4.10.4", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-e21ASJDirE96kKXZLcYcnn4Zt0WGOvMYc1P8EK0gQeQ3I8PbJWqBKx9AUr/YeFpDkpYwEu1RsPe4UXk2+QL7IA=="], "@smithy/util-endpoints": ["@smithy/util-endpoints@3.2.7", "", { "dependencies": { "@smithy/node-config-provider": "^4.3.7", "@smithy/types": "^4.11.0", "tslib": "^2.6.2" } }, "sha512-s4ILhyAvVqhMDYREeTS68R43B1V5aenV5q/V1QpRQJkCXib5BPRo4s7uNdzGtIKxaPHCfU/8YkvPAEvTpxgspg=="], @@ -2119,6 +2133,8 @@ "@towns-protocol/sdk-crypto": ["@towns-protocol/sdk-crypto@workspace:packages/sdk-crypto"], + "@towns-protocol/smart-account": ["@towns-protocol/smart-account@workspace:packages/smart-account"], + "@towns-protocol/stream-metadata": ["@towns-protocol/stream-metadata@workspace:packages/stream-metadata"], "@towns-protocol/stress": ["@towns-protocol/stress@workspace:packages/stress"], @@ -2211,6 +2227,8 @@ "@types/pbkdf2": ["@types/pbkdf2@3.1.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew=="], + "@types/pg": ["@types/pg@8.6.1", "", { "dependencies": { "@types/node": "*", "pg-protocol": "*", "pg-types": "^2.2.0" } }, "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w=="], + "@types/prettier": ["@types/prettier@2.7.3", "", {}, "sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA=="], "@types/prompts": ["@types/prompts@2.4.9", "", { "dependencies": { "@types/node": "*", "kleur": "^3.0.3" } }, "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA=="], @@ -2403,7 +2421,7 @@ "account-abstraction": ["accountabstraction@github:eth-infinitism/account-abstraction#d99245d", { "dependencies": { "@nomiclabs/hardhat-etherscan": "^2.1.6", "@openzeppelin/contracts": "^5.0.0", "@thehubbleproject/bls": "^0.5.1", "@typechain/hardhat": "^2.3.0", "@types/debug": "^4.1.12", "@types/mocha": "^9.0.0", "debug": "^4.3.4", "ethereumjs-util": "^7.1.0", "ethereumjs-wallet": "^1.0.1", "hardhat-deploy": "^0.11.23", "hardhat-deploy-ethers": "^0.3.0-beta.11", "solidity-coverage": "^0.8.4", "source-map-support": "^0.5.19", "table": "^6.8.0", "typescript": "^4.3.5" } }, "eth-infinitism-account-abstraction-d99245d"], - "acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "acorn": ["acorn@8.11.2", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w=="], "acorn-import-attributes": ["acorn-import-attributes@1.9.5", "", { "peerDependencies": { "acorn": "^8" } }, "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ=="], @@ -2555,7 +2573,7 @@ "base64id": ["base64id@2.0.0", "", {}, "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="], - "baseline-browser-mapping": ["baseline-browser-mapping@2.9.13", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-WhtvB2NG2wjr04+h77sg3klAIwrgOqnjS49GGudnUPGFFgg7G17y7Qecqp+2Dr5kUDxNRBca0SK7cG8JwzkWDQ=="], + "baseline-browser-mapping": ["baseline-browser-mapping@2.9.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg=="], "basic-ftp": ["basic-ftp@5.1.0", "", {}, "sha512-RkaJzeJKDbaDWTIPiJwubyljaEPwpVWkm9Rt5h9Nd6h7tEXTJ3VB4qxdZBioV7JO5yLUaOKwz7vDOzlncUsegw=="], @@ -3465,7 +3483,7 @@ "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="], - "http-errors": ["http-errors@2.0.1", "", { "dependencies": { "depd": "~2.0.0", "inherits": "~2.0.4", "setprototypeof": "~1.2.0", "statuses": "~2.0.2", "toidentifier": "~1.0.1" } }, "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ=="], + "http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="], @@ -3681,7 +3699,7 @@ "js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="], - "js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], "jsep": ["jsep@1.4.0", "", {}, "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw=="], @@ -4065,7 +4083,7 @@ "node-environment-flags": ["node-environment-flags@1.0.6", "", { "dependencies": { "object.getownpropertydescriptors": "^2.0.3", "semver": "^5.7.0" } }, "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw=="], - "node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], "node-fetch-native": ["node-fetch-native@1.6.7", "", {}, "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q=="], @@ -4159,7 +4177,7 @@ "own-keys": ["own-keys@1.0.1", "", { "dependencies": { "get-intrinsic": "^1.2.6", "object-keys": "^1.1.1", "safe-push-apply": "^1.0.0" } }, "sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg=="], - "ox": ["ox@0.11.1", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-1l1gOLAqg0S0xiN1dH5nkPna8PucrZgrIJOfS49MLNiMevxu07Iz4ZjuJS9N+xifvT+PsZyIptS7WHM8nC+0+A=="], + "ox": ["ox@0.11.3", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw=="], "p-any": ["p-any@4.0.0", "", { "dependencies": { "p-cancelable": "^3.0.0", "p-some": "^6.0.0" } }, "sha512-S/B50s+pAVe0wmEZHmBs/9yJXeZ5KhHzOsgKzt0hRdgkoR3DxW9ts46fcsWi/r3VnzsnkKS7q4uimze+zjdryw=="], @@ -4239,6 +4257,8 @@ "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], + "permissionless": ["permissionless@0.2.57", "", { "peerDependencies": { "ox": "^0.8.0", "viem": "^2.28.1" }, "optionalPeers": ["ox"] }, "sha512-QrzAoQGYPV/NJ2x5Sj18h7qed6f+kCyQAojrncN091UPiGqHjFNjgdsgreiv8pxlQgF4UcpuJUvsHLpOEBd6cQ=="], + "pg": ["pg@8.16.3", "", { "dependencies": { "pg-connection-string": "^2.9.1", "pg-pool": "^3.10.1", "pg-protocol": "^1.10.3", "pg-types": "2.2.0", "pgpass": "1.0.5" }, "optionalDependencies": { "pg-cloudflare": "^1.2.7" }, "peerDependencies": { "pg-native": ">=3.0.1" }, "optionalPeers": ["pg-native"] }, "sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw=="], "pg-cloudflare": ["pg-cloudflare@1.2.7", "", {}, "sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg=="], @@ -4397,7 +4417,7 @@ "range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="], - "raw-body": ["raw-body@2.5.3", "", { "dependencies": { "bytes": "~3.1.2", "http-errors": "~2.0.1", "iconv-lite": "~0.4.24", "unpipe": "~1.0.0" } }, "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA=="], + "raw-body": ["raw-body@2.5.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig=="], "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="], @@ -4699,7 +4719,7 @@ "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], - "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], + "statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], "std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="], @@ -5051,7 +5071,7 @@ "vfile-message": ["vfile-message@4.0.3", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-stringify-position": "^4.0.0" } }, "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw=="], - "viem": ["viem@2.43.5", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.11.1", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-QuJpuEMEPM3EreN+vX4mVY68Sci0+zDxozYfbh/WfV+SSy/Gthm74PH8XmitXdty1xY54uTCJ+/Gbbd1IiMPSA=="], + "viem": ["viem@2.44.0", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.11.3", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-ERvl+N/mPIUck9OSVZGnt1Ex1pMTwKdtOMIbUXLlGJP3KlxdA+1F+Q1hO21qQToaM/ysjTD50ZPQuKyj4Dk3FA=="], "vite": ["vite@6.4.1", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-+Oxm7q9hDoLMyJOYfUYBuHQo+dkAloi33apOPP56pzj+vsdJDzr+j1NISE5pyaAuKL4A3UD34qd0lx5+kfKp2g=="], @@ -5183,6 +5203,8 @@ "@asyncapi/parser/ajv-formats": ["ajv-formats@2.1.1", "", { "dependencies": { "ajv": "^8.0.0" } }, "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA=="], + "@asyncapi/parser/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], + "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/util/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], @@ -5223,6 +5245,8 @@ "@changesets/git/micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="], + "@changesets/parse/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="], + "@changesets/write/prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], "@coinbase/cdp-sdk/abitype": ["abitype@1.0.6", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3 >=3.22.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A=="], @@ -5289,9 +5313,7 @@ "@manypkg/get-packages/read-yaml-file": ["read-yaml-file@1.1.0", "", { "dependencies": { "graceful-fs": "^4.1.5", "js-yaml": "^3.6.1", "pify": "^4.0.1", "strip-bom": "^3.0.0" } }, "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA=="], - "@mdx-js/mdx/remark-mdx": ["remark-mdx@3.1.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-Pjj2IYlUY3+D8x00UJsIOg5BEvfMyeI+2uLPn9VO9Wg4MEtN/VTIq2NEJQfde9PnX15KgtHyl9S0BcTnWrIuWg=="], - - "@mdx-js/mdx/remark-rehype": ["remark-rehype@11.1.2", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "mdast-util-to-hast": "^13.0.0", "unified": "^11.0.0", "vfile": "^6.0.0" } }, "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw=="], + "@mdx-js/mdx/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], "@mdx-js/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="], @@ -5349,16 +5371,10 @@ "@mintlify/cli/fs-extra": ["fs-extra@11.2.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw=="], - "@mintlify/cli/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/cli/semver": ["semver@7.7.2", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA=="], - "@mintlify/common/acorn": ["acorn@8.11.2", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w=="], - "@mintlify/common/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], - "@mintlify/common/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/common/mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.1.3", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ=="], "@mintlify/common/tailwindcss": ["tailwindcss@3.4.4", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.21.0", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.1", "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.11", "resolve": "^1.22.2", "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-ZoyXOdJjISB7/BcLTR6SEsLgKtDStYyYZVLsUtWChO4Ps20CBad7lfJKVDiejocV4ME1hLmyY0WJE3hSDcmQ2A=="], @@ -5367,12 +5383,8 @@ "@mintlify/link-rot/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="], - "@mintlify/mdx/arktype": ["arktype@2.1.29", "", { "dependencies": { "@ark/schema": "0.56.0", "@ark/util": "0.56.0", "arkregex": "0.0.5" } }, "sha512-jyfKk4xIOzvYNayqnD8ZJQqOwcrTOUbIU4293yrzAjA3O1dWh61j71ArMQ6tS/u4pD7vabSPe7nG3RCyoXW6RQ=="], - "@mintlify/mdx/mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], - "@mintlify/mdx/remark-gfm": ["remark-gfm@4.0.1", "", { "dependencies": { "@types/mdast": "^4.0.0", "mdast-util-gfm": "^3.0.0", "micromark-extension-gfm": "^3.0.0", "remark-parse": "^11.0.0", "remark-stringify": "^11.0.0", "unified": "^11.0.0" } }, "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg=="], - "@mintlify/models/axios": ["axios@1.10.0", "", { "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw=="], "@mintlify/openapi-parser/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], @@ -5385,8 +5397,6 @@ "@mintlify/prebuild/fs-extra": ["fs-extra@11.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw=="], - "@mintlify/prebuild/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/prebuild/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], "@mintlify/prebuild/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="], @@ -5401,22 +5411,16 @@ "@mintlify/previewing/got": ["got@13.0.0", "", { "dependencies": { "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", "cacheable-lookup": "^7.0.0", "cacheable-request": "^10.2.8", "decompress-response": "^6.0.0", "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", "responselike": "^3.0.0" } }, "sha512-XfBk1CxOOScDcMr9O1yKkNaQyy865NbYs+F7dr4H0LZMVgCj2Le59k6PqbNHoL5ToeaEQUYh6c6yMfVcc6SJxA=="], - "@mintlify/previewing/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/previewing/unist-util-visit": ["unist-util-visit@4.1.2", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0", "unist-util-visit-parents": "^5.1.1" } }, "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg=="], "@mintlify/scraping/fs-extra": ["fs-extra@11.1.1", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ=="], - "@mintlify/scraping/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/scraping/mdast-util-mdx-jsx": ["mdast-util-mdx-jsx@3.1.3", "", { "dependencies": { "@types/estree-jsx": "^1.0.0", "@types/hast": "^3.0.0", "@types/mdast": "^4.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "devlop": "^1.1.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-to-markdown": "^2.0.0", "parse-entities": "^4.0.0", "stringify-entities": "^4.0.0", "unist-util-stringify-position": "^4.0.0", "vfile-message": "^4.0.0" } }, "sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ=="], "@mintlify/scraping/remark-mdx": ["remark-mdx@3.0.1", "", { "dependencies": { "mdast-util-mdx": "^3.0.0", "micromark-extension-mdxjs": "^3.0.0" } }, "sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA=="], "@mintlify/scraping/zod": ["zod@3.21.4", "", {}, "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw=="], - "@mintlify/validation/js-yaml": ["js-yaml@4.1.0", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA=="], - "@mintlify/validation/uuid": ["uuid@11.1.0", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A=="], "@mintlify/validation/zod": ["zod@3.21.4", "", {}, "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw=="], @@ -5431,8 +5435,6 @@ "@nomicfoundation/hardhat-verify/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@nomiclabs/hardhat-etherscan/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@nomiclabs/hardhat-etherscan/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], "@pnpm/network.ca-file/graceful-fs": ["graceful-fs@4.2.10", "", {}, "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="], @@ -5515,21 +5517,21 @@ "@solana/errors/commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="], + "@solana/rpc-subscriptions-channel-websocket/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "@solana/rpc-transport-http/undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="], "@solana/web3.js/@solana/codecs-numbers": ["@solana/codecs-numbers@2.3.0", "", { "dependencies": { "@solana/codecs-core": "2.3.0", "@solana/errors": "2.3.0" }, "peerDependencies": { "typescript": ">=5.3.3" } }, "sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg=="], "@solana/web3.js/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], - "@solana/web3.js/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@stoplight/better-ajv-errors/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "@stoplight/json/jsonc-parser": ["jsonc-parser@2.2.1", "", {}, "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="], "@stoplight/json/safe-stable-stringify": ["safe-stable-stringify@1.1.1", "", {}, "sha512-ERq4hUjKDbJfE4+XtZLFPCDi8Vb1JqaxAPTxWFLBx8XcAlf9Bda/ZJdVezs/NAfsMQScyIlUMx+Yeu7P7rx5jw=="], - "@stoplight/json-ref-readers/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], + "@stoplight/json-ref-readers/node-fetch": ["node-fetch@2.6.7", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ=="], "@stoplight/json-ref-readers/tslib": ["tslib@1.14.1", "", {}, "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="], @@ -5551,16 +5553,20 @@ "@stoplight/spectral-parsers/@stoplight/types": ["@stoplight/types@14.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" } }, "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g=="], - "@stoplight/spectral-runtime/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@stoplight/yaml/@stoplight/types": ["@stoplight/types@14.1.1", "", { "dependencies": { "@types/json-schema": "^7.0.4", "utility-types": "^3.10.0" } }, "sha512-/kjtr+0t0tjKr+heVfviO9FrU/uGLc+QNX3fHJc19xsCNYqU7lVhaXxDmEID9BZTjG+/r9pK9xP/xU02XGg65g=="], + "@towns-protocol/diamond/forge-std": ["forge-std@github:foundry-rs/forge-std#7117c90", {}, "foundry-rs-forge-std-7117c90"], + "@ts-morph/common/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typechain/hardhat/fs-extra": ["fs-extra@9.1.0", "", { "dependencies": { "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ=="], + "@types/glob/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], + "@types/minimatch/minimatch": ["minimatch@10.0.3", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.0" } }, "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw=="], + "@types/ws/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], + "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], @@ -5625,6 +5631,8 @@ "account-abstraction/typescript": ["typescript@4.9.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="], + "acorn-walk/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "ajv-formats/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], @@ -5633,14 +5641,10 @@ "body-parser/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "body-parser/http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], - "body-parser/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], "body-parser/qs": ["qs@6.11.0", "", { "dependencies": { "side-channel": "^1.0.4" } }, "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="], - "body-parser/raw-body": ["raw-body@2.5.1", "", { "dependencies": { "bytes": "3.1.2", "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig=="], - "boxen/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], "browser-resolve/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], @@ -5689,8 +5693,6 @@ "create-ecdh/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], - "cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "cspell/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], "cspell/commander": ["commander@13.1.0", "", {}, "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw=="], @@ -5717,16 +5719,16 @@ "elliptic/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], - "engine.io/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="], - "engine.io/cookie": ["cookie@0.4.2", "", {}, "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA=="], - "engine.io/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="], + "engine.io/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], "engine.io/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], "ens-contracts/@openzeppelin/contracts": ["@openzeppelin/contracts@4.9.3", "", {}, "sha512-He3LieZ1pP2TNt5JbkPA4PNT9WC3gOTOlDcFGJW4Le4QKqwmiNJCRt44APfxMxvq7OugU/cqYuPcSBzOw38DAg=="], + "esast-util-from-js/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "esbuild-plugin-pino/esbuild": ["esbuild@0.27.2", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.2", "@esbuild/android-arm": "0.27.2", "@esbuild/android-arm64": "0.27.2", "@esbuild/android-x64": "0.27.2", "@esbuild/darwin-arm64": "0.27.2", "@esbuild/darwin-x64": "0.27.2", "@esbuild/freebsd-arm64": "0.27.2", "@esbuild/freebsd-x64": "0.27.2", "@esbuild/linux-arm": "0.27.2", "@esbuild/linux-arm64": "0.27.2", "@esbuild/linux-ia32": "0.27.2", "@esbuild/linux-loong64": "0.27.2", "@esbuild/linux-mips64el": "0.27.2", "@esbuild/linux-ppc64": "0.27.2", "@esbuild/linux-riscv64": "0.27.2", "@esbuild/linux-s390x": "0.27.2", "@esbuild/linux-x64": "0.27.2", "@esbuild/netbsd-arm64": "0.27.2", "@esbuild/netbsd-x64": "0.27.2", "@esbuild/openbsd-arm64": "0.27.2", "@esbuild/openbsd-x64": "0.27.2", "@esbuild/openharmony-arm64": "0.27.2", "@esbuild/sunos-x64": "0.27.2", "@esbuild/win32-arm64": "0.27.2", "@esbuild/win32-ia32": "0.27.2", "@esbuild/win32-x64": "0.27.2" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw=="], "escodegen/estraverse": ["estraverse@1.9.3", "", {}, "sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA=="], @@ -5777,12 +5779,8 @@ "express/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "express/http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], - "express/qs": ["qs@6.11.0", "", { "dependencies": { "side-channel": "^1.0.4" } }, "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q=="], - "express/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], - "extension-port-stream/readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], "extract-zip/get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="], @@ -5793,14 +5791,12 @@ "fast-json-stringify/ajv": ["ajv@8.17.1", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2" } }, "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g=="], - "fastify/pino": ["pino@10.1.0", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^3.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w=="], + "fastify/pino": ["pino@10.1.1", "", { "dependencies": { "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^3.0.0", "pino-std-serializers": "^7.0.0", "process-warning": "^5.0.0", "quick-format-unescaped": "^4.0.3", "real-require": "^0.2.0", "safe-stable-stringify": "^2.3.1", "sonic-boom": "^4.0.1", "thread-stream": "^4.0.0" }, "bin": { "pino": "bin.js" } }, "sha512-3qqVfpJtRQUCAOs4rTOEwLH6mwJJ/CSAlbis8fKOiMzTtXh0HN/VLsn3UWVTJ7U8DsWmxeNon2IpGb+wORXH4g=="], "favicons/sharp": ["sharp@0.33.5", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.3", "semver": "^7.6.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.5", "@img/sharp-darwin-x64": "0.33.5", "@img/sharp-libvips-darwin-arm64": "1.0.4", "@img/sharp-libvips-darwin-x64": "1.0.4", "@img/sharp-libvips-linux-arm": "1.0.5", "@img/sharp-libvips-linux-arm64": "1.0.4", "@img/sharp-libvips-linux-s390x": "1.0.4", "@img/sharp-libvips-linux-x64": "1.0.4", "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", "@img/sharp-libvips-linuxmusl-x64": "1.0.4", "@img/sharp-linux-arm": "0.33.5", "@img/sharp-linux-arm64": "0.33.5", "@img/sharp-linux-s390x": "0.33.5", "@img/sharp-linux-x64": "0.33.5", "@img/sharp-linuxmusl-arm64": "0.33.5", "@img/sharp-linuxmusl-x64": "0.33.5", "@img/sharp-wasm32": "0.33.5", "@img/sharp-win32-ia32": "0.33.5", "@img/sharp-win32-x64": "0.33.5" } }, "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw=="], "finalhandler/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "finalhandler/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], - "find-cache-dir/pkg-dir": ["pkg-dir@3.0.0", "", { "dependencies": { "find-up": "^3.0.0" } }, "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw=="], "front-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], @@ -5855,8 +5851,6 @@ "hast-util-to-jsx-runtime/property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "hast-util-to-mdast/hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], - "hastscript/property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], "hosted-git-info/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="], @@ -5869,6 +5863,8 @@ "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], + "import-in-the-middle/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "ink/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="], "ink/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], @@ -5893,7 +5889,7 @@ "ink/wrap-ansi": ["wrap-ansi@9.0.2", "", { "dependencies": { "ansi-styles": "^6.2.1", "string-width": "^7.0.0", "strip-ansi": "^7.1.0" } }, "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww=="], - "inquirer/@inquirer/prompts": ["@inquirer/prompts@7.10.1", "", { "dependencies": { "@inquirer/checkbox": "^4.3.2", "@inquirer/confirm": "^5.1.21", "@inquirer/editor": "^4.2.23", "@inquirer/expand": "^4.0.23", "@inquirer/input": "^4.3.1", "@inquirer/number": "^3.0.23", "@inquirer/password": "^4.0.23", "@inquirer/rawlist": "^4.1.11", "@inquirer/search": "^3.2.2", "@inquirer/select": "^4.4.2" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg=="], + "ink/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], "inquirer/ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], @@ -5933,20 +5929,20 @@ "marked-terminal/chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="], - "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], + "md5.js/hash-base": ["hash-base@3.1.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.1" } }, "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg=="], - "mdast-util-find-and-replace/unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], + "mdast-util-find-and-replace/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], "mdast-util-frontmatter/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="], - "micromark-extension-mdxjs/micromark-extension-mdx-jsx": ["micromark-extension-mdx-jsx@3.0.2", "", { "dependencies": { "@types/estree": "^1.0.0", "devlop": "^1.0.0", "estree-util-is-identifier-name": "^3.0.0", "micromark-factory-mdx-expression": "^2.0.0", "micromark-factory-space": "^2.0.0", "micromark-util-character": "^2.0.0", "micromark-util-events-to-acorn": "^2.0.0", "micromark-util-symbol": "^2.0.0", "micromark-util-types": "^2.0.0", "vfile-message": "^4.0.0" } }, "sha512-e5+q1DjMh62LZAJOnDraSSbDMvGJ8x3cbjygy2qFEi7HCeUT4BDKCvMozPozcD6WmOt6sVvYDNBKhFSz3kjOVQ=="], - "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "miller-rabin/bn.js": ["bn.js@4.12.2", "", {}, "sha512-n4DSx829VRTRByMRGdjQ9iqsN0Bh4OolPsFnaZBLcbi8iXcB+kJ9s7EnRt4wILZNV3kPLHkRVfOc/HvhC3ovDw=="], "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="], + "mlly/acorn": ["acorn@8.15.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="], + "mocha/chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="], "mocha/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="], @@ -6011,6 +6007,8 @@ "ponder/vite-tsconfig-paths": ["vite-tsconfig-paths@4.3.1", "", { "dependencies": { "debug": "^4.1.1", "globrex": "^0.1.2", "tsconfck": "^3.0.1" }, "peerDependencies": { "vite": "*" }, "optionalPeers": ["vite"] }, "sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw=="], + "ponder/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "porto/idb-keyval": ["idb-keyval@6.2.2", "", {}, "sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg=="], "porto/ox": ["ox@0.9.17", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.0.9", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-rKAnhzhRU3Xh3hiko+i1ZxywZ55eWQzeS/Q4HRKLx2PqfHOolisZHErSsJVipGlmQKHW5qwOED/GighEw9dbLg=="], @@ -6037,6 +6035,8 @@ "puppeteer/cosmiconfig": ["cosmiconfig@9.0.0", "", { "dependencies": { "env-paths": "^2.2.1", "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg=="], + "puppeteer-core/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], "raw-body/iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="], @@ -6049,12 +6049,6 @@ "rechoir/resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="], - "rehype-katex/unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - - "rehype-stringify/hast-util-to-html": ["hast-util-to-html@9.0.5", "", { "dependencies": { "@types/hast": "^3.0.0", "@types/unist": "^3.0.0", "ccount": "^2.0.0", "comma-separated-tokens": "^2.0.0", "hast-util-whitespace": "^3.0.0", "html-void-elements": "^3.0.0", "mdast-util-to-hast": "^13.0.0", "property-information": "^7.0.0", "space-separated-tokens": "^2.0.0", "stringify-entities": "^4.0.0", "zwitch": "^2.0.4" } }, "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw=="], - - "remark-gfm/mdast-util-gfm": ["mdast-util-gfm@3.1.0", "", { "dependencies": { "mdast-util-from-markdown": "^2.0.0", "mdast-util-gfm-autolink-literal": "^2.0.0", "mdast-util-gfm-footnote": "^2.0.0", "mdast-util-gfm-strikethrough": "^2.0.0", "mdast-util-gfm-table": "^2.0.0", "mdast-util-gfm-task-list-item": "^2.0.0", "mdast-util-to-markdown": "^2.0.0" } }, "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ=="], - "restore-cursor/onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="], "restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], @@ -6071,6 +6065,8 @@ "rpc-websockets/buffer": ["buffer@6.0.3", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.2.1" } }, "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA=="], + "rpc-websockets/ws": ["ws@8.19.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg=="], + "sc-istanbul/glob": ["glob@5.0.15", "", { "dependencies": { "inflight": "^1.0.4", "inherits": "2", "minimatch": "2 || 3", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA=="], "sc-istanbul/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], @@ -6089,17 +6085,13 @@ "send/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="], - "send/http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="], - - "send/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], - "serialize-error/type-fest": ["type-fest@4.41.0", "", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="], "shelljs/glob": ["glob@7.2.0", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q=="], "simple-swizzle/is-arrayish": ["is-arrayish@0.3.4", "", {}, "sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA=="], - "socket.io/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="], + "socket.io/debug": ["debug@4.3.7", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ=="], "socks-proxy-agent/agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="], @@ -6107,7 +6099,9 @@ "solc/semver": ["semver@5.7.2", "", { "bin": { "semver": "bin/semver" } }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="], - "solhint/fs-extra": ["fs-extra@11.3.3", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg=="], + "solhint/cosmiconfig": ["cosmiconfig@8.3.6", "", { "dependencies": { "import-fresh": "^3.3.0", "js-yaml": "^4.1.0", "parse-json": "^5.2.0", "path-type": "^4.0.0" }, "peerDependencies": { "typescript": ">=4.9.5" }, "optionalPeers": ["typescript"] }, "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA=="], + + "solhint/fs-extra": ["fs-extra@11.2.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw=="], "solhint/prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="], @@ -6185,10 +6179,6 @@ "unified/is-plain-obj": ["is-plain-obj@4.1.0", "", {}, "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg=="], - "unist-util-remove/unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - - "unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@6.0.2", "", { "dependencies": { "@types/unist": "^3.0.0", "unist-util-is": "^6.0.0" } }, "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ=="], - "unstorage/chokidar": ["chokidar@4.0.3", "", { "dependencies": { "readdirp": "^4.0.1" } }, "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA=="], "unstorage/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], @@ -6339,12 +6329,6 @@ "@mintlify/link-rot/unist-util-visit/unist-util-visit-parents": ["unist-util-visit-parents@5.1.3", "", { "dependencies": { "@types/unist": "^2.0.0", "unist-util-is": "^5.0.0" } }, "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg=="], - "@mintlify/mdx/arktype/@ark/schema": ["@ark/schema@0.56.0", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA=="], - - "@mintlify/mdx/arktype/@ark/util": ["@ark/util@0.56.0", "", {}, "sha512-BghfRC8b9pNs3vBoDJhcta0/c1J1rsoS1+HgVUreMFPdhz/CRAKReAu57YEllNaSy98rWAdY1gE+gFup7OXpgA=="], - - "@mintlify/mdx/arktype/arkregex": ["arkregex@0.0.5", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ncYjBdLlh5/QnVsAA8De16Tc9EqmYM7y/WU9j+236KcyYNUXogpz3sC4ATIZYzzLxwI+0sEOaQLEmLmRleaEXw=="], - "@mintlify/openapi-parser/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], "@mintlify/prebuild/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], @@ -6483,6 +6467,10 @@ "@typechain/hardhat/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], + "@types/glob/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + + "@types/ws/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], + "@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "@unruggable/gateways/ethers/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.10.1", "", {}, "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw=="], @@ -6499,8 +6487,6 @@ "@unruggable/gateways/ethers/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="], - "@walletconnect/jsonrpc-http-connection/cross-fetch/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="], - "@walletconnect/logger/pino/on-exit-leak-free": ["on-exit-leak-free@0.2.0", "", {}, "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg=="], "@walletconnect/logger/pino/pino-abstract-transport": ["pino-abstract-transport@0.5.0", "", { "dependencies": { "duplexify": "^4.1.2", "split2": "^4.0.0" } }, "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ=="], @@ -6533,8 +6519,6 @@ "body-parser/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "body-parser/http-errors/statuses": ["statuses@2.0.1", "", {}, "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ=="], - "browserify-sign/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], "browserify-sign/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], @@ -6575,10 +6559,6 @@ "detect-package-manager/execa/strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="], - "engine.io/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="], - - "engine.io/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], - "esbuild-plugin-pino/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="], "esbuild-plugin-pino/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="], @@ -6667,7 +6647,7 @@ "fast-json-stringify/ajv/json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="], - "fastify/pino/pino-abstract-transport": ["pino-abstract-transport@2.0.0", "", { "dependencies": { "split2": "^4.0.0" } }, "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw=="], + "fastify/pino/thread-stream": ["thread-stream@4.0.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA=="], "favicons/sharp/@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ=="], @@ -6751,8 +6731,6 @@ "hardhat/find-up/locate-path": ["locate-path@2.0.0", "", { "dependencies": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" } }, "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA=="], - "hast-util-to-mdast/hast-util-to-html/property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "ignore-walk/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="], "ink/cli-cursor/restore-cursor": ["restore-cursor@4.0.0", "", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="], @@ -6779,6 +6757,8 @@ "log-update/slice-ansi/is-fullwidth-code-point": ["is-fullwidth-code-point@4.0.0", "", {}, "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ=="], + "md5.js/hash-base/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], + "mocha/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "mocha/chokidar/readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="], @@ -6831,8 +6811,6 @@ "qrcode/yargs/yargs-parser": ["yargs-parser@18.1.3", "", { "dependencies": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } }, "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ=="], - "rehype-stringify/hast-util-to-html/property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="], - "restore-cursor/onetime/mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="], "ripemd160/hash-base/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="], @@ -6845,8 +6823,6 @@ "send/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="], - "socket.io/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="], - "solhint/fs-extra/jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="], "solhint/fs-extra/universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="], @@ -7137,6 +7113,12 @@ "log-update/cli-cursor/restore-cursor/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="], + "md5.js/hash-base/readable-stream/isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="], + + "md5.js/hash-base/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], + + "md5.js/hash-base/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], + "mocha/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "mocha/yargs/cliui/wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="], diff --git a/core/justfile b/core/justfile index ae8fe69b008..659acadcc39 100644 --- a/core/justfile +++ b/core/justfile @@ -58,6 +58,7 @@ _get-docker-build-hash: git ls-tree HEAD ../packages/contracts/scripts 2>/dev/null git ls-tree HEAD ../packages/contracts/src 2>/dev/null git ls-tree HEAD ../scripts/deploy-contracts.sh 2>/dev/null + git ls-tree HEAD ../scripts/deploy-base-contracts.sh 2>/dev/null git ls-tree HEAD ../scripts/start-local-basechain.sh 2>/dev/null git ls-tree HEAD ../scripts/start-local-riverchain.sh 2>/dev/null git ls-tree HEAD ../core/justfile 2>/dev/null @@ -109,14 +110,27 @@ _anvil-start $NAME $PORT $CHAIN_ID: echo "Starting Docker ${NAME} chain on port ${PORT}" IMAGE=$(just _get-docker-image) + # Expose Alto bundler port (4337) for base chain + ALTO_PORT_ARG="" + if [ "${NAME}" = "base" ]; then + ALTO_PORT_ARG="-p 4337:4337" + fi + docker run -d \ --name towns-${NAME}-chain \ -p ${PORT}:${PORT} \ + ${ALTO_PORT_ARG} \ -e CHAIN=${NAME} \ -e RIVER_BLOCK_TIME \ $IMAGE ../scripts/wait-for-port.sh ${PORT} "Docker_anvil_${NAME}" + + # Wait for Alto bundler if base chain + if [ "${NAME}" = "base" ]; then + echo "Waiting for Alto bundler on port 4337..." + ../scripts/wait-for-port.sh 4337 "Docker_alto" + fi else echo "Starting ${NAME} on port ${PORT}" mkdir -p ./run_files/anvil @@ -134,16 +148,78 @@ _anvil-start $NAME $PORT $CHAIN_ID: fi fi +# Alto bundler for ERC-4337 account abstraction +_alto-start: + #!/usr/bin/env -S bash {{BASH_OPTS}} + if nc -z localhost 4337 > /dev/null 2>&1; then + echo "Alto bundler already running on port 4337" + else + echo "Starting Alto bundler on port 4337..." + mkdir -p ./run_files/anvil + ANVIL_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + ENTRYPOINT_V06="0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + ENTRYPOINT_V07="0x0000000071727De22E5E9d8BAf0edAc6f37da032" + ( nohup bunx @pimlico/alto@0.0.20 \ + --entrypoints "${ENTRYPOINT_V06},${ENTRYPOINT_V07}" \ + --rpc-url "http://127.0.0.1:8545" \ + --executor-private-keys "${ANVIL_PRIVATE_KEY}" \ + --utility-private-key "${ANVIL_PRIVATE_KEY}" \ + --min-balance "0" \ + --safe-mode false \ + --deploy-simulations-contract \ + --port 4337 \ + ./run_files/anvil/alto.log 2>&1 & ) + ../scripts/wait-for-port.sh 4337 alto_bundler + fi + +_alto-stop: + #!/usr/bin/env -S bash {{BASH_OPTS}} + ../scripts/kill-on-port.sh 4337 alto_bundler + +# Run Alto bundler in foreground (for VSCode task) +alto-run: + #!/usr/bin/env -S bash {{BASH_OPTS}} + if nc -z localhost 4337 > /dev/null 2>&1; then + echo "Alto bundler already running on port 4337" + exit 0 + fi + echo "Starting Alto bundler on port 4337..." + ANVIL_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" + ENTRYPOINT_V06="0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" + ENTRYPOINT_V07="0x0000000071727De22E5E9d8BAf0edAc6f37da032" + bunx @pimlico/alto@0.0.20 \ + --entrypoints "${ENTRYPOINT_V06},${ENTRYPOINT_V07}" \ + --rpc-url "http://127.0.0.1:8545" \ + --executor-private-keys "${ANVIL_PRIVATE_KEY}" \ + --utility-private-key "${ANVIL_PRIVATE_KEY}" \ + --min-balance "0" \ + --safe-mode false \ + --deploy-simulations-contract \ + --port 4337 + anvil-base: #!/usr/bin/env -S bash {{BASH_OPTS}} just _anvil-start "base" "8545" "31337" +# Start base anvil chain with Alto bundler (native mode - runs in foreground) +anvil-base-with-alto: + #!/usr/bin/env -S bash {{BASH_OPTS}} + just _anvil-start "base" "8545" "31337" + echo "Waiting for EntryPoint contracts to be deployed..." + # Wait for EntryPoint v0.7 to be deployed (happens during 'Configure Nodes' step) + while ! cast code 0x0000000071727De22E5E9d8BAf0edAc6f37da032 --rpc-url http://127.0.0.1:8545 2>/dev/null | grep -q "^0x6080"; do + sleep 1 + done + echo "EntryPoint deployed. Starting Alto bundler..." + just alto-run + anvil-base-stop: #!/usr/bin/env -S bash {{BASH_OPTS}} if [ "${USE_DOCKER_CHAINS}" = "1" ]; then docker stop towns-base-chain 2>/dev/null || true docker rm towns-base-chain 2>/dev/null || true else + just _alto-stop ../scripts/kill-on-port.sh 8545 anvil_base fi @@ -527,7 +603,7 @@ just-register-nodes-river: register-nodes-river: config-river-chain config-instances just-register-nodes-river -config: config-root config-app-registry config-notifications register-nodes-base register-nodes-river storage-start +config: config-root config-app-registry config-notifications register-nodes-base register-nodes-river storage-start _alto-start build: #!/usr/bin/env -S bash {{BASH_OPTS}} diff --git a/packages/anvil-docker/Dockerfile b/packages/anvil-docker/Dockerfile index bde306d5014..2ca60b7b6f1 100644 --- a/packages/anvil-docker/Dockerfile +++ b/packages/anvil-docker/Dockerfile @@ -32,6 +32,9 @@ RUN curl -fsSL https://bun.sh/install | bash && \ ln -s /root/.bun/bin/bun /usr/local/bin/bun && \ ln -s /root/.bun/bin/bunx /usr/local/bin/bunx +# Install Alto bundler globally using bun (for deploying ERC-4337 contracts) +RUN bun install -g @pimlico/alto@0.0.20 + # Install just from precompiled binary RUN curl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh | bash -s -- --to /usr/local/bin @@ -94,10 +97,20 @@ RUN apt-get update && \ apt-get install -y --no-install-recommends \ bash \ curl \ - netcat-openbsd && \ + netcat-openbsd \ + ca-certificates \ + unzip && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* +# Install Bun for Alto bundler +RUN curl -fsSL https://bun.sh/install | bash && \ + ln -s /root/.bun/bin/bun /usr/local/bin/bun && \ + ln -s /root/.bun/bin/bunx /usr/local/bin/bunx + +# Install Alto bundler globally using bun +RUN bun install -g @pimlico/alto@0.0.20 + # Create app directory WORKDIR /app diff --git a/packages/anvil-docker/scripts/run.sh b/packages/anvil-docker/scripts/run.sh index 43a31c487bd..6346952fdaa 100644 --- a/packages/anvil-docker/scripts/run.sh +++ b/packages/anvil-docker/scripts/run.sh @@ -5,93 +5,79 @@ set -e export RIVER_BLOCK_TIME="${RIVER_BLOCK_TIME:-1}" -# Parse command line arguments -parse_args() { - SHOW_HELP=false - - while [ $# -gt 0 ]; do - case $1 in - --help) - SHOW_HELP=true - shift - ;; - *) - echo "Unknown option: $1" - show_help - exit 1 - ;; - esac - done -} - -show_help() { - cat << EOF -Usage: $0 [OPTIONS] - -OPTIONS: - --help Show this help message - -DESCRIPTION: - This script starts local blockchain networks (base chain and river chain) - and optionally runs tests against them. +# Anvil's first default private key +ANVIL_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" -EXAMPLES: - $0 # Start both chains in the background and exit - $0 --help # Show this help message - -EOF -} +# ERC-4337 EntryPoint addresses +ENTRYPOINT_V06="0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789" +ENTRYPOINT_V07="0x0000000071727De22E5E9d8BAf0edAc6f37da032" +ENTRYPOINT_SIMULATIONS="0x74Cb5e4eE81b86e70f9045036a1C5477de69eE87" main() { - # Parse command line arguments - parse_args "$@" - - # Show help if requested - if [ "$SHOW_HELP" = true ]; then - show_help + if [ "$1" = "--help" ]; then + echo "Usage: CHAIN=base|river $0" + echo "Starts Anvil chain from pre-deployed state. Base chain includes Alto bundler." exit 0 fi - if [ "$CHAIN" = "base" ]; then - start_base_chain - elif [ "$CHAIN" = "river" ]; then - start_river_chain - else - echo "Run with CHAIN=base or CHAIN=river." - exit 1 - fi -} - -setup_trap() { - trap 'cleanup $?' SIGINT SIGTERM EXIT + case "$CHAIN" in + base) start_base_chain ;; + river) start_river_chain ;; + *) + echo "Error: Set CHAIN=base or CHAIN=river" + exit 1 + ;; + esac } start_base_chain() { echo "Starting base chain..." - RIVER_ANVIL_OPTS="--load-state base-anvil-state.json --host 0.0.0.0" bash ./scripts/start-local-basechain.sh - sleep 1 # Give it a moment to start - BASE_PID=$(pgrep -f "anvil.*base-anvil-state.json" | head -n 1) - echo "Base chain started with PID: $BASE_PID" + RIVER_ANVIL_OPTS="--load-state base-anvil-state.json --host 0.0.0.0" bash ./scripts/start-local-basechain.sh & + BASE_PID=$! + + # Wait for Anvil to be ready + while ! nc -z localhost 8545 2>/dev/null; do + echo "Waiting for base chain..." + sleep 1 + done + echo "Base chain ready on port 8545" + + # Start Alto bundler (ERC-4337 contracts are pre-deployed in the Anvil state) + echo "Starting Alto bundler..." + /root/.bun/bin/bunx @pimlico/alto@0.0.20 \ + --entrypoints "$ENTRYPOINT_V06,$ENTRYPOINT_V07" \ + --rpc-url "http://127.0.0.1:8545" \ + --executor-private-keys "$ANVIL_PRIVATE_KEY" \ + --utility-private-key "$ANVIL_PRIVATE_KEY" \ + --min-balance "0" \ + --safe-mode false \ + --entrypoint-simulation-contract "$ENTRYPOINT_SIMULATIONS" \ + --port 4337 & + ALTO_PID=$! + + while ! nc -z localhost 4337 2>/dev/null; do + echo "Waiting for Alto bundler..." + sleep 1 + done + echo "Alto bundler ready on port 4337" + + # Keep container alive + wait $BASE_PID } start_river_chain() { echo "Starting river chain..." - RIVER_ANVIL_OPTS="--load-state river-anvil-state.json --host 0.0.0.0" bash ./scripts/start-local-riverchain.sh - sleep 1 # Give it a moment to start - RIVER_PID=$(pgrep -f "anvil.*river-anvil-state.json" | head -n 1) - echo "River chain started with PID: $RIVER_PID" + RIVER_ANVIL_OPTS="--load-state river-anvil-state.json --host 0.0.0.0" bash ./scripts/start-local-riverchain.sh } -# Function to cleanup on exit cleanup() { - local exit_code=$1 echo "Cleaning up..." - echo "Killing base chain (PID: $BASE_PID)" - kill -9 $BASE_PID 2>/dev/null || true - echo "Killing river chain (PID: $RIVER_PID)" - kill -9 $RIVER_PID 2>/dev/null || true - exit $exit_code + [ -n "$ALTO_PID" ] && kill -9 $ALTO_PID 2>/dev/null || true + [ -n "$BASE_PID" ] && kill -9 $BASE_PID 2>/dev/null || true + exit "${1:-0}" } +trap 'cleanup $?' SIGINT SIGTERM EXIT + # Call main with all arguments main "$@" diff --git a/packages/bot/package.json b/packages/bot/package.json index 67e87dbc5a6..87940988896 100644 --- a/packages/bot/package.json +++ b/packages/bot/package.json @@ -26,6 +26,7 @@ "@towns-protocol/sdk-crypto": "workspace:^", "@towns-protocol/utils": "workspace:^", "@towns-protocol/web3": "workspace:^", + "@towns-protocol/smart-account": "workspace:^", "ethers": "^5.8.0", "image-size": "^2.0.2", "jsonwebtoken": "^9.0.2", diff --git a/packages/bot/src/bot.test.ts b/packages/bot/src/bot.test.ts index 6d9698ff633..7ebf7956f8d 100644 --- a/packages/bot/src/bot.test.ts +++ b/packages/bot/src/bot.test.ts @@ -59,17 +59,83 @@ import { randomUUID } from 'crypto' import { getBalance, readContract, waitForTransactionReceipt } from 'viem/actions' import townsAppAbi from '@towns-protocol/generated/dev/abis/ITownsApp.abi' import channelsFacetAbi from '@towns-protocol/generated/dev/abis/Channels.abi' -import { parseEther } from 'viem' +import walletLinkAbi from '@towns-protocol/generated/dev/abis/WalletLink.abi' +import { + createPublicClient, + createWalletClient, + encodeAbiParameters, + encodeFunctionData, + http, + parseEther, + type Hex, + type PublicClient, + type Transport, + type Chain, + type WalletClient, +} from 'viem' +import { foundry } from 'viem/chains' +import { generatePrivateKey, privateKeyToAccount, type PrivateKeyAccount } from 'viem/accounts' +import { createBundlerClient } from 'viem/account-abstraction' +import { + discoverAccount, + modularAccountAbi, + toModularSmartAccount, +} from '@towns-protocol/smart-account' import { execute } from 'viem/experimental/erc7821' import { UserDevice } from '@towns-protocol/encryption' import { nanoid } from 'nanoid' import { create } from '@bufbuild/protobuf' import { deriveKeyAndIV } from '@towns-protocol/sdk-crypto' +import IAppInstallerAbi from '@towns-protocol/generated/dev/abis/IAppInstaller.abi' const log = dlog('test:bot') const WEBHOOK_URL = `https://localhost:${process.env.BOT_PORT}/webhook` +// Smart account constants +const BUNDLER_RPC_URL = process.env.BUNDLER_RPC_URL ?? 'http://127.0.0.1:4337' +const LINKED_WALLET_MESSAGE = 'Link your external wallet' +const ANVIL_PRIVATE_KEY = + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' as const + +// Minimal ABI to read execution manifest from AccountModules contract +const IExecutionModuleABI = [ + { + name: 'executionManifest', + type: 'function', + inputs: [], + outputs: [ + { + name: '', + type: 'tuple', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + components: [ + { name: 'executionSelector', type: 'bytes4' }, + { name: 'skipRuntimeValidation', type: 'bool' }, + { name: 'allowGlobalValidation', type: 'bool' }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + components: [ + { name: 'executionSelector', type: 'bytes4' }, + { name: 'entityId', type: 'uint32' }, + { name: 'isPreHook', type: 'bool' }, + { name: 'isPostHook', type: 'bool' }, + ], + }, + { name: 'interfaceIds', type: 'bytes4[]' }, + ], + }, + ], + stateMutability: 'pure', + }, +] as const + const SLASH_COMMANDS = [ { name: 'help', description: 'Get help with bot commands' }, { name: 'status', description: 'Check bot status' }, @@ -117,8 +183,17 @@ describe('Bot', { sequential: true }, () => { let bobDefaultChannel: Channel let ethersProvider: ethers.providers.StaticJsonRpcProvider + // Smart account variables for Bob + let bobSmartAccountOwner: PrivateKeyAccount + let bobSmartAccount: Awaited> + let bobSmartAccountAddress: Address + let viemPublicClient: PublicClient + let viemWalletClient: WalletClient + let bundlerClient: ReturnType + beforeAll(async () => { await shouldInitializeBotOwner() + await shouldSetupBobSmartAccount() await shouldMintBot() await shouldInstallBotInSpace() await shouldRegisterBotInAppRegistry() @@ -163,6 +238,191 @@ describe('Bot', { sequential: true }, () => { expect(channelId).toBeDefined() } + const shouldSetupBobSmartAccount = async () => { + // Create viem clients using townsConfig RPC URL + const baseRpcUrl = townsConfig.base.rpcUrl + const spaceFactoryAddress = townsConfig.base.chainConfig.addresses.spaceFactory + + viemPublicClient = createPublicClient({ + chain: foundry, + transport: http(baseRpcUrl), + }) + + viemWalletClient = createWalletClient({ + chain: foundry, + transport: http(baseRpcUrl), + account: privateKeyToAccount(ANVIL_PRIVATE_KEY), + }) + + bundlerClient = createBundlerClient({ + client: viemPublicClient, + transport: http(BUNDLER_RPC_URL), + }) + + // Generate a new private key for the smart account owner + bobSmartAccountOwner = privateKeyToAccount(generatePrivateKey()) + + // Discover the smart account address + const discovered = await discoverAccount( + viemPublicClient, + bobSmartAccountOwner.address, + 'modular', + ) + bobSmartAccountAddress = discovered.address + + // Create the modular smart account instance + bobSmartAccount = await toModularSmartAccount({ + client: viemPublicClient, + owner: bobSmartAccountOwner, + address: bobSmartAccountAddress, + }) + + // Fund the smart account using Anvil's default funded account + const fundTx = await viemWalletClient.sendTransaction({ + to: bobSmartAccount.address, + value: parseEther('1'), + }) + await viemPublicClient.waitForTransactionReceipt({ hash: fundTx }) + + // Create a viem account from Bob's root wallet for signing + const bobViemAccount = privateKeyToAccount(bob.rootWallet.privateKey as Hex) + + // Get nonce for Bob's root key + const nonce = await viemPublicClient.readContract({ + address: spaceFactoryAddress, + abi: walletLinkAbi, + functionName: 'getLatestNonceForRootKey', + args: [bobViemAccount.address], + }) + + // Create EIP-712 signature from Bob's root wallet using viem + // Domain and types must match WalletLinkBase.sol + const signature = await bobViemAccount.signTypedData({ + domain: { + name: 'SpaceFactory', + version: '1', + chainId: foundry.id, + verifyingContract: spaceFactoryAddress, + }, + types: { + LinkedWallet: [ + { name: 'message', type: 'string' }, + { name: 'userID', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + ], + }, + primaryType: 'LinkedWallet', + message: { + message: LINKED_WALLET_MESSAGE, + userID: bobSmartAccount.address, + nonce, + }, + }) + + // Send userOp to link the smart account to Bob's root key + // Note: Explicit gas limits required for Alto bundler with modular accounts + const userOpHash = await bundlerClient.sendUserOperation({ + account: bobSmartAccount, + calls: [ + { + to: spaceFactoryAddress, + abi: walletLinkAbi, + functionName: 'linkCallerToRootKey', + args: [ + { + addr: bobViemAccount.address, + signature, + message: LINKED_WALLET_MESSAGE, + }, + nonce, + ], + }, + ], + callGasLimit: 300000n, + verificationGasLimit: 500000n, + preVerificationGas: 100000n, + }) + + const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, + }) + expect(receipt.success).toBe(true) + + // Verify the link + const isLinked = await viemPublicClient.readContract({ + address: spaceFactoryAddress, + abi: walletLinkAbi, + functionName: 'checkIfLinked', + args: [bobViemAccount.address, bobSmartAccount.address], + }) + expect(isLinked).toBe(true) + const accountModulesAddress = townsConfig.base.chainConfig.addresses.accountModules + if (!accountModulesAddress) { + throw new Error('AccountModules address is not configured') + } + const isAlreadyInstalled = await viemPublicClient.readContract({ + address: accountModulesAddress, + abi: [ + { + name: 'isInstalled', + type: 'function', + inputs: [{ type: 'address', name: 'account' }], + outputs: [{ type: 'bool' }], + stateMutability: 'view', + }, + ] as const, + functionName: 'isInstalled', + args: [bobSmartAccount.address], + }) + if (isAlreadyInstalled) { + return + } + const manifest = await viemPublicClient.readContract({ + address: accountModulesAddress, + abi: IExecutionModuleABI, + functionName: 'executionManifest', + }) + const moduleInstallData = encodeAbiParameters( + [{ type: 'address' }], + [bobSmartAccount.address], + ) + const installExecutionCallData = encodeFunctionData({ + abi: modularAccountAbi, + functionName: 'installExecution', + args: [accountModulesAddress, manifest, moduleInstallData], + }) + const executeBatchCallData = encodeFunctionData({ + abi: modularAccountAbi, + functionName: 'executeBatch', + args: [ + [ + { + target: bobSmartAccount.address, + value: 0n, + data: installExecutionCallData, + }, + ], + ], + }) + + const encodedInstallCallData = await bobSmartAccount.encodeCallData(executeBatchCallData) + + // Use explicit executeBatch calldata to avoid SelfCallRecursionDepthExceeded. + // Increased gas limits to avoid "out of gas: not enough gas for reentrancy sentry" error + const installModulesHash = await bundlerClient.sendUserOperation({ + account: bobSmartAccount, + callData: encodedInstallCallData, + callGasLimit: 2000000n, + verificationGasLimit: 500000n, + preVerificationGas: 100000n, + }) + + const installModulesReceipt = await bundlerClient.waitForUserOperationReceipt({ + hash: installModulesHash, + }) + expect(installModulesReceipt.success).toBe(true) + } + const shouldMintBot = async () => { botWallet = ethers.Wallet.createRandom().connect(ethersProvider) botClientAddress = botWallet.address as Address @@ -293,6 +553,16 @@ describe('Bot', { sequential: true }, () => { expect(validResponse).toBe(true) } + it('should have Bob smart account linked to root key', async () => { + const isLinked = await viemPublicClient.readContract({ + address: townsConfig.base.chainConfig.addresses.spaceFactory, + abi: walletLinkAbi, + functionName: 'checkIfLinked', + args: [bob.userId, bobSmartAccountAddress], + }) + expect(isLinked).toBe(true) + }) + it('should have app_address defined in user stream for bot', async () => { const botUserStreamId = makeUserStreamId(botClientAddress) const streamView = await bobClient.riverConnection.call(async (client) => { @@ -999,12 +1269,12 @@ describe('Bot', { sequential: true }, () => { }), ) - const bobBalanceBefore = (await ethersProvider.getBalance(bob.userId)).toBigInt() + const bobBalanceBefore = (await ethersProvider.getBalance(bobSmartAccountAddress)).toBigInt() // Bob sends a message asking for a tip const { eventId: bobMessageId } = await bobDefaultChannel.sendMessage('Tip me please!') await waitFor(() => receivedMessages.some((x) => x.eventId === bobMessageId)) // Verify bob's balance increased - const bobBalanceAfter = (await ethersProvider.getBalance(bob.userId)).toBigInt() + const bobBalanceAfter = (await ethersProvider.getBalance(bobSmartAccountAddress)).toBigInt() expect(bobBalanceAfter).toBeGreaterThan(bobBalanceBefore) }) @@ -1034,12 +1304,12 @@ describe('Bot', { sequential: true }, () => { }), ) - const bobTokenBalanceBefore = await TestERC20.balanceOf(tokenName, bob.userId) + const bobTokenBalanceBefore = await TestERC20.balanceOf(tokenName, bobSmartAccountAddress) const { eventId: bobMessageId } = await bobDefaultChannel.sendMessage('Tip me ERC-20!') await waitFor(() => receivedMessages.some((x) => x.eventId === bobMessageId)) - const bobTokenBalanceAfter = await TestERC20.balanceOf(tokenName, bob.userId) + const bobTokenBalanceAfter = await TestERC20.balanceOf(tokenName, bobSmartAccountAddress) expect(bobTokenBalanceAfter).toBeGreaterThan(bobTokenBalanceBefore) const botBalanceAfter = await TestERC20.balanceOf(tokenName, bot.appAddress) @@ -2216,4 +2486,38 @@ describe('Bot', { sequential: true }, () => { expect(decrypted?.info?.filename).toBe('bot-avatar.png') }) }) + + it('bot can be installed in DM channel', async () => { + await setForwardSetting(ForwardSettingValue.FORWARD_SETTING_ALL_MESSAGES) + const userOpHash = await bundlerClient.sendUserOperation({ + account: bobSmartAccount, + calls: [ + { + to: appRegistryDapp.installer.address as `0x${string}`, + abi: IAppInstallerAbi, + functionName: 'installApp', + args: [appAddress, bobSmartAccount.address, '0x'], + value: parseEther('0.02'), // for the protocol fee + }, + ], + }) + const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, + }) + expect(receipt.success).toBe(true) + const receivedMessages: OnMessageType[] = [] + subscriptions.push( + bot.onMessage((_h, e) => { + if (e.isDm) { + receivedMessages.push(e) + } + }), + ) + const { streamId } = await bobClient.dms.createDM(bot.botId, appAddress) + const dm = bobClient.dms.getDm(streamId) + const { eventId } = await dm.sendMessage('Hello') + await waitFor(() => receivedMessages.length > 0, { timeoutMS: 15_000 }) + const message = receivedMessages.find((x) => x.eventId === eventId) + expect(message).toBeDefined() + }) }) diff --git a/packages/smart-account/AGENTS.md b/packages/smart-account/AGENTS.md new file mode 100644 index 00000000000..dfcdc85fb39 --- /dev/null +++ b/packages/smart-account/AGENTS.md @@ -0,0 +1,300 @@ +# Smart Account Package + +## Overview + +This package provides an ERC-4337 modular smart account SDK for Towns Protocol, built on [viem](https://viem.sh) for type-safe Ethereum interactions. The primary focus is on **Modular Accounts** (EntryPoint v0.7), which offer extensible validation and execution through a plugin/hook architecture. + +All account creation functions return standard viem `SmartAccount` instances that work seamlessly with viem's bundler client and other viem utilities. + +For legacy compatibility, the package also supports Simple Accounts (EntryPoint v0.6), but modular accounts are recommended for all new development. + +## Essential Commands + +### From package root (/packages/smart-account): + +- `bun run build` - Compile TypeScript to dist/ +- `bun run test` - Run integration tests with vitest +- `bun run test:watch` - Watch mode for development + +### From root directory: + +- `bun run build` - Build this package via turbo +- `bun run lint` - Run linting +- `bun run prettier:fix` - Format code + +## Architecture Overview + +### Modular Accounts (Primary) + +Modular accounts use EntryPoint v0.7 and provide: +- Extensible validation and execution +- Validation modules and hooks +- ReplaySafeHash signature protection +- Plugin architecture for custom logic + +### Factory Pattern + +Accounts are deployed using CREATE2 factories, providing deterministic addresses: +- Same owner = same address across chains +- Address is predictable before deployment +- Factory handles proxy deployment and initialization + +### Subpath Exports + +The package uses subpath exports for tree-shaking: +- `@towns-protocol/smart-account/create2` - Account creation functions +- `@towns-protocol/smart-account/id` - Account detection utilities +- `@towns-protocol/smart-account/abis` - Contract ABIs + +### Key Constants + +From `src/constants.ts`: + +- **EntryPoint v0.7**: `0x0000000071727De22E5E9d8BAf0edAc6f37da032` +- **Modular Account Factory**: `0x00000000000017c61b5bEe81050EC8eFc9c6fecd` +- **Modular Account Implementation**: `0x000000000000c5A9089039570Dd36455b5C07383` +- **Modular Account Storage**: `0x0000000000006E2f9d80CaEc0Da6500f005EB25A` + +## Key Components + +### Primary API - Modular Accounts + +**Account Creation** (`src/create2/toModularSmartAccount.ts`): +- `toModularSmartAccount({ client, owner, address? })` - Creates a modular smart account instance +- Returns a viem `SmartAccount` ready for use with bundlers +- Handles account initialization and signature configuration + +**Account Detection** (`src/id/detectAccountType.ts`): +- `detectAccountType(client, address)` - Identifies if an address is a modular or simple account +- Returns `'modular' | 'simple' | null` +- Checks EIP-1967 implementation slot to determine account type + +**Signature Utilities** (`src/create2/nativeSMASigner.ts`): +- `nativeSMASigner(signer, chainId, accountAddress)` - Creates signer with ReplaySafeHash protection +- `packUOSignature(signature)` - Packs user operation signatures +- `pack1271Signature(signature, entityId)` - Packs EIP-1271 signatures + +### Legacy Support + +For backwards compatibility only: +- `toSimpleSmartAccount()` - Creates EntryPoint v0.6 accounts (legacy) +- `toTownsSmartAccount()` - Auto-discovery factory that supports both types + +## Viem Integration + +This package is built on viem and returns standard viem `SmartAccount` instances. This ensures compatibility with the entire viem ecosystem. + +### Key Integration Points + +**Returns viem SmartAccount**: +All account creation functions (`toModularSmartAccount`, `toSimpleSmartAccount`) return viem's `SmartAccount` type, which includes: +- Standard account interface (address, signMessage, signTypedData, signUserOperationHash) +- Compatible with viem's bundler client +- Works with viem's contract interaction utilities + +**Uses viem Clients**: +- `PublicClient` - For reading blockchain state and account discovery +- `LocalAccount` - For account owner/signer +- `BundlerClient` - For sending user operations + +**Example**: +```typescript +import { createPublicClient, createBundlerClient, http } from 'viem' +import { toModularSmartAccount } from '@towns-protocol/smart-account/create2' + +// Standard viem setup +const publicClient = createPublicClient({ chain, transport: http() }) +const bundlerClient = createBundlerClient({ client: publicClient, transport: http(bundlerUrl) }) + +// Create account - returns viem SmartAccount +const account = await toModularSmartAccount({ client: publicClient, owner }) + +// Use with viem's bundler +await bundlerClient.sendUserOperation({ account, calls: [...] }) +``` + +## Development Patterns + +### Client Setup + +Use viem's `PublicClient` for all account operations: + +```typescript +import { createPublicClient, http } from 'viem' +import { base } from 'viem/chains' + +const publicClient = createPublicClient({ + chain: base, + transport: http() +}) +``` + +### Account Owner + +The `owner` parameter uses viem's `LocalAccount` type: + +```typescript +import { privateKeyToAccount } from 'viem/accounts' + +const owner = privateKeyToAccount('0x...') +``` + +### Async/Await + +All account operations are asynchronous: + +```typescript +const account = await toModularSmartAccount({ + client: publicClient, + owner, +}) +``` + +### Type-Safe ABIs + +Contract ABIs are exported for use with viem: + +```typescript +import { modularAccountAbi } from '@towns-protocol/smart-account/abis' + +// Use with viem's contract functions +``` + +## Testing Strategy + +### Integration Tests + +Location: `test/userop.test.ts` + +Tests cover: +- **Bundler Integration**: Full user operation flow with Alto bundler +- **Batch Operations**: Multiple calls in a single user operation +- **WalletLink Integration**: Linking smart accounts to root keys +- **Account Discovery**: Address computation and deployment detection + +### Test Environment + +- **Anvil**: Local blockchain for testing +- **Alto Bundler**: ERC-4337 bundler implementation +- **Test Pattern**: Fund accounts → send user operations → verify results + +### Key Test Patterns + +1. **Fund accounts before operations**: +```typescript +const fundTx = await walletClient.sendTransaction({ + to: smartAccount.address, + value: parseEther('1') +}) +await publicClient.waitForTransactionReceipt({ hash: fundTx }) +``` + +2. **Use bundler client for user operations**: +```typescript +const bundlerClient = createBundlerClient({ + client: publicClient, + transport: http(bundlerUrl) +}) + +const userOpHash = await bundlerClient.sendUserOperation({ + account: smartAccount, + calls: [{ to: recipient, value: parseEther('0.1') }] +}) +``` + +3. **Verify receipts and balances**: +```typescript +const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash +}) +expect(receipt.success).toBe(true) +``` + +## Common Tasks + +### 1. Creating Modular Accounts + +```typescript +import { toModularSmartAccount } from '@towns-protocol/smart-account/create2' +import { createPublicClient, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' + +const publicClient = createPublicClient({ + chain: yourChain, + transport: http() +}) + +const owner = privateKeyToAccount('0x...') +const account = await toModularSmartAccount({ + client: publicClient, + owner, +}) +``` + +### 2. Detecting Account Type + +```typescript +import { detectAccountType } from '@towns-protocol/smart-account/id' + +const type = await detectAccountType(publicClient, accountAddress) +if (type === 'modular') { + // It's a modular account +} else if (type === 'simple') { + // It's a legacy simple account +} +``` + +### 3. Signing with Replay Protection + +The `toModularSmartAccount` function automatically configures ReplaySafeHash protection for signatures. No additional setup is required. + +### 4. Batch Operations + +```typescript +const userOpHash = await bundlerClient.sendUserOperation({ + account, + calls: [ + { to: recipient1, value: parseEther('0.1') }, + { to: recipient2, value: parseEther('0.2') }, + { to: recipient3, value: parseEther('0.3') } + ] +}) +``` + +### 5. Linking Accounts via WalletLink + +See `test/userop.test.ts` for a complete example of linking smart accounts to root keys using EIP-712 signatures and the SpaceFactory contract. + +## File Structure + +``` +/packages/smart-account/ +├── src/ +│ ├── index.ts # Main exports and re-exports +│ ├── types.ts # Type definitions +│ ├── constants.ts # Contract addresses +│ ├── create2/ +│ │ ├── toModularSmartAccount.ts # Modular account factory (primary) +│ │ ├── toSimpleSmartAccount.ts # Simple account factory (legacy) +│ │ ├── toTownsSmartAccount.ts # Auto-discovery factory (legacy) +│ │ └── nativeSMASigner.ts # Signature utilities +│ ├── id/ +│ │ └── detectAccountType.ts # Type detection +│ └── abis/ +│ ├── modularAccountAbi.ts # Modular account ABI +│ ├── modularFactoryAbi.ts # Modular factory ABI +│ └── ... # Other ABIs +├── test/ +│ └── userop.test.ts # Integration tests +├── package.json +├── tsconfig.json +└── vitest.config.ts +``` + +## Technology Stack + +- **viem** - Blockchain interaction library +- **TypeScript** - Type-safe development +- **Vitest** - Testing framework +- **permissionless** - ERC-4337 utilities (dev) +- **@pimlico/alto** - Bundler for tests (dev) diff --git a/packages/smart-account/README.md b/packages/smart-account/README.md new file mode 100644 index 00000000000..0360d3159ab --- /dev/null +++ b/packages/smart-account/README.md @@ -0,0 +1,235 @@ +# @towns-protocol/smart-account + +ERC-4337 modular smart account SDK for Towns Protocol. Built on [viem](https://viem.sh) for type-safe Ethereum interactions. + +## Features + +- Modular smart accounts (EntryPoint v0.7) +- Seamless viem integration - returns viem `SmartAccount` instances +- Account type detection +- Batch operations support via viem's bundler client +- ReplaySafeHash signature protection +- Tree-shakeable subpath exports + +## Installation + +```bash +bun add @towns-protocol/smart-account +``` + +## Quick Start + +```typescript +import { toModularSmartAccount } from "@towns-protocol/smart-account/create2"; +import { createPublicClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { base } from "viem/chains"; + +const publicClient = createPublicClient({ + chain: base, + transport: http(), +}); + +const owner = privateKeyToAccount("0x..."); + +const account = await toModularSmartAccount({ + client: publicClient, + owner, +}); +``` + +## Viem Integration + +This package is built on viem and returns standard viem `SmartAccount` instances. This means you can use the account with any viem-compatible bundler client: + +```typescript +import { createBundlerClient } from "viem/account-abstraction"; +import { toModularSmartAccount } from "@towns-protocol/smart-account/create2"; + +// Create the smart account +const account = await toModularSmartAccount({ + client: publicClient, + owner: localAccount, +}); + +// Use with viem's bundler client +const bundlerClient = createBundlerClient({ + client: publicClient, + transport: http("https://your-bundler-url.com"), +}); + +// Send user operations using viem's API +const userOpHash = await bundlerClient.sendUserOperation({ + account, // Standard viem SmartAccount + calls: [{ to: recipient, value: parseEther("0.1") }], +}); +``` + +The account works seamlessly with viem's: + +- `createBundlerClient` - For sending user operations +- `createPublicClient` - For reading blockchain state +- Contract interaction utilities - `readContract`, `writeContract`, etc. + +## API Reference + +### `@towns-protocol/smart-account/create2` + +#### `toModularSmartAccount({ client, owner, address? })` + +Creates a modular smart account (EntryPoint v0.7). + +**Parameters:** + +- `client: PublicClient` - Viem public client for blockchain interaction +- `owner: LocalAccount` - Account owner (signer) +- `address?: Address` - Optional: specify address for existing account + +**Returns:** `SmartAccount` instance ready for use with bundlers + +**Example:** + +```typescript +import { toModularSmartAccount } from "@towns-protocol/smart-account/create2"; + +const account = await toModularSmartAccount({ + client: publicClient, + owner: localAccount, +}); +``` + +### `@towns-protocol/smart-account/id` + +#### `detectAccountType(client, address)` + +Detects if an address is a modular or simple account. + +**Parameters:** + +- `client: PublicClient` - Viem public client +- `address: Address` - Address to check + +**Returns:** `'modular' | 'simple' | null` + +**Example:** + +```typescript +import { detectAccountType } from "@towns-protocol/smart-account/id"; + +const type = await detectAccountType(publicClient, accountAddress); +if (type === "modular") { + // It's a modular account +} +``` + +### `@towns-protocol/smart-account/abis` + +Exports contract ABIs for modular accounts: + +- `modularAccountAbi` - Modular account contract ABI +- `modularFactoryAbi` - Modular account factory ABI + +## Usage Examples + +### 1. Creating a Modular Account + +```typescript +import { toModularSmartAccount } from "@towns-protocol/smart-account/create2"; +import { createPublicClient, http } from "viem"; +import { privateKeyToAccount } from "viem/accounts"; +import { base } from "viem/chains"; + +const publicClient = createPublicClient({ + chain: base, + transport: http(), +}); + +const owner = privateKeyToAccount("0x..."); +const account = await toModularSmartAccount({ + client: publicClient, + owner, +}); + +console.log("Account address:", account.address); +``` + +### 2. Detecting Account Type + +```typescript +import { detectAccountType } from "@towns-protocol/smart-account/id"; + +const type = await detectAccountType(publicClient, "0x..."); +console.log("Account type:", type); // 'modular', 'simple', or null +``` + +### 3. Sending User Operations + +```typescript +import { createBundlerClient } from "viem/account-abstraction"; +import { parseEther } from "viem"; + +const bundlerClient = createBundlerClient({ + client: publicClient, + transport: http(bundlerUrl), +}); + +// Single call +const userOpHash = await bundlerClient.sendUserOperation({ + account, + calls: [{ to: recipient, value: parseEther("0.1") }], +}); + +const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, +}); + +console.log("Success:", receipt.success); +``` + +### 4. Batch Operations + +```typescript +const userOpHash = await bundlerClient.sendUserOperation({ + account, + calls: [ + { to: recipient1, value: parseEther("0.1") }, + { to: recipient2, value: parseEther("0.2") }, + { to: recipient3, value: parseEther("0.3") }, + ], +}); +``` + +## Legacy Support + +This package also supports **Simple Accounts** (EntryPoint v0.6) for backwards compatibility: + +```typescript +import { toSimpleSmartAccount } from "@towns-protocol/smart-account/create2"; + +// Create a simple account (legacy) +const simpleAccount = await toSimpleSmartAccount({ + client: publicClient, + owner: localAccount, +}); +``` + +Simple accounts are supported for existing deployments but **modular accounts are recommended for new projects**. + +## Development + +### Running Tests + +```bash +bun run test +``` + +### Building + +```bash +bun run build +``` + +## Related Packages + +- [viem](https://viem.sh) - Blockchain interaction library +- `@towns-protocol/generated` - Contract ABIs and generated types diff --git a/packages/smart-account/package.json b/packages/smart-account/package.json new file mode 100644 index 00000000000..91f56cfeafa --- /dev/null +++ b/packages/smart-account/package.json @@ -0,0 +1,43 @@ +{ + "name": "@towns-protocol/smart-account", + "version": "0.0.1", + "type": "module", + "main": "./dist/index.js", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.js" + }, + "./create2": { + "types": "./dist/create2/index.d.ts", + "import": "./dist/create2/index.js" + }, + "./id": { + "types": "./dist/id/index.d.ts", + "import": "./dist/id/index.js" + }, + "./upgrade": { + "types": "./dist/upgrade/index.d.ts", + "import": "./dist/upgrade/index.js" + }, + "./abis": { + "types": "./dist/abis/index.d.ts", + "import": "./dist/abis/index.js" + } + }, + "scripts": { + "build": "tsc", + "test": "vitest run", + "test:watch": "vitest" + }, + "dependencies": { + "viem": "^2.29.3" + }, + "devDependencies": { + "@towns-protocol/generated": "workspace:^", + "permissionless": "^0.2.57", + "vitest": "^3.2.3", + "typescript": "~5.8.3" + } +} diff --git a/packages/smart-account/src/abis/index.ts b/packages/smart-account/src/abis/index.ts new file mode 100644 index 00000000000..b2daa6a8139 --- /dev/null +++ b/packages/smart-account/src/abis/index.ts @@ -0,0 +1,16 @@ +export { + simpleAccountAbi, + executeBatchAbi, + executeAbi, + upgradeAbi, + ownerAbi, +} from './simpleAccountAbi' +export { simpleFactoryAbi, createAccountAbi } from './simpleFactoryAbi' +export { + modularAccountAbi, + modularExecuteAbi, + modularExecuteBatchAbi, + EXECUTE_USER_OP_SELECTOR, +} from './modularAccountAbi' +export { modularFactoryAbi, accountFactoryAbi } from './modularFactoryAbi' +export { semiModularAccountAbi, semiModularAccountBytecodeAbi } from './semiModularAccountAbi' diff --git a/packages/smart-account/src/abis/modularAccountAbi.ts b/packages/smart-account/src/abis/modularAccountAbi.ts new file mode 100644 index 00000000000..11878fd0e43 --- /dev/null +++ b/packages/smart-account/src/abis/modularAccountAbi.ts @@ -0,0 +1,1282 @@ +// Selector for executeUserOp function (used by modular accounts) +// This is the first 4 bytes of keccak256("executeUserOp((address,uint256,bytes,bytes,bytes32,uint256,bytes32,bytes,bytes),bytes32)") +export const EXECUTE_USER_OP_SELECTOR = '0x8DD7712F' as const + +// Modular account execute ABI (single call with value) +export const modularExecuteAbi = [ + { + type: 'function', + name: 'execute', + inputs: [ + { name: 'target', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + { name: 'data', type: 'bytes', internalType: 'bytes' }, + ], + outputs: [{ name: 'result', type: 'bytes', internalType: 'bytes' }], + stateMutability: 'payable', + }, +] as const + +// Modular account executeBatch ABI (tuple[] with target, value, data) +export const modularExecuteBatchAbi = [ + { + type: 'function', + name: 'executeBatch', + inputs: [ + { + name: 'calls', + type: 'tuple[]', + internalType: 'struct Call[]', + components: [ + { name: 'target', type: 'address', internalType: 'address' }, + { name: 'value', type: 'uint256', internalType: 'uint256' }, + { name: 'data', type: 'bytes', internalType: 'bytes' }, + ], + }, + ], + outputs: [{ name: 'results', type: 'bytes[]', internalType: 'bytes[]' }], + stateMutability: 'payable', + }, +] as const + +export const modularAccountAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'entryPoint', + type: 'address', + internalType: 'contract IEntryPoint', + }, + { + name: 'executionInstallDelegate', + type: 'address', + internalType: 'contract ExecutionInstallDelegate', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'fallback', + stateMutability: 'payable', + }, + { + type: 'receive', + stateMutability: 'payable', + }, + { + type: 'function', + name: 'accountId', + inputs: [], + outputs: [ + { + name: '', + type: 'string', + internalType: 'string', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'entryPoint', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IEntryPoint', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'execute', + inputs: [ + { + name: 'target', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: 'result', + type: 'bytes', + internalType: 'bytes', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'executeBatch', + inputs: [ + { + name: 'calls', + type: 'tuple[]', + internalType: 'struct Call[]', + components: [ + { + name: 'target', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: 'results', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'executeUserOp', + inputs: [ + { + name: 'userOp', + type: 'tuple', + internalType: 'struct PackedUserOperation', + components: [ + { + name: 'sender', + type: 'address', + internalType: 'address', + }, + { + name: 'nonce', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'callData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'accountGasLimits', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'preVerificationGas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'gasFees', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'paymasterAndData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'executeWithRuntimeValidation', + inputs: [ + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'authorization', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'getExecutionData', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: 'data', + type: 'tuple', + internalType: 'struct ExecutionDataView', + components: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'executionHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getValidationData', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + outputs: [ + { + name: 'data', + type: 'tuple', + internalType: 'struct ValidationDataView', + components: [ + { + name: 'validationFlags', + type: 'uint8', + internalType: 'ValidationFlags', + }, + { + name: 'validationHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + { + name: 'executionHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + { + name: 'selectors', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'initializeWithValidation', + inputs: [ + { + name: 'validationConfig', + type: 'bytes25', + internalType: 'ValidationConfig', + }, + { + name: 'selectors', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + { + name: 'installData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'hooks', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'installExecution', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + { + name: 'moduleInstallData', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'installValidation', + inputs: [ + { + name: 'validationConfig', + type: 'bytes25', + internalType: 'ValidationConfig', + }, + { + name: 'selectors', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + { + name: 'installData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'hooks', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'isValidSignature', + inputs: [ + { + name: 'hash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'onERC1155BatchReceived', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: '', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'onERC1155Received', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'onERC721Received', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'performCreate', + inputs: [ + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'isCreate2', + type: 'bool', + internalType: 'bool', + }, + { + name: 'salt', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: 'createdAddr', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'proxiableUUID', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [ + { + name: 'interfaceId', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'uninstallExecution', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + { + name: 'moduleUninstallData', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'uninstallValidation', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + { + name: 'uninstallData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'hookUninstallData', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'upgradeToAndCall', + inputs: [ + { + name: 'newImplementation', + type: 'address', + internalType: 'address', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'validateUserOp', + inputs: [ + { + name: 'userOp', + type: 'tuple', + internalType: 'struct PackedUserOperation', + components: [ + { + name: 'sender', + type: 'address', + internalType: 'address', + }, + { + name: 'nonce', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'callData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'accountGasLimits', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'preVerificationGas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'gasFees', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'paymasterAndData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'userOpHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'missingAccountFunds', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'validationData', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'ExecutionInstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + indexed: false, + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ExecutionUninstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'onUninstallSucceeded', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'manifest', + type: 'tuple', + indexed: false, + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Initialized', + inputs: [ + { + name: 'version', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Upgraded', + inputs: [ + { + name: 'implementation', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ValidationInstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'entityId', + type: 'uint32', + indexed: true, + internalType: 'uint32', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ValidationUninstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'entityId', + type: 'uint32', + indexed: true, + internalType: 'uint32', + }, + { + name: 'onUninstallSucceeded', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'ArrayLengthMismatch', + inputs: [], + }, + { + type: 'error', + name: 'CreateFailed', + inputs: [], + }, + { + type: 'error', + name: 'DeferredActionSignatureInvalid', + inputs: [], + }, + { + type: 'error', + name: 'DeferredValidationHasValidationHooks', + inputs: [], + }, + { + type: 'error', + name: 'ExecutionHookAlreadySet', + inputs: [ + { + name: 'hookConfig', + type: 'bytes25', + internalType: 'HookConfig', + }, + ], + }, + { + type: 'error', + name: 'InterfaceNotSupported', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'InvalidInitialization', + inputs: [], + }, + { + type: 'error', + name: 'ModuleInstallCallbackFailed', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'revertReason', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'NonCanonicalEncoding', + inputs: [], + }, + { + type: 'error', + name: 'NotEntryPoint', + inputs: [], + }, + { + type: 'error', + name: 'PreValidationHookDuplicate', + inputs: [], + }, + { + type: 'error', + name: 'RequireUserOperationContext', + inputs: [], + }, + { + type: 'error', + name: 'SegmentOutOfOrder', + inputs: [], + }, + { + type: 'error', + name: 'SelfCallRecursionDepthExceeded', + inputs: [], + }, + { + type: 'error', + name: 'SignatureValidationInvalid', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'UnauthorizedCallContext', + inputs: [], + }, + { + type: 'error', + name: 'UnexpectedAggregator', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + { + name: 'aggregator', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'UnrecognizedFunction', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'UpgradeFailed', + inputs: [], + }, + { + type: 'error', + name: 'UserOpValidationInvalid', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'ValidationAlreadySet', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'ValidationAssocHookLimitExceeded', + inputs: [], + }, + { + type: 'error', + name: 'ValidationEntityIdInUse', + inputs: [], + }, + { + type: 'error', + name: 'ValidationFunctionMissing', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'ValidationSignatureSegmentMissing', + inputs: [], + }, +] as const diff --git a/packages/smart-account/src/abis/modularFactoryAbi.ts b/packages/smart-account/src/abis/modularFactoryAbi.ts new file mode 100644 index 00000000000..4f1a2f2b286 --- /dev/null +++ b/packages/smart-account/src/abis/modularFactoryAbi.ts @@ -0,0 +1,641 @@ +export const modularFactoryAbi = [ + { + type: 'constructor', + inputs: [ + { + name: '_entryPoint', + type: 'address', + internalType: 'contract IEntryPoint', + }, + { + name: '_accountImpl', + type: 'address', + internalType: 'contract ModularAccount', + }, + { + name: '_semiModularImpl', + type: 'address', + internalType: 'contract SemiModularAccountBytecode', + }, + { + name: '_singleSignerValidationModule', + type: 'address', + internalType: 'address', + }, + { + name: '_webAuthnValidationModule', + type: 'address', + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'ACCOUNT_IMPL', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract ModularAccount', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'ENTRY_POINT', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IEntryPoint', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'SEMI_MODULAR_ACCOUNT_IMPL', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract SemiModularAccountBytecode', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'SINGLE_SIGNER_VALIDATION_MODULE', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'WEBAUTHN_VALIDATION_MODULE', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'acceptOwnership', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'addStake', + inputs: [ + { + name: 'unstakeDelay', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'createAccount', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract ModularAccount', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'createSemiModularAccount', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract SemiModularAccountBytecode', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'createWebAuthnAccount', + inputs: [ + { + name: 'ownerX', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'ownerY', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract ModularAccount', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'getAddress', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAddressSemiModular', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getAddressWebAuthn', + inputs: [ + { + name: 'ownerX', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'ownerY', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getSalt', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'getSaltWebAuthn', + inputs: [ + { + name: 'ownerX', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'ownerY', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'salt', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + ], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'owner', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'pendingOwner', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'renounceOwnership', + inputs: [], + outputs: [], + stateMutability: 'view', + }, + { + type: 'function', + name: 'transferOwnership', + inputs: [ + { + name: 'newOwner', + type: 'address', + internalType: 'address', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'unlockStake', + inputs: [], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdraw', + inputs: [ + { + name: 'to', + type: 'address', + internalType: 'address payable', + }, + { + name: 'token', + type: 'address', + internalType: 'address', + }, + { + name: 'amount', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'withdrawStake', + inputs: [ + { + name: 'withdrawAddress', + type: 'address', + internalType: 'address payable', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'ModularAccountDeployed', + inputs: [ + { + name: 'account', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferStarted', + inputs: [ + { + name: 'previousOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'OwnershipTransferred', + inputs: [ + { + name: 'previousOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'newOwner', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'SemiModularAccountDeployed', + inputs: [ + { + name: 'account', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'owner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'salt', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'WebAuthnModularAccountDeployed', + inputs: [ + { + name: 'account', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'ownerX', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + { + name: 'ownerY', + type: 'uint256', + indexed: true, + internalType: 'uint256', + }, + { + name: 'salt', + type: 'uint256', + indexed: false, + internalType: 'uint256', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'AddressEmptyCode', + inputs: [ + { + name: 'target', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'AddressInsufficientBalance', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'FailedInnerCall', + inputs: [], + }, + { + type: 'error', + name: 'InvalidAction', + inputs: [], + }, + { + type: 'error', + name: 'OwnableInvalidOwner', + inputs: [ + { + name: 'owner', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'OwnableUnauthorizedAccount', + inputs: [ + { + name: 'account', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'SafeERC20FailedOperation', + inputs: [ + { + name: 'token', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'TransferFailed', + inputs: [], + }, +] as const + +// Also export as accountFactoryAbi for backward compatibility +export const accountFactoryAbi = modularFactoryAbi diff --git a/packages/smart-account/src/abis/semiModularAccountAbi.ts b/packages/smart-account/src/abis/semiModularAccountAbi.ts new file mode 100644 index 00000000000..4e64f16cecc --- /dev/null +++ b/packages/smart-account/src/abis/semiModularAccountAbi.ts @@ -0,0 +1,1291 @@ +export const semiModularAccountBytecodeAbi = [ + { + type: 'constructor', + inputs: [ + { + name: 'entryPoint', + type: 'address', + internalType: 'contract IEntryPoint', + }, + { + name: 'executionInstallDelegate', + type: 'address', + internalType: 'contract ExecutionInstallDelegate', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'fallback', + stateMutability: 'payable', + }, + { + type: 'receive', + stateMutability: 'payable', + }, + { + type: 'function', + name: 'accountId', + inputs: [], + outputs: [ + { + name: '', + type: 'string', + internalType: 'string', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'entryPoint', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'contract IEntryPoint', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'execute', + inputs: [ + { + name: 'target', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: 'result', + type: 'bytes', + internalType: 'bytes', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'executeBatch', + inputs: [ + { + name: 'calls', + type: 'tuple[]', + internalType: 'struct Call[]', + components: [ + { + name: 'target', + type: 'address', + internalType: 'address', + }, + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + ], + outputs: [ + { + name: 'results', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'executeUserOp', + inputs: [ + { + name: 'userOp', + type: 'tuple', + internalType: 'struct PackedUserOperation', + components: [ + { + name: 'sender', + type: 'address', + internalType: 'address', + }, + { + name: 'nonce', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'callData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'accountGasLimits', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'preVerificationGas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'gasFees', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'paymasterAndData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'executeWithRuntimeValidation', + inputs: [ + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'authorization', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'getExecutionData', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: 'data', + type: 'tuple', + internalType: 'struct ExecutionDataView', + components: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'executionHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getFallbackSignerData', + inputs: [], + outputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'getValidationData', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + outputs: [ + { + name: 'data', + type: 'tuple', + internalType: 'struct ValidationDataView', + components: [ + { + name: 'validationFlags', + type: 'uint8', + internalType: 'ValidationFlags', + }, + { + name: 'validationHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + { + name: 'executionHooks', + type: 'bytes25[]', + internalType: 'HookConfig[]', + }, + { + name: 'selectors', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'installExecution', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + { + name: 'moduleInstallData', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'installValidation', + inputs: [ + { + name: 'validationConfig', + type: 'bytes25', + internalType: 'ValidationConfig', + }, + { + name: 'selectors', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + { + name: 'installData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'hooks', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'isValidSignature', + inputs: [ + { + name: 'hash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'onERC1155BatchReceived', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: '', + type: 'uint256[]', + internalType: 'uint256[]', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'onERC1155Received', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'onERC721Received', + inputs: [ + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'address', + internalType: 'address', + }, + { + name: '', + type: 'uint256', + internalType: 'uint256', + }, + { + name: '', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [ + { + name: '', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + stateMutability: 'pure', + }, + { + type: 'function', + name: 'performCreate', + inputs: [ + { + name: 'value', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'isCreate2', + type: 'bool', + internalType: 'bool', + }, + { + name: 'salt', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + outputs: [ + { + name: 'createdAddr', + type: 'address', + internalType: 'address', + }, + ], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'proxiableUUID', + inputs: [], + outputs: [ + { + name: '', + type: 'bytes32', + internalType: 'bytes32', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'supportsInterface', + inputs: [ + { + name: 'interfaceId', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + outputs: [ + { + name: '', + type: 'bool', + internalType: 'bool', + }, + ], + stateMutability: 'view', + }, + { + type: 'function', + name: 'uninstallExecution', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + { + name: 'moduleUninstallData', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'uninstallValidation', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + { + name: 'uninstallData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'hookUninstallData', + type: 'bytes[]', + internalType: 'bytes[]', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'updateFallbackSignerData', + inputs: [ + { + name: 'fallbackSigner', + type: 'address', + internalType: 'address', + }, + { + name: 'isDisabled', + type: 'bool', + internalType: 'bool', + }, + ], + outputs: [], + stateMutability: 'nonpayable', + }, + { + type: 'function', + name: 'upgradeToAndCall', + inputs: [ + { + name: 'newImplementation', + type: 'address', + internalType: 'address', + }, + { + name: 'data', + type: 'bytes', + internalType: 'bytes', + }, + ], + outputs: [], + stateMutability: 'payable', + }, + { + type: 'function', + name: 'validateUserOp', + inputs: [ + { + name: 'userOp', + type: 'tuple', + internalType: 'struct PackedUserOperation', + components: [ + { + name: 'sender', + type: 'address', + internalType: 'address', + }, + { + name: 'nonce', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'initCode', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'callData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'accountGasLimits', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'preVerificationGas', + type: 'uint256', + internalType: 'uint256', + }, + { + name: 'gasFees', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'paymasterAndData', + type: 'bytes', + internalType: 'bytes', + }, + { + name: 'signature', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + name: 'userOpHash', + type: 'bytes32', + internalType: 'bytes32', + }, + { + name: 'missingAccountFunds', + type: 'uint256', + internalType: 'uint256', + }, + ], + outputs: [ + { + name: 'validationData', + type: 'uint256', + internalType: 'uint256', + }, + ], + stateMutability: 'nonpayable', + }, + { + type: 'event', + name: 'ExecutionInstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'manifest', + type: 'tuple', + indexed: false, + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ExecutionUninstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'onUninstallSucceeded', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + { + name: 'manifest', + type: 'tuple', + indexed: false, + internalType: 'struct ExecutionManifest', + components: [ + { + name: 'executionFunctions', + type: 'tuple[]', + internalType: 'struct ManifestExecutionFunction[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'skipRuntimeValidation', + type: 'bool', + internalType: 'bool', + }, + { + name: 'allowGlobalValidation', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'executionHooks', + type: 'tuple[]', + internalType: 'struct ManifestExecutionHook[]', + components: [ + { + name: 'executionSelector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'entityId', + type: 'uint32', + internalType: 'uint32', + }, + { + name: 'isPreHook', + type: 'bool', + internalType: 'bool', + }, + { + name: 'isPostHook', + type: 'bool', + internalType: 'bool', + }, + ], + }, + { + name: 'interfaceIds', + type: 'bytes4[]', + internalType: 'bytes4[]', + }, + ], + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'FallbackSignerUpdated', + inputs: [ + { + name: 'newFallbackSigner', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'isDisabled', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Initialized', + inputs: [ + { + name: 'version', + type: 'uint64', + indexed: false, + internalType: 'uint64', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'Upgraded', + inputs: [ + { + name: 'implementation', + type: 'address', + indexed: true, + internalType: 'address', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ValidationInstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'entityId', + type: 'uint32', + indexed: true, + internalType: 'uint32', + }, + ], + anonymous: false, + }, + { + type: 'event', + name: 'ValidationUninstalled', + inputs: [ + { + name: 'module', + type: 'address', + indexed: true, + internalType: 'address', + }, + { + name: 'entityId', + type: 'uint32', + indexed: true, + internalType: 'uint32', + }, + { + name: 'onUninstallSucceeded', + type: 'bool', + indexed: false, + internalType: 'bool', + }, + ], + anonymous: false, + }, + { + type: 'error', + name: 'ArrayLengthMismatch', + inputs: [], + }, + { + type: 'error', + name: 'CreateFailed', + inputs: [], + }, + { + type: 'error', + name: 'DeferredActionSignatureInvalid', + inputs: [], + }, + { + type: 'error', + name: 'DeferredValidationHasValidationHooks', + inputs: [], + }, + { + type: 'error', + name: 'ExecutionHookAlreadySet', + inputs: [ + { + name: 'hookConfig', + type: 'bytes25', + internalType: 'HookConfig', + }, + ], + }, + { + type: 'error', + name: 'FallbackSignerDisabled', + inputs: [], + }, + { + type: 'error', + name: 'FallbackSignerMismatch', + inputs: [], + }, + { + type: 'error', + name: 'FallbackValidationInstallationNotAllowed', + inputs: [], + }, + { + type: 'error', + name: 'InterfaceNotSupported', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'InvalidInitialization', + inputs: [], + }, + { + type: 'error', + name: 'InvalidSignatureType', + inputs: [], + }, + { + type: 'error', + name: 'ModuleInstallCallbackFailed', + inputs: [ + { + name: 'module', + type: 'address', + internalType: 'address', + }, + { + name: 'revertReason', + type: 'bytes', + internalType: 'bytes', + }, + ], + }, + { + type: 'error', + name: 'NonCanonicalEncoding', + inputs: [], + }, + { + type: 'error', + name: 'NotEntryPoint', + inputs: [], + }, + { + type: 'error', + name: 'PreValidationHookDuplicate', + inputs: [], + }, + { + type: 'error', + name: 'RequireUserOperationContext', + inputs: [], + }, + { + type: 'error', + name: 'SegmentOutOfOrder', + inputs: [], + }, + { + type: 'error', + name: 'SelfCallRecursionDepthExceeded', + inputs: [], + }, + { + type: 'error', + name: 'SignatureValidationInvalid', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'UnauthorizedCallContext', + inputs: [], + }, + { + type: 'error', + name: 'UnexpectedAggregator', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + { + name: 'aggregator', + type: 'address', + internalType: 'address', + }, + ], + }, + { + type: 'error', + name: 'UnrecognizedFunction', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'UpgradeFailed', + inputs: [], + }, + { + type: 'error', + name: 'UserOpValidationInvalid', + inputs: [ + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'ValidationAlreadySet', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + { + name: 'validationFunction', + type: 'bytes24', + internalType: 'ModuleEntity', + }, + ], + }, + { + type: 'error', + name: 'ValidationAssocHookLimitExceeded', + inputs: [], + }, + { + type: 'error', + name: 'ValidationEntityIdInUse', + inputs: [], + }, + { + type: 'error', + name: 'ValidationFunctionMissing', + inputs: [ + { + name: 'selector', + type: 'bytes4', + internalType: 'bytes4', + }, + ], + }, + { + type: 'error', + name: 'ValidationSignatureSegmentMissing', + inputs: [], + }, +] as const + +// Also export as semiModularAccountAbi for convenient naming +export const semiModularAccountAbi = semiModularAccountBytecodeAbi diff --git a/packages/smart-account/src/abis/simpleAccountAbi.ts b/packages/smart-account/src/abis/simpleAccountAbi.ts new file mode 100644 index 00000000000..1a3aeafbcab --- /dev/null +++ b/packages/smart-account/src/abis/simpleAccountAbi.ts @@ -0,0 +1,83 @@ +export const executeBatchAbi = [ + { + inputs: [ + { + internalType: 'address[]', + name: 'dest', + type: 'address[]', + }, + { + internalType: 'bytes[]', + name: 'func', + type: 'bytes[]', + }, + ], + name: 'executeBatch', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const + +export const executeAbi = [ + { + inputs: [ + { + internalType: 'address', + name: 'dest', + type: 'address', + }, + { + internalType: 'uint256', + name: 'value', + type: 'uint256', + }, + { + internalType: 'bytes', + name: 'func', + type: 'bytes', + }, + ], + name: 'execute', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const + +export const upgradeAbi = [ + { + inputs: [{ internalType: 'address', name: 'newImplementation', type: 'address' }], + name: 'upgradeTo', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, + { + inputs: [ + { internalType: 'address', name: 'newImplementation', type: 'address' }, + { internalType: 'bytes', name: 'data', type: 'bytes' }, + ], + name: 'upgradeToAndCall', + outputs: [], + stateMutability: 'payable', + type: 'function', + }, +] as const + +export const ownerAbi = [ + { + inputs: [], + name: 'owner', + outputs: [{ internalType: 'address', name: '', type: 'address' }], + stateMutability: 'view', + type: 'function', + }, +] as const + +export const simpleAccountAbi = [ + ...executeBatchAbi, + ...executeAbi, + ...upgradeAbi, + ...ownerAbi, +] as const diff --git a/packages/smart-account/src/abis/simpleFactoryAbi.ts b/packages/smart-account/src/abis/simpleFactoryAbi.ts new file mode 100644 index 00000000000..1c496d5f2ac --- /dev/null +++ b/packages/smart-account/src/abis/simpleFactoryAbi.ts @@ -0,0 +1,55 @@ +export const createAccountAbi = [ + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint256', + name: 'salt', + type: 'uint256', + }, + ], + name: 'createAccount', + outputs: [ + { + internalType: 'contract SimpleAccount', + name: 'ret', + type: 'address', + }, + ], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const + +export const getAddressAbi = [ + { + inputs: [ + { + internalType: 'address', + name: 'owner', + type: 'address', + }, + { + internalType: 'uint256', + name: 'salt', + type: 'uint256', + }, + ], + name: 'getAddress', + outputs: [ + { + internalType: 'address', + name: '', + type: 'address', + }, + ], + stateMutability: 'view', + type: 'function', + }, +] as const + +export const simpleFactoryAbi = [...createAccountAbi, ...getAddressAbi] as const diff --git a/packages/smart-account/src/constants.ts b/packages/smart-account/src/constants.ts new file mode 100644 index 00000000000..5223739ed14 --- /dev/null +++ b/packages/smart-account/src/constants.ts @@ -0,0 +1,16 @@ +// EntryPoints +export const ENTRYPOINT_V06 = '0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789' as const +export const ENTRYPOINT_V07 = '0x0000000071727De22E5E9d8BAf0edAc6f37da032' as const + +// SimpleAccount v0.6 +export const SIMPLE_ACCOUNT_FACTORY = '0x9406Cc6185a346906296840746125a0E44976454' as const +export const SIMPLE_ACCOUNT_IMPL = '0x8ABB13360b87Be5EEb1B98647A016adD927a136c' as const + +// ModularAccount v0.7 +export const MODULAR_ACCOUNT_FACTORY = '0x00000000000017c61b5bEe81050EC8eFc9c6fecd' as const +export const MODULAR_ACCOUNT_IMPL = '0x000000000000c5A9089039570Dd36455b5C07383' as const +export const MODULAR_ACCOUNT_STORAGE = '0x0000000000006E2f9d80CaEc0Da6500f005EB25A' as const + +// EIP-1967 implementation slot for proxy detection +export const EIP1967_IMPL_SLOT = + '0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc' as const diff --git a/packages/smart-account/src/create2/index.ts b/packages/smart-account/src/create2/index.ts new file mode 100644 index 00000000000..9d284301035 --- /dev/null +++ b/packages/smart-account/src/create2/index.ts @@ -0,0 +1,18 @@ +export { toTownsSmartAccount } from './toTownsSmartAccount' +export { toSimpleSmartAccount } from './toSimpleSmartAccount' +export type { + ToSimpleSmartAccountReturnType, + SimpleSmartAccountImplementation, +} from './toSimpleSmartAccount' +export { toModularSmartAccount } from './toModularSmartAccount' +export type { + ToModularSmartAccountReturnType, + ModularSmartAccountImplementation, + ValidationDataParams, +} from './toModularSmartAccount' +export { + nativeSMASigner, + packUOSignature, + pack1271Signature, + DEFAULT_OWNER_ENTITY_ID, +} from './nativeSMASigner' diff --git a/packages/smart-account/src/create2/nativeSMASigner.ts b/packages/smart-account/src/create2/nativeSMASigner.ts new file mode 100644 index 00000000000..fb9fde8406d --- /dev/null +++ b/packages/smart-account/src/create2/nativeSMASigner.ts @@ -0,0 +1,144 @@ +import { + hashMessage, + hashTypedData, + type Hex, + type SignableMessage, + type TypedData, + type TypedDataDefinition, + type Address, + type LocalAccount, + concat, + toHex, +} from 'viem' + +/** + * Default entity ID for the native owner validation + */ +export const DEFAULT_OWNER_ENTITY_ID = 0 + +/** + * Packs the user operation signature for modular accounts + * Format: 0xFF + 0x00 (EOA type) + validationSignature + */ +export function packUOSignature(validationSignature: Hex): Hex { + return concat(['0xFF', '0x00', validationSignature]) +} + +/** + * Packs the 1271 signature for modular accounts + * Format: 0x00 + entityId (4 bytes) + 0xFF + 0x00 (EOA type) + validationSignature + */ +export function pack1271Signature(validationSignature: Hex, entityId: number): Hex { + return concat([ + '0x00', + toHex(entityId, { size: 4 }), + '0xFF', + '0x00', // EOA type signature + validationSignature, + ]) +} + +// 👋 Taken from aa-sdk +// 👋 see aa-sdk for more details account-kit/smart-contracts/src/ma-v2/account/nativeSMASigner.ts +/** + * Creates an object with methods for generating a dummy signature, signing user operation hashes, signing messages, and signing typed data. + * + * @example + * ```ts + * import { nativeSMASigner } from "@account-kit/smart-contracts"; + + * import { LocalAccountSigner } from "@aa-sdk/core"; + * + * const MNEMONIC = "...": + * + * const account = createModularAccountV2({ config }); + * + * const signer = LocalAccountSigner.mnemonicToAccountSigner(MNEMONIC); + * + * const messageSigner = nativeSMASigner(signer, chain, account.address); + * ``` + * + * @param {LocalAccount} signer Signer to use for signing operations + * @param {Chain} chain Chain object for the signer + * @param {Address} accountAddress address of the smart account using this signer + * @returns {object} an object with methods for signing operations and managing signatures + */ +export function nativeSMASigner(signer: LocalAccount, chainId: number, accountAddress: Address) { + return { + /** + * Returns a dummy signature for gas estimation + */ + getDummySignature(): Hex { + const dummyEcdsaSignature = + '0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c' + return packUOSignature(dummyEcdsaSignature) + }, + + /** + * Signs a user operation hash with proper wrapping + */ + async signUserOperationHash(uoHash: Hex): Promise { + const signature = await signer.signMessage({ + message: { raw: uoHash }, + }) + return packUOSignature(signature) + }, + + /** + * Signs a message with 1271 signature wrapping + * Uses ReplaySafeHash typed data for replay protection + */ + async signMessage({ message }: { message: SignableMessage }): Promise { + const hash = hashMessage(message) + const validationSignature = await signer.signTypedData({ + domain: { + chainId, + verifyingContract: accountAddress, + }, + types: { + ReplaySafeHash: [{ name: 'hash', type: 'bytes32' }], + }, + message: { + hash, + }, + primaryType: 'ReplaySafeHash', + }) + return pack1271Signature(validationSignature, DEFAULT_OWNER_ENTITY_ID) + }, + + /** + * Signs typed data with appropriate wrapping + * Handles deferred actions specially (no 1271 wrapping) + */ + async signTypedData< + const typedData extends TypedData | Record, + primaryType extends keyof typedData | 'EIP712Domain' = keyof typedData, + >(typedDataDefinition: TypedDataDefinition): Promise { + // Deferred actions already have replay protection via the account domain + const isDeferredAction = + typedDataDefinition?.primaryType === 'DeferredAction' && + // @ts-expect-error domain may not exist on all typed data + typedDataDefinition?.domain?.verifyingContract === accountAddress + + if (isDeferredAction) { + return signer.signTypedData(typedDataDefinition) + } + + // Apply 1271 wrapping for other typed data + const validationSignature = await signer.signTypedData({ + domain: { + chainId, + verifyingContract: accountAddress, + }, + types: { + ReplaySafeHash: [{ name: 'hash', type: 'bytes32' }], + }, + message: { + hash: hashTypedData(typedDataDefinition), + }, + primaryType: 'ReplaySafeHash', + }) + return pack1271Signature(validationSignature, DEFAULT_OWNER_ENTITY_ID) + }, + } +} diff --git a/packages/smart-account/src/create2/toModularSmartAccount.ts b/packages/smart-account/src/create2/toModularSmartAccount.ts new file mode 100644 index 00000000000..7ed3833b5be --- /dev/null +++ b/packages/smart-account/src/create2/toModularSmartAccount.ts @@ -0,0 +1,377 @@ +import type { Address, Hex, LocalAccount, PublicClient } from 'viem' +import { + encodeFunctionData, + decodeFunctionData, + getContract, + concatHex, + zeroAddress, + maxUint32, + toHex, +} from 'viem' +import { + type SmartAccount, + type SmartAccountImplementation, + type UserOperation, + entryPoint07Abi, + entryPoint07Address, + getUserOperationHash, + toSmartAccount, +} from 'viem/account-abstraction' +import { getChainId, getCode, readContract } from 'viem/actions' +import { getAction } from 'viem/utils' +import { MODULAR_ACCOUNT_FACTORY } from '../constants' +import { modularAccountAbi } from '../abis/modularAccountAbi' +import { modularFactoryAbi } from '../abis/modularFactoryAbi' +import { nativeSMASigner, DEFAULT_OWNER_ENTITY_ID } from './nativeSMASigner' + +export type ModularAccountVersion = '2.0.0' +const ENTRYPOINT_VERSION = '0.7' as const + +// Selector for executeUserOp function +const executeUserOpSelector: Hex = '0x8DD7712F' + +export type ValidationDataParams = + | { validationModuleAddress: Address; entityId?: never } + | { validationModuleAddress?: never; entityId: number } + +export type ModularSmartAccountImplementation = SmartAccountImplementation< + typeof entryPoint07Abi, + typeof ENTRYPOINT_VERSION +> & { + // /** aa-sdk */ + encodeCallData: (callData: Hex) => Promise + // /** aa-sdk */ + getValidationData: (args: ValidationDataParams) => Promise<{ + validationFlags: number + validationHooks: readonly Hex[] + executionHooks: readonly Hex[] + selectors: readonly Hex[] + }> + /** aa-sdk */ + isAccountDeployed: () => Promise +} + +export type ToModularSmartAccountReturnType = SmartAccount + +const getAccountInitCode = async (owner: Address, index = BigInt(0)): Promise => { + if (!owner) throw new Error('Owner account not found') + + return encodeFunctionData({ + abi: modularFactoryAbi, + functionName: 'createSemiModularAccount', + args: [owner, index], + }) +} + +/** + * Decodes callData by removing the executeUserOpSelector prefix if present + */ +function modularDecodeCallData(callData: Hex): Hex { + if (callData.toLowerCase().startsWith(executeUserOpSelector.toLowerCase())) { + return `0x${callData.slice(executeUserOpSelector.length)}` + } + return callData +} + +/** + * Serializes a module entity (address + entityId) into hex + */ +function serializeModuleEntity(moduleAddress: Address, entityId: number): Hex { + return concatHex([moduleAddress, toHex(entityId, { size: 4 })]) +} + +/** + * Gets the nonce for the account from the EntryPoint (v0.7 style with key encoding) + */ +async function getAccountNonce( + client: PublicClient, + address: Address, + entryPointAddress: Address, + key: bigint = 0n, +): Promise { + return getAction( + client, + readContract, + 'readContract', + )({ + address: entryPointAddress, + abi: [ + { + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'key', type: 'uint192' }, + ], + name: 'getNonce', + outputs: [{ name: 'nonce', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ], + functionName: 'getNonce', + args: [address, key], + }) +} + +/** + * @description Creates a Modular Smart Account from a private key. + * + * @returns A Private Key Modular Account. + */ +export async function toModularSmartAccount(params: { + client: PublicClient + owner: LocalAccount + address: Address +}): Promise { + const { + // version, + // factoryAddress: _factoryAddress, + address: accountAddress, + owner: localOwner, + client, + // index = BigInt(0), + // nonceKey, + } = params + + const entryPoint = { + address: entryPoint07Address, + abi: entryPoint07Abi, + version: ENTRYPOINT_VERSION, + } as const + + let chainId: number + + const getMemoizedChainId = async () => { + if (chainId) return chainId + chainId = client.chain + ? client.chain.id + : await getAction(client, getChainId, 'getChainId')({}) + return chainId + } + + const getFactoryArgs = async () => { + return { + factory: MODULAR_ACCOUNT_FACTORY, + // original SALT for simple accounts = 0n, so keeping it consistent here + factoryData: await getAccountInitCode(localOwner.address, 0n), + } + } + + const accountContract = getContract({ + address: accountAddress, + abi: modularAccountAbi, + client, + }) + + return toSmartAccount({ + // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-assignment + client: client as any, + entryPoint, + getFactoryArgs, + async getAddress() { + return accountAddress + + // 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 🚨 + // (╯°□°)╯︵ ┻━┻ + // + // with local geth + permissionless, certain wallets w/ private keys like this one will cause smart account failure + // Geth throws this error: `invalid code: must not begin with 0xef` + // const PRIVATE_KEY = '0x1ffeb42d5991715177ec8bf1f06aef3a62e558d3dc6a686cc9fe23a8ab652bb2' + // + // The root of the problem is the getSenderAddress fn, which makes an eth_call where some smart account deployment code starts with `0xef` + // and geth (at least the local one) does not allow that b/c it's part of EOF (ethereum object format), and EOF is not being included until pectra upgrade + // + // This error also throws on vanilla permissionless.js in a separate repo! + // + // Get the sender address based on the init code + // accountAddress = await getSenderAddress(client, { + // factory, + // factoryData, + // entryPointAddress: entryPoint.address, + // }) + // + // + // + // This problem might only effect local geth dev - but I'm not gonna take chances here + // so I'm using the getInitData fn, which does the same thing, and has never posed problems + // const { addr } = await getInitData({ + // type: 'modular', + // signerAddress: localOwner.address, + // rpcUrl, + // }) + // accountAddress = addr + + // return accountAddress + }, + /** + * from aa-sdk + * @param callData + * @returns + */ + async encodeCallData(callData: Hex): Promise { + const validationData = await this.getValidationData({ + entityId: Number(0), + }) + + return validationData.executionHooks.length + ? concatHex([executeUserOpSelector, callData]) + : callData + }, + async encodeCalls(calls) { + if (calls.length > 1) { + return this.encodeCallData( + encodeFunctionData({ + abi: modularAccountAbi, + functionName: 'executeBatch', + args: [ + calls.map((a) => ({ + target: a.to, + value: a.value ?? 0n, + data: a.data ?? '0x', + })), + ], + }), + ) + } + + const call = calls.length === 0 ? undefined : calls[0] + + if (!call) { + throw new Error('No calls to encode') + } + + const data = await this.encodeCallData( + encodeFunctionData({ + abi: modularAccountAbi, + functionName: 'execute', + args: [call.to, call.value ?? 0n, call.data ?? '0x'], + }), + ) + + return data + }, + async decodeCalls(callData) { + try { + const decoded = decodeFunctionData({ + abi: modularAccountAbi, + data: modularDecodeCallData(callData), + }) + + if (decoded.functionName === 'executeBatch') { + const calls: { + to: Address + value: bigint + data: Hex + }[] = [] + + for (let i = 0; i < decoded.args[0].length; i++) { + calls.push({ + to: decoded.args[0][i].target, + value: decoded.args[0][i].value, + data: decoded.args[0][i].data, + }) + } + + return calls + } else if (decoded.functionName === 'execute') { + return [ + { + to: decoded.args[0], + value: decoded.args[1], + data: decoded.args[2], + }, + ] + } + + throw new Error('Invalid function name') + } catch (_) { + throw new Error('Invalid call data') + } + }, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + async getNonce(_args) { + const isGlobalValidation = true + // viem passes in a nonce key if we don't set it toModularSmartAccount, and it causes ops to fail + // setting 0n here is the same as aa-sdk + const nonceKey = 0n + + // this is how aa-sdk gets nonce for modular account + // globalValidation ? it defaults to true in the sdk so i'm setting it here + const fullNonceKey: bigint = + (nonceKey << 40n) + + (BigInt(DEFAULT_OWNER_ENTITY_ID) << 8n) + + (isGlobalValidation ? 1n : 0n) + + // first op, this results in nonce like 0x0000001 + return getAccountNonce(client, accountAddress, entryPoint.address, fullNonceKey) + }, + /** + * from aa-sdk + */ + async isAccountDeployed() { + return !!(await getAction(client, getCode, 'getCode')({ address: accountAddress })) + }, + /** + * from aa-sdk + */ + async getValidationData(args: ValidationDataParams) { + if (!(await this.isAccountDeployed())) { + return { + validationHooks: [], + executionHooks: [], + selectors: [], + validationFlags: 0, + } + } + + const { validationModuleAddress, entityId } = args + return await accountContract.read.getValidationData([ + serializeModuleEntity( + validationModuleAddress ?? zeroAddress, + entityId ?? Number(maxUint32), + ), + ]) + }, + async getStubSignature() { + return nativeSMASigner( + localOwner, + await getMemoizedChainId(), + accountAddress, + ).getDummySignature() + }, + async sign({ hash }) { + return this.signMessage({ message: hash }) + }, + async signMessage({ message }) { + return nativeSMASigner( + localOwner, + await getMemoizedChainId(), + accountAddress, + ).signMessage({ message }) + }, + async signTypedData(typedData) { + return nativeSMASigner( + localOwner, + await getMemoizedChainId(), + accountAddress, + ).signTypedData(typedData) + }, + async signUserOperation(parameters) { + const { chainId = await getMemoizedChainId(), ...userOperation } = parameters + + const hash = getUserOperationHash({ + userOperation: { + ...userOperation, + signature: '0x', + } as UserOperation<'0.7'>, + entryPointAddress: entryPoint.address, + entryPointVersion: entryPoint.version, + chainId: chainId, + }) + return nativeSMASigner( + localOwner, + await getMemoizedChainId(), + accountAddress, + ).signUserOperationHash(hash) + }, + }) as Promise +} diff --git a/packages/smart-account/src/create2/toSimpleSmartAccount.ts b/packages/smart-account/src/create2/toSimpleSmartAccount.ts new file mode 100644 index 00000000000..8e2422c0ac9 --- /dev/null +++ b/packages/smart-account/src/create2/toSimpleSmartAccount.ts @@ -0,0 +1,195 @@ +import type { Address, Hex, LocalAccount, PublicClient } from 'viem' +import { encodeFunctionData, decodeFunctionData } from 'viem' +import { + type SmartAccount, + type SmartAccountImplementation, + type UserOperation, + entryPoint06Abi, + entryPoint06Address, + getUserOperationHash, + toSmartAccount, +} from 'viem/account-abstraction' +import { readContract } from 'viem/actions' +import { getAction } from 'viem/utils' +import { SIMPLE_ACCOUNT_FACTORY } from '../constants' +import { simpleAccountAbi } from '../abis/simpleAccountAbi' +import { simpleFactoryAbi } from '../abis/simpleFactoryAbi' + +const ENTRYPOINT_VERSION = '0.6' as const + +export type SimpleSmartAccountImplementation = SmartAccountImplementation< + typeof entryPoint06Abi, + typeof ENTRYPOINT_VERSION +> + +export type ToSimpleSmartAccountReturnType = SmartAccount + +/** + * Encodes the factory init code for creating a SimpleAccount + */ +function getAccountInitCode(owner: Address, index: bigint = 0n): Hex { + return encodeFunctionData({ + abi: simpleFactoryAbi, + functionName: 'createAccount', + args: [owner, index], + }) +} + +/** + * Gets the nonce for the account from the EntryPoint + */ +async function getAccountNonce( + client: PublicClient, + address: Address, + entryPointAddress: Address, + key: bigint = 0n, +): Promise { + return getAction( + client, + readContract, + 'readContract', + )({ + address: entryPointAddress, + abi: [ + { + inputs: [ + { name: 'sender', type: 'address' }, + { name: 'key', type: 'uint192' }, + ], + name: 'getNonce', + outputs: [{ name: 'nonce', type: 'uint256' }], + stateMutability: 'view', + type: 'function', + }, + ], + functionName: 'getNonce', + args: [address, key], + }) +} + +/** + * Creates a Simple Smart Account (EntryPoint v0.6) + * + * @param config - Configuration for the simple smart account + * @returns A viem SmartAccount instance + */ +export async function toSimpleSmartAccount(params: { + client: PublicClient + owner: LocalAccount + address: Address +}): Promise { + const { client, owner, address: accountAddress } = params + + const entryPoint = { + address: entryPoint06Address, + abi: entryPoint06Abi, + version: ENTRYPOINT_VERSION, + } as const + + const getFactoryArgs = async () => { + return { + factory: SIMPLE_ACCOUNT_FACTORY, + factoryData: getAccountInitCode(owner.address, 0n), + } + } + + return toSmartAccount({ + client, + entryPoint, + getFactoryArgs, + + async getAddress() { + return accountAddress + }, + + async encodeCalls(calls) { + if (calls.length === 1) { + const call = calls[0] + return encodeFunctionData({ + abi: simpleAccountAbi, + functionName: 'execute', + args: [call.to, call.value ?? 0n, call.data ?? '0x'], + }) + } + + // executeBatch for v0.6 SimpleAccount uses (address[], bytes[]) signature + return encodeFunctionData({ + abi: simpleAccountAbi, + functionName: 'executeBatch', + args: [calls.map((call) => call.to), calls.map((call) => call.data ?? '0x')], + }) + }, + + async decodeCalls(callData) { + try { + const decoded = decodeFunctionData({ + abi: simpleAccountAbi, + data: callData, + }) + + if (decoded.functionName === 'execute') { + return [ + { + to: decoded.args[0] as Address, + value: decoded.args[1] as bigint, + data: decoded.args[2] as Hex, + }, + ] + } else if (decoded.functionName === 'executeBatch') { + const addresses = decoded.args[0] as Address[] + const datas = decoded.args[1] as Hex[] + return addresses.map((to, i) => ({ + to, + value: 0n, + data: datas[i], + })) + } + + throw new Error('Invalid function name') + } catch { + throw new Error('Invalid call data') + } + }, + + async getNonce(args) { + const key = args?.key ?? 0n + return getAccountNonce(client, accountAddress, entryPoint.address, key) + }, + + async getStubSignature() { + // Standard 65-byte dummy signature for gas estimation + return '0xfffffffffffffffffffffffffffffff0000000000000000000000000000000007aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa1c' + }, + + async sign({ hash }) { + return owner.signMessage({ message: { raw: hash } }) + }, + + async signMessage({ message }) { + return owner.signMessage({ message }) + }, + + async signTypedData(typedData) { + return owner.signTypedData(typedData) + }, + + async signUserOperation(parameters) { + const chainId = parameters.chainId ?? client.chain?.id + if (!chainId) { + throw new Error('Chain ID is required for signing user operations') + } + + const hash = getUserOperationHash({ + userOperation: { + ...parameters, + signature: '0x', + } as UserOperation<'0.6'>, + entryPointAddress: entryPoint.address, + entryPointVersion: entryPoint.version, + chainId, + }) + + return owner.signMessage({ message: { raw: hash } }) + }, + }) +} diff --git a/packages/smart-account/src/create2/toTownsSmartAccount.ts b/packages/smart-account/src/create2/toTownsSmartAccount.ts new file mode 100644 index 00000000000..dd8a5c46f93 --- /dev/null +++ b/packages/smart-account/src/create2/toTownsSmartAccount.ts @@ -0,0 +1,46 @@ +import { discoverAccount } from '../id/discoverAccount' +import { toSimpleSmartAccount } from './toSimpleSmartAccount' +import { toModularSmartAccount } from './toModularSmartAccount' +import type { Address, LocalAccount, PublicClient } from 'viem' +import type { SmartAccountType } from '../types' + +/** + * Creates a Towns Smart Account with automatic account type discovery + * + * This function will: + * 1. Discover or use the forced address + * 2. Detect if a modular or simple account is deployed + * 3. Create the appropriate account implementation + * + * @param config - Configuration for the Towns smart account + * @returns A viem SmartAccount ready for use with bundlers + * + * @example + * ```ts + * const account = await toTownsSmartAccount({ + * client: publicClient, + * owner: localAccount, + * preferredType: 'modular', // optional, defaults to 'modular' + * }) + * + * console.log(account.address) + * ``` + */ +export async function toTownsSmartAccount(config: { + client: PublicClient + owner: LocalAccount + preferredType?: SmartAccountType + address?: Address +}) { + const { client, owner, preferredType = 'modular', address: forceAddress } = config + + // Discover or use forced address + const discovered = forceAddress + ? { address: forceAddress, type: preferredType, deployed: false } + : await discoverAccount(client, owner.address, preferredType) + + // Route to correct implementation based on discovered/preferred type + return discovered.type === 'modular' + ? await toModularSmartAccount({ client, owner, address: discovered.address }) + : await toSimpleSmartAccount({ client, owner, address: discovered.address }) +} diff --git a/packages/smart-account/src/id/detectAccountType.ts b/packages/smart-account/src/id/detectAccountType.ts new file mode 100644 index 00000000000..ab77659d53c --- /dev/null +++ b/packages/smart-account/src/id/detectAccountType.ts @@ -0,0 +1,32 @@ +import type { Address, PublicClient } from 'viem' +import type { SmartAccountType } from '../types' +import { + EIP1967_IMPL_SLOT, + SIMPLE_ACCOUNT_IMPL, + MODULAR_ACCOUNT_IMPL, + MODULAR_ACCOUNT_STORAGE, +} from '../constants' + +export async function detectAccountType( + client: PublicClient, + address: Address, +): Promise { + const impl = await client.getStorageAt({ + address, + slot: EIP1967_IMPL_SLOT, + }) + if (!impl || impl === '0x') return null + + const implAddress = ('0x' + impl.slice(-40)) as Address + + if (implAddress.toLowerCase() === SIMPLE_ACCOUNT_IMPL.toLowerCase()) { + return 'simple' + } + if ( + implAddress.toLowerCase() === MODULAR_ACCOUNT_IMPL.toLowerCase() || + implAddress.toLowerCase() === MODULAR_ACCOUNT_STORAGE.toLowerCase() + ) { + return 'modular' + } + return null +} diff --git a/packages/smart-account/src/id/discoverAccount.ts b/packages/smart-account/src/id/discoverAccount.ts new file mode 100644 index 00000000000..db9507dc022 --- /dev/null +++ b/packages/smart-account/src/id/discoverAccount.ts @@ -0,0 +1,43 @@ +import type { Address, PublicClient } from 'viem' +import type { SmartAccountType } from '../types' +import { simpleFactoryAbi, modularFactoryAbi } from '../abis' +import { SIMPLE_ACCOUNT_FACTORY, MODULAR_ACCOUNT_FACTORY } from '../constants' + +export async function discoverAccount( + client: PublicClient, + owner: Address, + preferredType: SmartAccountType = 'modular', +): Promise<{ address: Address; type: SmartAccountType; deployed: boolean }> { + const [simpleAddr, modularAddr] = await Promise.all([ + client.readContract({ + address: SIMPLE_ACCOUNT_FACTORY, + abi: simpleFactoryAbi, + functionName: 'getAddress', + args: [owner, 0n], + }), + client.readContract({ + address: MODULAR_ACCOUNT_FACTORY, + abi: modularFactoryAbi, + functionName: 'getAddressSemiModular', + args: [owner, 0n], + }), + ]) + + const [simpleCode, modularCode] = await Promise.all([ + client.getCode({ address: simpleAddr }), + client.getCode({ address: modularAddr }), + ]) + + if (modularCode && modularCode !== '0x') { + return { address: modularAddr, type: 'modular', deployed: true } + } + if (simpleCode && simpleCode !== '0x') { + return { address: simpleAddr, type: 'simple', deployed: true } + } + + return { + address: preferredType === 'modular' ? modularAddr : simpleAddr, + type: preferredType, + deployed: false, + } +} diff --git a/packages/smart-account/src/id/index.ts b/packages/smart-account/src/id/index.ts new file mode 100644 index 00000000000..1feb60563cf --- /dev/null +++ b/packages/smart-account/src/id/index.ts @@ -0,0 +1,2 @@ +export { discoverAccount } from './discoverAccount' +export { detectAccountType } from './detectAccountType' diff --git a/packages/smart-account/src/index.ts b/packages/smart-account/src/index.ts new file mode 100644 index 00000000000..2a754d0a60d --- /dev/null +++ b/packages/smart-account/src/index.ts @@ -0,0 +1,17 @@ +// @towns-protocol/smart-account +// +// Subpath imports are available for tree-shaking: +// import { toTownsSmartAccount } from '@towns-protocol/smart-account/create2' +// import { discoverAccount } from '@towns-protocol/smart-account/id' +// import { needsUpgrade, encodeUpgrade } from '@towns-protocol/smart-account/upgrade' +// +// Re-exports below are for legacy packages using moduleResolution: "node" +// which doesn't support subpath exports. + +export * from './types' + +// Re-export all modules for legacy compatibility +export * from './create2' +export * from './id' +export * from './upgrade' +export * from './abis' diff --git a/packages/smart-account/src/types.ts b/packages/smart-account/src/types.ts new file mode 100644 index 00000000000..d750187f9d7 --- /dev/null +++ b/packages/smart-account/src/types.ts @@ -0,0 +1 @@ +export type SmartAccountType = 'simple' | 'modular' diff --git a/packages/smart-account/src/upgrade/encodeUpgrade.ts b/packages/smart-account/src/upgrade/encodeUpgrade.ts new file mode 100644 index 00000000000..49bb37fda69 --- /dev/null +++ b/packages/smart-account/src/upgrade/encodeUpgrade.ts @@ -0,0 +1,35 @@ +import type { Address, Hex } from 'viem' +import { encodeFunctionData } from 'viem' +import { simpleAccountAbi } from '../abis/simpleAccountAbi' +import { MODULAR_ACCOUNT_STORAGE } from '../constants' + +// ABI for the initialize function on SemiModularAccountBytecode +// This function is called during upgradeToAndCall to set up the new owner +const initializeAbi = [ + { + inputs: [{ internalType: 'address', name: 'owner', type: 'address' }], + name: 'initialize', + outputs: [], + stateMutability: 'nonpayable', + type: 'function', + }, +] as const + +export function encodeUpgrade( + smartAccountAddress: Address, + owner: Address, +): { to: Address; data: Hex } { + const initializeData = encodeFunctionData({ + abi: initializeAbi, + functionName: 'initialize', + args: [owner], + }) + + const data = encodeFunctionData({ + abi: simpleAccountAbi, + functionName: 'upgradeToAndCall', + args: [MODULAR_ACCOUNT_STORAGE, initializeData], + }) + + return { to: smartAccountAddress, data } +} diff --git a/packages/smart-account/src/upgrade/index.ts b/packages/smart-account/src/upgrade/index.ts new file mode 100644 index 00000000000..5475def96d4 --- /dev/null +++ b/packages/smart-account/src/upgrade/index.ts @@ -0,0 +1,2 @@ +export { needsUpgrade } from './needsUpgrade' +export { encodeUpgrade } from './encodeUpgrade' diff --git a/packages/smart-account/src/upgrade/needsUpgrade.ts b/packages/smart-account/src/upgrade/needsUpgrade.ts new file mode 100644 index 00000000000..6d4c133a4e7 --- /dev/null +++ b/packages/smart-account/src/upgrade/needsUpgrade.ts @@ -0,0 +1,8 @@ +import type { SmartAccountType } from '../types' + +export function needsUpgrade( + preferredType: SmartAccountType, + currentType: SmartAccountType, +): boolean { + return preferredType === 'modular' && currentType === 'simple' +} diff --git a/packages/smart-account/test/userop.test.ts b/packages/smart-account/test/userop.test.ts new file mode 100644 index 00000000000..266c7acbc62 --- /dev/null +++ b/packages/smart-account/test/userop.test.ts @@ -0,0 +1,305 @@ +import { describe, it, expect, beforeAll } from 'vitest' +import { + createPublicClient, + createWalletClient, + http, + parseEther, + type Hex, + type Address, + type PublicClient, + type Transport, + type Chain, + type WalletClient, +} from 'viem' +import { foundry } from 'viem/chains' +import { generatePrivateKey, privateKeyToAccount, type PrivateKeyAccount } from 'viem/accounts' +import { createBundlerClient } from 'viem/account-abstraction' +import { toModularSmartAccount } from '../src/create2/toModularSmartAccount' +import { toTownsSmartAccount } from '../src/create2/toTownsSmartAccount' +import walletLinkAbi from '@towns-protocol/generated/v3/abis/WalletLink.abi' +import { discoverAccount } from '../src/id/discoverAccount' + +// SpaceFactory address from local deployment +const SPACE_FACTORY_ADDRESS = process.env.BASE_ADDRESSES_SPACE_FACTORY as Address + +// Anvil default funded account +const ANVIL_PRIVATE_KEY = + '0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80' as const + +const ANVIL_RPC_URL = process.env.ANVIL_RPC_URL || 'http://127.0.0.1:8545' +const BUNDLER_RPC_URL = process.env.BUNDLER_RPC_URL || 'http://127.0.0.1:4337' + +describe('UserOp Integration Tests', () => { + // Tests that require external anvil instance with Alto bundler + // Run "Start Local Dev" or "just anvils" (with USE_DOCKER_CHAINS=1) before running these tests + describe('with Alto bundler', () => { + let bundlerClient: ReturnType + let publicClient: PublicClient + let walletClient: WalletClient + + beforeAll(async () => { + publicClient = createPublicClient({ + chain: foundry, + transport: http(ANVIL_RPC_URL), + }) + + walletClient = createWalletClient({ + chain: foundry, + transport: http(ANVIL_RPC_URL), + account: privateKeyToAccount(ANVIL_PRIVATE_KEY), + }) + + // Use Alto bundler from Docker (started via "Start Local Dev" or "just anvils") + bundlerClient = createBundlerClient({ + client: publicClient, + transport: http(BUNDLER_RPC_URL), + }) + }) + + it('should create a modular smart account and send a userOp', async () => { + // Create owner and smart account + const owner = privateKeyToAccount(generatePrivateKey()) + const discovered = await discoverAccount(publicClient, owner.address, 'modular') + const smartAccount = await toModularSmartAccount({ + client: publicClient, + owner, + address: discovered.address, + }) + + expect(smartAccount.address).toBeDefined() + const fundTx = await walletClient.sendTransaction({ + to: smartAccount.address, + value: parseEther('1'), + }) + await publicClient.waitForTransactionReceipt({ hash: fundTx }) + const recipient = privateKeyToAccount(generatePrivateKey()).address + // Note: Explicit gas limits are required because Alto's gas estimation + // has a second validation pass that fails for modular accounts. + // This is a known Alto issue with Alchemy's ModularAccountFactory. + const userOpHash = await bundlerClient.sendUserOperation({ + account: smartAccount, + calls: [{ to: recipient, value: parseEther('0.1') }], + callGasLimit: 200000n, + verificationGasLimit: 500000n, + preVerificationGas: 100000n, + }) + const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, + }) + expect(receipt.success).toBe(true) + const recipientBalance = await publicClient.getBalance({ address: recipient }) + expect(recipientBalance).toBe(parseEther('0.1')) + }) + + it('should handle batch operations', async () => { + const owner = privateKeyToAccount(generatePrivateKey()) + const discovered = await discoverAccount(publicClient, owner.address, 'modular') + const smartAccount = await toModularSmartAccount({ + client: publicClient, + owner, + address: discovered.address, + }) + + const fundTx = await walletClient.sendTransaction({ + to: smartAccount.address, + value: parseEther('2'), + }) + await publicClient.waitForTransactionReceipt({ hash: fundTx }) + + const recipient1 = privateKeyToAccount(generatePrivateKey()).address + const recipient2 = privateKeyToAccount(generatePrivateKey()).address + + // Note: Explicit gas limits are required because Alto's gas estimation + // has a second validation pass that fails for modular accounts. + const userOpHash = await bundlerClient.sendUserOperation({ + account: smartAccount, + calls: [ + { to: recipient1, value: parseEther('0.1') }, + { to: recipient2, value: parseEther('0.2') }, + ], + callGasLimit: 300000n, + verificationGasLimit: 500000n, + preVerificationGas: 100000n, + }) + + const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, + }) + + expect(receipt.success).toBe(true) + expect(await publicClient.getBalance({ address: recipient1 })).toBe(parseEther('0.1')) + expect(await publicClient.getBalance({ address: recipient2 })).toBe(parseEther('0.2')) + }) + + it('should link smart account to root key via WalletLink', async () => { + const rootKey = privateKeyToAccount(generatePrivateKey()) + const owner = privateKeyToAccount(generatePrivateKey()) + const discovered = await discoverAccount(publicClient, owner.address, 'modular') + const smartAccount = await toModularSmartAccount({ + client: publicClient, + owner, + address: discovered.address, + }) + + // Fund the smart account + const fundTx = await walletClient.sendTransaction({ + to: smartAccount.address, + value: parseEther('1'), + }) + await publicClient.waitForTransactionReceipt({ hash: fundTx }) + + // Get the nonce for the root key + const nonce = await publicClient.readContract({ + address: SPACE_FACTORY_ADDRESS, + abi: walletLinkAbi, + functionName: 'getLatestNonceForRootKey', + args: [rootKey.address], + }) + + // Create EIP-712 signature from root key + // Domain and types must match WalletLinkBase.sol + const LINKED_WALLET_MESSAGE = 'Link your external wallet' + const domain = { + name: 'SpaceFactory', + version: '1', + chainId: foundry.id, + verifyingContract: SPACE_FACTORY_ADDRESS, + } + const types = { + LinkedWallet: [ + { name: 'message', type: 'string' }, + { name: 'userID', type: 'address' }, + { name: 'nonce', type: 'uint256' }, + ], + } + const value = { + message: LINKED_WALLET_MESSAGE, + userID: smartAccount.address as Address, + nonce, + } + + const signature = await rootKey.signTypedData({ + domain, + types, + primaryType: 'LinkedWallet', + message: value, + }) + + // Send userOp to link the smart account to the root key + // Note: Explicit gas limits required for Alto bundler with modular accounts + const userOpHash = await bundlerClient.sendUserOperation({ + account: smartAccount, + calls: [ + { + to: SPACE_FACTORY_ADDRESS, + abi: walletLinkAbi, + functionName: 'linkCallerToRootKey', + args: [ + { + addr: rootKey.address, + signature, + message: LINKED_WALLET_MESSAGE, + }, + nonce, + ], + }, + ], + callGasLimit: 300000n, + verificationGasLimit: 500000n, + preVerificationGas: 100000n, + }) + + const receipt = await bundlerClient.waitForUserOperationReceipt({ + hash: userOpHash, + }) + expect(receipt.success).toBe(true) + const isLinked = await publicClient.readContract({ + address: SPACE_FACTORY_ADDRESS, + abi: walletLinkAbi, + functionName: 'checkIfLinked', + args: [rootKey.address, smartAccount.address], + }) + expect(isLinked).toBe(true) + }) + }) + + describe('account creation (no bundler)', () => { + let publicClient: PublicClient + + beforeAll(() => { + publicClient = createPublicClient({ + chain: foundry, + transport: http(ANVIL_RPC_URL), + }) + }) + + it('modular account address is deterministic', async () => { + const owner = privateKeyToAccount( + '0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' as Hex, + ) + const account = await toTownsSmartAccount({ + client: publicClient, + owner, + preferredType: 'modular', + }) + + expect(account.address).toMatch(/^0x[a-fA-F0-9]{40}$/) + }) + + it('simple account address is deterministic', async () => { + const owner = privateKeyToAccount( + '0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890' as Hex, + ) + const account = await toTownsSmartAccount({ + client: publicClient, + owner, + preferredType: 'simple', + }) + + expect(account.address).toMatch(/^0x[a-fA-F0-9]{40}$/) + }) + + it('different owners get different addresses', async () => { + const owner1 = privateKeyToAccount( + '0x1111111111111111111111111111111111111111111111111111111111111111' as Hex, + ) + const owner2 = privateKeyToAccount( + '0x2222222222222222222222222222222222222222222222222222222222222222' as Hex, + ) + + const account1 = await toTownsSmartAccount({ + client: publicClient, + owner: owner1, + preferredType: 'modular', + }) + + const account2 = await toTownsSmartAccount({ + client: publicClient, + owner: owner2, + preferredType: 'modular', + }) + + expect(account1.address).not.toBe(account2.address) + }) + + it('simple and modular accounts have different addresses for same owner', async () => { + const owner = privateKeyToAccount( + '0x3333333333333333333333333333333333333333333333333333333333333333' as Hex, + ) + + const simpleAccount = await toTownsSmartAccount({ + client: publicClient, + owner, + preferredType: 'simple', + }) + + const modularAccount = await toTownsSmartAccount({ + client: publicClient, + owner, + preferredType: 'modular', + }) + + expect(simpleAccount.address).not.toBe(modularAccount.address) + }) + }) +}) diff --git a/packages/smart-account/tsconfig.json b/packages/smart-account/tsconfig.json new file mode 100644 index 00000000000..f74902efbd1 --- /dev/null +++ b/packages/smart-account/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "test"] +} diff --git a/packages/smart-account/vitest.config.ts b/packages/smart-account/vitest.config.ts new file mode 100644 index 00000000000..670014a2368 --- /dev/null +++ b/packages/smart-account/vitest.config.ts @@ -0,0 +1,12 @@ +import { defineConfig, mergeConfig } from 'vitest/config' +import { rootConfig } from '../../vitest.config.mts' + +export default mergeConfig( + rootConfig, + defineConfig({ + test: { + globals: true, + testTimeout: 60_000, + }, + }), +) diff --git a/scripts/deploy-base-contracts.sh b/scripts/deploy-base-contracts.sh index 82608876af7..663e85d3049 100755 --- a/scripts/deploy-base-contracts.sh +++ b/scripts/deploy-base-contracts.sh @@ -30,6 +30,90 @@ PERMIT2_ADDRESS=0x000000000022D473030F116dDEE9F6B43aC78BA3 PERMIT2_BYTECODE=$(cast code $PERMIT2_ADDRESS --rpc-url $BASE_RPC_URL) cast rpc anvil_setCode $PERMIT2_ADDRESS $PERMIT2_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL +# Deploy ERC-4337 EntryPoint v0.7 +ENTRYPOINT_V07_ADDRESS=0x0000000071727De22E5E9d8BAf0edAc6f37da032 +ENTRYPOINT_V07_BYTECODE=$(cast code $ENTRYPOINT_V07_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $ENTRYPOINT_V07_ADDRESS $ENTRYPOINT_V07_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SenderCreator (REQUIRED - EntryPoint v0.7 helper contract for account creation) +SENDER_CREATOR_ADDRESS=0xEFC2c1444eBCC4Db75e7613d20C6a62fF67A167C +SENDER_CREATOR_BYTECODE=$(cast code $SENDER_CREATOR_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SENDER_CREATOR_ADDRESS $SENDER_CREATOR_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy EntryPointSimulations (REQUIRED - Alto bundler needs this for userOp simulation) +ENTRYPOINT_SIMULATIONS_ADDRESS=0x74Cb5e4eE81b86e70f9045036a1C5477de69eE87 +ENTRYPOINT_SIMULATIONS_BYTECODE=$(cast code $ENTRYPOINT_SIMULATIONS_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $ENTRYPOINT_SIMULATIONS_ADDRESS $ENTRYPOINT_SIMULATIONS_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy ERC-4337 EntryPoint v0.6 +ENTRYPOINT_V06_ADDRESS=0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789 +ENTRYPOINT_V06_BYTECODE=$(cast code $ENTRYPOINT_V06_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $ENTRYPOINT_V06_ADDRESS $ENTRYPOINT_V06_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SimpleAccountFactory v0.6 (for legacy account support) +SIMPLE_ACCOUNT_FACTORY_V06_ADDRESS=0x9406Cc6185a346906296840746125a0E44976454 +SIMPLE_ACCOUNT_FACTORY_V06_BYTECODE=$(cast code $SIMPLE_ACCOUNT_FACTORY_V06_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SIMPLE_ACCOUNT_FACTORY_V06_ADDRESS $SIMPLE_ACCOUNT_FACTORY_V06_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SimpleAccount implementation v0.6 +SIMPLE_ACCOUNT_IMPL_V06_ADDRESS=0x8ABB13360b87Be5EEb1B98647A016adD927a136c +SIMPLE_ACCOUNT_IMPL_V06_BYTECODE=$(cast code $SIMPLE_ACCOUNT_IMPL_V06_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SIMPLE_ACCOUNT_IMPL_V06_ADDRESS $SIMPLE_ACCOUNT_IMPL_V06_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SimpleAccountFactory v0.7 +SIMPLE_ACCOUNT_FACTORY_ADDRESS=0x91E60e0613810449d098b0b5Ec8b51A0FE8c8985 +SIMPLE_ACCOUNT_FACTORY_BYTECODE=$(cast code $SIMPLE_ACCOUNT_FACTORY_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SIMPLE_ACCOUNT_FACTORY_ADDRESS $SIMPLE_ACCOUNT_FACTORY_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy ModularAccountFactory v2.0.0 +MODULAR_ACCOUNT_FACTORY_ADDRESS=0x00000000000017c61b5bEe81050EC8eFc9c6fecd +MODULAR_ACCOUNT_FACTORY_BYTECODE=$(cast code $MODULAR_ACCOUNT_FACTORY_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $MODULAR_ACCOUNT_FACTORY_ADDRESS $MODULAR_ACCOUNT_FACTORY_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy ModularAccount v2.0.0 implementation +MODULAR_ACCOUNT_IMPL_ADDRESS=0x00000000000002377B26b1EdA7b0BC371C60DD4f +MODULAR_ACCOUNT_IMPL_BYTECODE=$(cast code $MODULAR_ACCOUNT_IMPL_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $MODULAR_ACCOUNT_IMPL_ADDRESS $MODULAR_ACCOUNT_IMPL_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SemiModularAccountBytecode v2.0.0 +SEMI_MODULAR_ACCOUNT_ADDRESS=0x000000000000c5A9089039570Dd36455b5C07383 +SEMI_MODULAR_ACCOUNT_BYTECODE=$(cast code $SEMI_MODULAR_ACCOUNT_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SEMI_MODULAR_ACCOUNT_ADDRESS $SEMI_MODULAR_ACCOUNT_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SingleSignerValidationModule v2.0.0 +SINGLE_SIGNER_VALIDATION_ADDRESS=0x00000000000099DE0BF6fA90dEB851E2A2df7d83 +SINGLE_SIGNER_VALIDATION_BYTECODE=$(cast code $SINGLE_SIGNER_VALIDATION_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SINGLE_SIGNER_VALIDATION_ADDRESS $SINGLE_SIGNER_VALIDATION_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy ExecutionInstallDelegate v2.0.0 (REQUIRED - modular accounts have immutable reference) +EXECUTION_INSTALL_DELEGATE_ADDRESS=0x0000000000008e6a39E03C7156e46b238C9E2036 +EXECUTION_INSTALL_DELEGATE_BYTECODE=$(cast code $EXECUTION_INSTALL_DELEGATE_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $EXECUTION_INSTALL_DELEGATE_ADDRESS $EXECUTION_INSTALL_DELEGATE_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Deploy SemiModularAccountStorageOnly v2.0.0 (for 7702 accounts) +SEMI_MODULAR_STORAGE_ONLY_ADDRESS=0x0000000000006E2f9d80CaEc0Da6500f005EB25A +SEMI_MODULAR_STORAGE_ONLY_BYTECODE=$(cast code $SEMI_MODULAR_STORAGE_ONLY_ADDRESS --rpc-url $BASE_RPC_URL) +cast rpc anvil_setCode $SEMI_MODULAR_STORAGE_ONLY_ADDRESS $SEMI_MODULAR_STORAGE_ONLY_BYTECODE --rpc-url $BASE_ANVIL_RPC_URL + +# Stake ModularAccountFactory in EntryPoint (REQUIRED - bundler rejects unstaked factories) +# The factory has an owner check on addStake, so we need to impersonate the owner +ANVIL_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 +FACTORY_OWNER=$(cast call $MODULAR_ACCOUNT_FACTORY_ADDRESS "owner()(address)" --rpc-url $BASE_ANVIL_RPC_URL) +echo "Factory owner: $FACTORY_OWNER" + +# Fund the owner address +cast send $FACTORY_OWNER --value 1ether --private-key $ANVIL_PRIVATE_KEY --rpc-url $BASE_ANVIL_RPC_URL + +# Impersonate the owner and stake +cast rpc anvil_impersonateAccount $FACTORY_OWNER --rpc-url $BASE_ANVIL_RPC_URL +cast send $MODULAR_ACCOUNT_FACTORY_ADDRESS \ + "addStake(uint32)" 86400 \ + --value 0.1ether \ + --from $FACTORY_OWNER \ + --unlocked \ + --rpc-url $BASE_ANVIL_RPC_URL +cast rpc anvil_stopImpersonatingAccount $FACTORY_OWNER --rpc-url $BASE_ANVIL_RPC_URL + # Space Architect make clear-anvil-deployments context=$RIVER_ENV make deploy-any-local context=$RIVER_ENV rpc=base_anvil type=utils contract=DeployProxyBatchDelegation @@ -52,3 +136,4 @@ make interact-any-local context=$RIVER_ENV rpc=base_anvil contract=InteractClaim make deploy-any-local context=$RIVER_ENV rpc=base_anvil type=utils contract=DeployMember make deploy-any-local context=$RIVER_ENV rpc=base_anvil type=utils contract=DeployMockNFT make deploy-any-local context=$RIVER_ENV rpc=base_anvil type=utils contract=DeployEntitlementGatedExample +