@dev.sail.money/sailor 1.3.0-98 → 1.4.0-244
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -7
- package/LICENSE +1 -1
- package/README.md +64 -472
- package/package.json +5 -6
- package/packages/cli/README.md +1 -1
- package/packages/cli/dist/index.cjs +1481 -463
- package/packages/cli/dist/server.cjs +16088 -17900
- package/packages/sdk/README.md +1 -1
- package/packages/sdk/dist/abis/ConfigurablePermission.d.ts +130 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.d.ts.map +1 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.js +79 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.js.map +1 -0
- package/packages/sdk/dist/abis/SailKernel.d.ts +42 -0
- package/packages/sdk/dist/abis/SailKernel.d.ts.map +1 -1
- package/packages/sdk/dist/abis/SailKernel.js +34 -0
- package/packages/sdk/dist/abis/SailKernel.js.map +1 -1
- package/packages/sdk/dist/abis/index.d.ts +1 -0
- package/packages/sdk/dist/abis/index.d.ts.map +1 -1
- package/packages/sdk/dist/abis/index.js +1 -0
- package/packages/sdk/dist/abis/index.js.map +1 -1
- package/packages/sdk/dist/chains.d.ts +9 -7
- package/packages/sdk/dist/chains.d.ts.map +1 -1
- package/packages/sdk/dist/chains.js +103 -32
- package/packages/sdk/dist/chains.js.map +1 -1
- package/packages/sdk/dist/client.d.ts +1 -1
- package/packages/sdk/dist/client.d.ts.map +1 -1
- package/packages/sdk/dist/client.js +137 -16
- package/packages/sdk/dist/client.js.map +1 -1
- package/packages/sdk/dist/deployments.d.ts +6 -4
- package/packages/sdk/dist/deployments.d.ts.map +1 -1
- package/packages/sdk/dist/deployments.js +120 -118
- package/packages/sdk/dist/deployments.js.map +1 -1
- package/packages/sdk/dist/eip712.d.ts +84 -0
- package/packages/sdk/dist/eip712.d.ts.map +1 -1
- package/packages/sdk/dist/eip712.js +148 -0
- package/packages/sdk/dist/eip712.js.map +1 -1
- package/packages/sdk/dist/fees.d.ts +2 -1
- package/packages/sdk/dist/fees.d.ts.map +1 -1
- package/packages/sdk/dist/fees.js +2 -1
- package/packages/sdk/dist/fees.js.map +1 -1
- package/packages/sdk/dist/index.d.ts +4 -3
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +4 -3
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/packages/sdk/dist/safe.d.ts +49 -0
- package/packages/sdk/dist/safe.d.ts.map +1 -1
- package/packages/sdk/dist/safe.js +74 -0
- package/packages/sdk/dist/safe.js.map +1 -1
- package/packages/sdk/dist/types.d.ts +7 -0
- package/packages/sdk/dist/types.d.ts.map +1 -1
- package/packages/sdk/package.json +6 -2
- package/packages/ui/dist/assets/{add-BX5reKtK.js → add-sHg4oAtj.js} +2 -2
- package/packages/ui/dist/assets/{all-wallets-IZ3PlVF-.js → all-wallets-BhPcqrMm.js} +2 -2
- package/packages/ui/dist/assets/{app-store-ARgRdMdF.js → app-store-B_PQMwCf.js} +1 -1
- package/packages/ui/dist/assets/{apple-VCaqsI9w.js → apple-CqAFK7Fj.js} +2 -2
- package/packages/ui/dist/assets/arrow-bottom-CbxIflTv.js +8 -0
- package/packages/ui/dist/assets/{arrow-bottom-circle-h5vFiZ2I.js → arrow-bottom-circle-BFgY35YA.js} +2 -2
- package/packages/ui/dist/assets/arrow-left-DCG2m2BY.js +8 -0
- package/packages/ui/dist/assets/arrow-right-NrPOhG6W.js +8 -0
- package/packages/ui/dist/assets/arrow-top-BHTmGsDP.js +8 -0
- package/packages/ui/dist/assets/{bank-6c28yOM9.js → bank-BqDvUazs.js} +2 -2
- package/packages/ui/dist/assets/{basic-CJnbTfSd.js → basic-CHFjQMod.js} +177 -177
- package/packages/ui/dist/assets/{browser-CDKlxM3D.js → browser-C_VdKE7p.js} +2 -2
- package/packages/ui/dist/assets/{card-DQdED02q.js → card-w-1brQoV.js} +2 -2
- package/packages/ui/dist/assets/ccip-jvDTeGaI.js +1 -0
- package/packages/ui/dist/assets/{checkmark-JoRNVoFV.js → checkmark-CLBmxdAF.js} +2 -2
- package/packages/ui/dist/assets/{checkmark-bold-B6bGHVIs.js → checkmark-bold-Ca_e1PMs.js} +2 -2
- package/packages/ui/dist/assets/chevron-bottom-BhvFRdSL.js +8 -0
- package/packages/ui/dist/assets/chevron-left-cjMaNbHC.js +8 -0
- package/packages/ui/dist/assets/chevron-right-CRuHR0b-.js +8 -0
- package/packages/ui/dist/assets/chevron-top-Bq0a2jj-.js +8 -0
- package/packages/ui/dist/assets/{chrome-store-D-fiJ9qJ.js → chrome-store-Cieq6j7x.js} +2 -2
- package/packages/ui/dist/assets/{clock-xCPkzwjj.js → clock-Dkj5WbVg.js} +2 -2
- package/packages/ui/dist/assets/{close-BkqmPpWG.js → close-C8eE6Dfz.js} +2 -2
- package/packages/ui/dist/assets/{coinPlaceholder-PIvN9oq_.js → coinPlaceholder-DndKH-8C.js} +2 -2
- package/packages/ui/dist/assets/{compass-CW5kWcxW.js → compass-DzoLByzm.js} +2 -2
- package/packages/ui/dist/assets/{copy-DUZlAQJJ.js → copy-Y7UMmVLt.js} +2 -2
- package/packages/ui/dist/assets/core-BkWdAWjX.js +907 -0
- package/packages/ui/dist/assets/cursor-BAQNxqYB.js +3 -0
- package/packages/ui/dist/assets/{cursor-transparent-BUAMB0G1.js → cursor-transparent-BUHY29Re.js} +2 -2
- package/packages/ui/dist/assets/{desktop-BxdlwV8P.js → desktop-DkZLCs5P.js} +2 -2
- package/packages/ui/dist/assets/{disconnect-GelNh3mn.js → disconnect-CphsO-wg.js} +2 -2
- package/packages/ui/dist/assets/{discord-N0jnxkzC.js → discord-CYH46bgt.js} +2 -2
- package/packages/ui/dist/assets/{etherscan-B41u7wF4.js → etherscan-2-3-Icbx.js} +2 -2
- package/packages/ui/dist/assets/events-DQ172AOg.js +1 -0
- package/packages/ui/dist/assets/{exclamation-triangle-BWJC56FC.js → exclamation-triangle-Bx9-1mpn.js} +2 -2
- package/packages/ui/dist/assets/{extension-G6I6oogw.js → extension-BuDZDNPV.js} +2 -2
- package/packages/ui/dist/assets/external-link-k6oTiNch.js +8 -0
- package/packages/ui/dist/assets/{facebook-47twy32b.js → facebook-BVB4qCju.js} +2 -2
- package/packages/ui/dist/assets/{farcaster-DYqnqCqs.js → farcaster-CxfWmDK3.js} +2 -2
- package/packages/ui/dist/assets/{filters-dF6xeJnE.js → filters-CXyIzkBz.js} +2 -2
- package/packages/ui/dist/assets/{github-DbW4Ihz2.js → github-Bga1HQTm.js} +2 -2
- package/packages/ui/dist/assets/{google-TKm7G8LF.js → google-CKLjkN5t.js} +2 -2
- package/packages/ui/dist/assets/{help-circle-CY3qTmsG.js → help-circle-CW4A601v.js} +1 -1
- package/packages/ui/dist/assets/{id-JpHW4q14.js → id-BaRFLHqy.js} +2 -2
- package/packages/ui/dist/assets/{image-Dip2fG98.js → image-4pE_c0pP.js} +2 -2
- package/packages/ui/dist/assets/index-B07bCKJ8.css +1 -0
- package/packages/ui/dist/assets/index-BKPTb_0U.js +1 -0
- package/packages/ui/dist/assets/index-BV8s6ez1.js +1 -0
- package/packages/ui/dist/assets/index-BaLMTrx4.js +47 -0
- package/packages/ui/dist/assets/index-CguqCMNp.js +16 -0
- package/packages/ui/dist/assets/index-RMrT9ktE.js +1780 -0
- package/packages/ui/dist/assets/{index-q0mGElxZ.js → index-_n5fH6AD.js} +3 -3
- package/packages/ui/dist/assets/index.es-rQvUXQTw.js +26 -0
- package/packages/ui/dist/assets/{info-B1enFsqh.js → info-UMAWEFh_.js} +2 -2
- package/packages/ui/dist/assets/{info-circle-D4j3FISs.js → info-circle-DuTp8NTC.js} +2 -2
- package/packages/ui/dist/assets/{lightbulb-DZbKr-vS.js → lightbulb-CkYYJbAa.js} +2 -2
- package/packages/ui/dist/assets/{mail-D-TO_uVQ.js → mail-CntZNMWz.js} +2 -2
- package/packages/ui/dist/assets/metamask-sdk-DIj7UxWU.js +542 -0
- package/packages/ui/dist/assets/{mobile-Bkmwzav2.js → mobile-DdyrzTfW.js} +2 -2
- package/packages/ui/dist/assets/{more-D1_I_jiB.js → more-DpZ1Bqpv.js} +2 -2
- package/packages/ui/dist/assets/{network-placeholder-DUaFjoXh.js → network-placeholder-B8yy8U56.js} +2 -2
- package/packages/ui/dist/assets/{nftPlaceholder-Cc0iUryh.js → nftPlaceholder-BXFbCJ-Z.js} +2 -2
- package/packages/ui/dist/assets/{off-BvX71sse.js → off-DavoQSqH.js} +2 -2
- package/packages/ui/dist/assets/{play-store-XzLbtbTd.js → play-store-BJeHSxBp.js} +2 -2
- package/packages/ui/dist/assets/{plus-B77_RmYR.js → plus-B-L3uTWl.js} +2 -2
- package/packages/ui/dist/assets/{qr-code-BNeIhB1d.js → qr-code-CcQBy6o3.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-B9sX-yty.js → recycle-horizontal-BLC3_x1m.js} +2 -2
- package/packages/ui/dist/assets/{refresh-BWRygnjm.js → refresh-78cbzBlS.js} +2 -2
- package/packages/ui/dist/assets/{reown-logo-DCAEsGFm.js → reown-logo-Bx5RmN6G.js} +2 -2
- package/packages/ui/dist/assets/{search-ZXIqrawS.js → search-XWB8l5E2.js} +2 -2
- package/packages/ui/dist/assets/{secp256k1-Doz05h4g.js → secp256k1-u9EmDRXd.js} +1 -1
- package/packages/ui/dist/assets/{send-BQcO0jNC.js → send-BjGwACTt.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontal-4yZEzz2K.js → swapHorizontal-DJWcWn3A.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalBold-DxBKu3sl.js → swapHorizontalBold-CG930oAl.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalMedium-DAQYJ2JK.js → swapHorizontalMedium-CHIdtnCI.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-CUlZzFJ6.js → swapHorizontalRoundedBold-B2oGt4O4.js} +2 -2
- package/packages/ui/dist/assets/{swapVertical-CjWHAaDM.js → swapVertical-CnjOFXH3.js} +2 -2
- package/packages/ui/dist/assets/{telegram-JBeabiJP.js → telegram-BtOilYdH.js} +2 -2
- package/packages/ui/dist/assets/{three-dots-D3R8OjSx.js → three-dots-D_VsAJlo.js} +2 -2
- package/packages/ui/dist/assets/{twitch-1f9z7xVO.js → twitch-BIX3n7hL.js} +2 -2
- package/packages/ui/dist/assets/{twitterIcon-BW7n2xnp.js → twitterIcon-C3DDaPem.js} +2 -2
- package/packages/ui/dist/assets/{verify-Cs5owI38.js → verify-CtzMScZy.js} +2 -2
- package/packages/ui/dist/assets/{verify-filled-Ci5sx5qS.js → verify-filled-CVjdmBEW.js} +2 -2
- package/packages/ui/dist/assets/{w3m-modal-DnWtss8u.js → w3m-modal-BZ3BUhSD.js} +1 -1
- package/packages/ui/dist/assets/{wallet-MaGNqaW-.js → wallet-hURaFgJp.js} +2 -2
- package/packages/ui/dist/assets/{wallet-placeholder-kTOy12_L.js → wallet-placeholder-BcF2KreB.js} +2 -2
- package/packages/ui/dist/assets/{walletconnect-CyuP92jg.js → walletconnect-C8XCABRo.js} +3 -3
- package/packages/ui/dist/assets/{warning-circle-BImUCdpG.js → warning-circle-BMz6LCU4.js} +2 -2
- package/packages/ui/dist/assets/{x-II45JHpV.js → x-deAHZeLU.js} +2 -2
- package/packages/ui/dist/index.html +2 -2
- package/templates/default/.agents/skills/sail-mandates/SKILL.md +1 -1
- package/templates/default/.agents/skills/sail-mandates/references/approvals.md +3 -3
- package/templates/default/.agents/skills/sail-mandates/references/examples-index.md +3 -3
- package/templates/default/.agents/skills/sail-onboarding/SKILL.md +34 -33
- package/templates/default/.agents/skills/sail-servers/SKILL.md +1 -0
- package/templates/default/.agents/skills/sail-swap-quote/SKILL.md +76 -0
- package/templates/default/.agents/skills/sail-template-approve-batch/SKILL.md +98 -0
- package/templates/default/.agents/skills/sail-template-borrow/SKILL.md +68 -0
- package/templates/default/.agents/skills/sail-template-deposit/SKILL.md +61 -0
- package/templates/default/.agents/skills/sail-template-swap/SKILL.md +207 -0
- package/templates/default/.agents/skills/sail-template-swap-no-oracle/SKILL.md +100 -0
- package/templates/default/.agents/skills/sail-template-transfer/SKILL.md +52 -0
- package/templates/default/.agents/skills/sail-template-withdraw/SKILL.md +50 -0
- package/templates/default/.agents/skills/sail-templates/SKILL.md +142 -0
- package/templates/default/.agents/skills/sail-templates/catalog.mjs +200 -0
- package/templates/default/.agents/skills/sail-templates/deployed.json +133 -0
- package/templates/default/.agents/skills/sail-templates/oracles/IOracle.sol +13 -0
- package/templates/default/.agents/skills/sail-templates/oracles/UniV3TwapOracle.sol +114 -0
- package/templates/default/.agents/skills/sail-templates/oracles/libs/FullMath.sol +62 -0
- package/templates/default/.agents/skills/sail-templates/oracles/libs/TickMath.sol +44 -0
- package/templates/default/.agents/skills/sail-templates/references/config-schemas.md +139 -0
- package/templates/default/.agents/skills/sail-templates/references/reuse-flow.md +139 -0
- package/templates/default/.agents/skills/sail-token-resolve/SKILL.md +174 -0
- package/templates/default/.env.example +9 -0
- package/templates/default/AGENTS.md +107 -13
- package/templates/default/docs/PERMISSION_MODEL.md +2 -2
- package/{examples → templates/default/examples}/custom-mandate/.sail/contracts/interfaces/IPermission.sol +4 -0
- package/{examples → templates/default/examples}/custom-mandate/README.md +4 -1
- package/{examples → templates/default/examples}/permissions/interfaces/IBatchPermission.sol +2 -0
- package/{examples → templates/default/examples}/permissions/interfaces/IPermission.sol +4 -0
- package/templates/default/scripts/quote-swap.mjs +211 -0
- package/templates/default/scripts/resolve-token.mjs +992 -0
- package/templates/default/scripts/shared-template-addr.mjs +110 -0
- package/templates/default/test/BoundedCallPermission.t.sol +2 -1
- package/docs/PERMISSION_MODEL.md +0 -93
- package/examples/README.md +0 -24
- package/examples/lifi-permissions/LifiBoundedApprovePermissionCloneable.sol +0 -84
- package/examples/lifi-permissions/LifiDiamondSwapPermissionCloneable.sol +0 -97
- package/examples/lifi-permissions/README.md +0 -53
- package/packages/ui/dist/assets/arrow-bottom-Cwptw8fW.js +0 -8
- package/packages/ui/dist/assets/arrow-left-bM1TRcV9.js +0 -8
- package/packages/ui/dist/assets/arrow-right-BYd_N4Jr.js +0 -8
- package/packages/ui/dist/assets/arrow-top-CLUnwVE2.js +0 -8
- package/packages/ui/dist/assets/ccip-BL7RIPfY.js +0 -1
- package/packages/ui/dist/assets/chevron-bottom-BMCelIEu.js +0 -8
- package/packages/ui/dist/assets/chevron-left-ryPLhHCc.js +0 -8
- package/packages/ui/dist/assets/chevron-right-CdDNRv7f.js +0 -8
- package/packages/ui/dist/assets/chevron-top-BxWIjjGk.js +0 -8
- package/packages/ui/dist/assets/core-von2c1sc.js +0 -907
- package/packages/ui/dist/assets/cursor-BzRVY7BD.js +0 -3
- package/packages/ui/dist/assets/events-C9icG2YB.js +0 -1
- package/packages/ui/dist/assets/external-link-BPaGQf4a.js +0 -8
- package/packages/ui/dist/assets/fallback-BTfJeGjh.js +0 -1
- package/packages/ui/dist/assets/index-BGJ_8fMk.js +0 -1
- package/packages/ui/dist/assets/index-Bq3PAopp.js +0 -16
- package/packages/ui/dist/assets/index-C4_cA5XW.js +0 -1
- package/packages/ui/dist/assets/index-CaDN0gL4.js +0 -1
- package/packages/ui/dist/assets/index-DLElIcBr.js +0 -1789
- package/packages/ui/dist/assets/index-lhNfD4jA.css +0 -1
- package/packages/ui/dist/assets/index.es-BaCKS_tW.js +0 -26
- package/packages/ui/dist/assets/metamask-sdk-DljW3QD1.js +0 -542
- package/packages/ui/dist/assets/native-CJ5et6AR.js +0 -1
- package/packages/ui/dist/assets/parseSignature-BAS-wKoj.js +0 -1
- package/scripts/check-docs.mjs +0 -309
- package/scripts/check-init.mjs +0 -123
- package/scripts/check-update.mjs +0 -177
- package/scripts/clean.mjs +0 -17
- package/scripts/pack.mjs +0 -21
- package/templates/default/.agents/skills/sail-overview/SKILL.md +0 -100
- package/templates/default/.agents/skills/sail-sailor/SKILL.md +0 -190
- package/templates/default/.agents/skills/sail-setup/SKILL.md +0 -38
- package/templates/default/.gitlab-ci.yml +0 -58
- /package/{examples → templates/default/examples}/custom-mandate/foundry.toml +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/BoundedCallPermission.sol +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/README.md +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/SailCalldata.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedApproveAndCallBatch.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedBorrow_AaveV3_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedLimitless_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedPerp_GMXv2_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedStake_Venice_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSupply_AaveV3_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwapNative_UniswapV3_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV3_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV4_Unichain.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedTransfer_ERC20_Ethereum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedVault_ERC4626_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/README.md +0 -0
- /package/{examples → templates/default/examples}/permissions/SailCalldata.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/foundry.toml +0 -0
|
@@ -15767,13 +15767,13 @@ var init_getCallError = __esm({
|
|
|
15767
15767
|
|
|
15768
15768
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/utils/promise/withResolvers.js
|
|
15769
15769
|
function withResolvers() {
|
|
15770
|
-
let
|
|
15770
|
+
let resolve4 = () => void 0;
|
|
15771
15771
|
let reject = () => void 0;
|
|
15772
15772
|
const promise = new Promise((resolve_, reject_) => {
|
|
15773
|
-
|
|
15773
|
+
resolve4 = resolve_;
|
|
15774
15774
|
reject = reject_;
|
|
15775
15775
|
});
|
|
15776
|
-
return { promise, resolve:
|
|
15776
|
+
return { promise, resolve: resolve4, reject };
|
|
15777
15777
|
}
|
|
15778
15778
|
var init_withResolvers = __esm({
|
|
15779
15779
|
"../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/utils/promise/withResolvers.js"() {
|
|
@@ -15792,8 +15792,8 @@ function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait2 = 0, sort
|
|
|
15792
15792
|
if (sort && Array.isArray(data))
|
|
15793
15793
|
data.sort(sort);
|
|
15794
15794
|
for (let i = 0; i < scheduler.length; i++) {
|
|
15795
|
-
const { resolve:
|
|
15796
|
-
|
|
15795
|
+
const { resolve: resolve4 } = scheduler[i];
|
|
15796
|
+
resolve4?.([data[i], data]);
|
|
15797
15797
|
}
|
|
15798
15798
|
}).catch((err) => {
|
|
15799
15799
|
for (let i = 0; i < scheduler.length; i++) {
|
|
@@ -15809,16 +15809,16 @@ function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait2 = 0, sort
|
|
|
15809
15809
|
return {
|
|
15810
15810
|
flush,
|
|
15811
15811
|
async schedule(args) {
|
|
15812
|
-
const { promise, resolve:
|
|
15812
|
+
const { promise, resolve: resolve4, reject } = withResolvers();
|
|
15813
15813
|
const split2 = shouldSplitBatch?.([...getBatchedArgs(), args]);
|
|
15814
15814
|
if (split2)
|
|
15815
15815
|
exec();
|
|
15816
15816
|
const hasActiveScheduler = getScheduler().length > 0;
|
|
15817
15817
|
if (hasActiveScheduler) {
|
|
15818
|
-
setScheduler({ args, resolve:
|
|
15818
|
+
setScheduler({ args, resolve: resolve4, reject });
|
|
15819
15819
|
return promise;
|
|
15820
15820
|
}
|
|
15821
|
-
setScheduler({ args, resolve:
|
|
15821
|
+
setScheduler({ args, resolve: resolve4, reject });
|
|
15822
15822
|
setTimeout(exec, wait2);
|
|
15823
15823
|
return promise;
|
|
15824
15824
|
}
|
|
@@ -16595,7 +16595,7 @@ var init_observe = __esm({
|
|
|
16595
16595
|
|
|
16596
16596
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/utils/wait.js
|
|
16597
16597
|
async function wait(time, { signal } = {}) {
|
|
16598
|
-
return new Promise((
|
|
16598
|
+
return new Promise((resolve4, reject) => {
|
|
16599
16599
|
if (signal?.aborted) {
|
|
16600
16600
|
reject(getAbortError(signal));
|
|
16601
16601
|
return;
|
|
@@ -16603,7 +16603,7 @@ async function wait(time, { signal } = {}) {
|
|
|
16603
16603
|
const cleanup = () => signal?.removeEventListener("abort", onAbort);
|
|
16604
16604
|
const timeout = setTimeout(() => {
|
|
16605
16605
|
cleanup();
|
|
16606
|
-
|
|
16606
|
+
resolve4();
|
|
16607
16607
|
}, time);
|
|
16608
16608
|
const onAbort = () => {
|
|
16609
16609
|
clearTimeout(timeout);
|
|
@@ -17419,7 +17419,7 @@ var init_calls = __esm({
|
|
|
17419
17419
|
|
|
17420
17420
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/utils/promise/withRetry.js
|
|
17421
17421
|
function withRetry(fn, { delay: delay_ = 100, retryCount = 2, shouldRetry: shouldRetry2 = () => true, signal } = {}) {
|
|
17422
|
-
return new Promise((
|
|
17422
|
+
return new Promise((resolve4, reject) => {
|
|
17423
17423
|
const attemptRetry = async ({ count = 0 } = {}) => {
|
|
17424
17424
|
if (signal?.aborted) {
|
|
17425
17425
|
reject(getAbortError(signal));
|
|
@@ -17439,7 +17439,7 @@ function withRetry(fn, { delay: delay_ = 100, retryCount = 2, shouldRetry: shoul
|
|
|
17439
17439
|
};
|
|
17440
17440
|
try {
|
|
17441
17441
|
const data = await fn();
|
|
17442
|
-
|
|
17442
|
+
resolve4(data);
|
|
17443
17443
|
} catch (err) {
|
|
17444
17444
|
if (signal?.aborted) {
|
|
17445
17445
|
reject(getAbortError(signal));
|
|
@@ -17586,7 +17586,7 @@ async function sendCalls(client, parameters) {
|
|
|
17586
17586
|
results.push({ reason, status: "rejected" });
|
|
17587
17587
|
}
|
|
17588
17588
|
if (experimental_fallbackDelay > 0)
|
|
17589
|
-
await new Promise((
|
|
17589
|
+
await new Promise((resolve4) => setTimeout(resolve4, experimental_fallbackDelay));
|
|
17590
17590
|
}
|
|
17591
17591
|
if (results.every((r) => r.status === "rejected"))
|
|
17592
17592
|
throw results[0].reason;
|
|
@@ -17716,9 +17716,9 @@ async function waitForCallsStatus(client, parameters) {
|
|
|
17716
17716
|
throwOnFailure = false
|
|
17717
17717
|
} = parameters;
|
|
17718
17718
|
const observerId = stringify(["waitForCallsStatus", client.uid, id]);
|
|
17719
|
-
const { promise, resolve:
|
|
17719
|
+
const { promise, resolve: resolve4, reject } = withResolvers();
|
|
17720
17720
|
let timer;
|
|
17721
|
-
const unobserve = observe(observerId, { resolve:
|
|
17721
|
+
const unobserve = observe(observerId, { resolve: resolve4, reject }, (emit2) => {
|
|
17722
17722
|
const unpoll = poll(async () => {
|
|
17723
17723
|
const done = (fn) => {
|
|
17724
17724
|
clearTimeout(timer);
|
|
@@ -18123,13 +18123,13 @@ async function isImageUri(uri) {
|
|
|
18123
18123
|
}
|
|
18124
18124
|
if (!Object.hasOwn(globalThis, "Image"))
|
|
18125
18125
|
return false;
|
|
18126
|
-
return new Promise((
|
|
18126
|
+
return new Promise((resolve4) => {
|
|
18127
18127
|
const img = new Image();
|
|
18128
18128
|
img.onload = () => {
|
|
18129
|
-
|
|
18129
|
+
resolve4(true);
|
|
18130
18130
|
};
|
|
18131
18131
|
img.onerror = () => {
|
|
18132
|
-
|
|
18132
|
+
resolve4(false);
|
|
18133
18133
|
};
|
|
18134
18134
|
img.src = uri;
|
|
18135
18135
|
});
|
|
@@ -20077,7 +20077,7 @@ var init_nonceManager = __esm({
|
|
|
20077
20077
|
|
|
20078
20078
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/utils/promise/withTimeout.js
|
|
20079
20079
|
function withTimeout(fn, { errorInstance = new Error("timed out"), timeout, signal }) {
|
|
20080
|
-
return new Promise((
|
|
20080
|
+
return new Promise((resolve4, reject) => {
|
|
20081
20081
|
;
|
|
20082
20082
|
(async () => {
|
|
20083
20083
|
let timeoutId;
|
|
@@ -20092,7 +20092,7 @@ function withTimeout(fn, { errorInstance = new Error("timed out"), timeout, sign
|
|
|
20092
20092
|
}
|
|
20093
20093
|
}, timeout);
|
|
20094
20094
|
}
|
|
20095
|
-
|
|
20095
|
+
resolve4(await fn({ signal: controller?.signal || null }));
|
|
20096
20096
|
} catch (err) {
|
|
20097
20097
|
if (controller?.signal.aborted && isAbortError(err)) {
|
|
20098
20098
|
reject(errorInstance);
|
|
@@ -24137,10 +24137,10 @@ async function getWebSocketRpcClient(url, options = {}) {
|
|
|
24137
24137
|
socket.addEventListener("error", onError);
|
|
24138
24138
|
socket.addEventListener("open", onOpen);
|
|
24139
24139
|
if (socket.readyState === WebSocket5.CONNECTING) {
|
|
24140
|
-
await new Promise((
|
|
24140
|
+
await new Promise((resolve4, reject) => {
|
|
24141
24141
|
if (!socket)
|
|
24142
24142
|
return;
|
|
24143
|
-
socket.onopen =
|
|
24143
|
+
socket.onopen = resolve4;
|
|
24144
24144
|
socket.onerror = reject;
|
|
24145
24145
|
});
|
|
24146
24146
|
}
|
|
@@ -28321,13 +28321,13 @@ async function waitForTransactionReceipt(client, parameters) {
|
|
|
28321
28321
|
let retrying = false;
|
|
28322
28322
|
let _unobserve;
|
|
28323
28323
|
let _unwatch;
|
|
28324
|
-
const { promise, resolve:
|
|
28324
|
+
const { promise, resolve: resolve4, reject } = withResolvers();
|
|
28325
28325
|
const timer = timeout ? setTimeout(() => {
|
|
28326
28326
|
_unwatch?.();
|
|
28327
28327
|
_unobserve?.();
|
|
28328
28328
|
reject(new WaitForTransactionReceiptTimeoutError({ hash: hash3 }));
|
|
28329
28329
|
}, timeout) : void 0;
|
|
28330
|
-
_unobserve = observe(observerId, { onReplaced, resolve:
|
|
28330
|
+
_unobserve = observe(observerId, { onReplaced, resolve: resolve4, reject }, async (emit2) => {
|
|
28331
28331
|
receipt = await getAction(client, getTransactionReceipt, "getTransactionReceipt")({ hash: hash3 }).catch(() => void 0);
|
|
28332
28332
|
if (receipt && confirmations <= 1) {
|
|
28333
28333
|
clearTimeout(timer);
|
|
@@ -30586,7 +30586,7 @@ function webSocket(url, config = {}) {
|
|
|
30586
30586
|
},
|
|
30587
30587
|
async subscribe({ params, onData, onError }) {
|
|
30588
30588
|
const rpcClient = await getWebSocketRpcClient(url_, wsRpcClientOpts);
|
|
30589
|
-
const { result: subscriptionId } = await new Promise((
|
|
30589
|
+
const { result: subscriptionId } = await new Promise((resolve4, reject) => rpcClient.request({
|
|
30590
30590
|
body: {
|
|
30591
30591
|
method: "eth_subscribe",
|
|
30592
30592
|
params
|
|
@@ -30603,7 +30603,7 @@ function webSocket(url, config = {}) {
|
|
|
30603
30603
|
return;
|
|
30604
30604
|
}
|
|
30605
30605
|
if (typeof response.id === "number") {
|
|
30606
|
-
|
|
30606
|
+
resolve4(response);
|
|
30607
30607
|
return;
|
|
30608
30608
|
}
|
|
30609
30609
|
if (response.method !== "eth_subscription")
|
|
@@ -30614,12 +30614,12 @@ function webSocket(url, config = {}) {
|
|
|
30614
30614
|
return {
|
|
30615
30615
|
subscriptionId,
|
|
30616
30616
|
async unsubscribe() {
|
|
30617
|
-
return new Promise((
|
|
30617
|
+
return new Promise((resolve4) => rpcClient.request({
|
|
30618
30618
|
body: {
|
|
30619
30619
|
method: "eth_unsubscribe",
|
|
30620
30620
|
params: [subscriptionId]
|
|
30621
30621
|
},
|
|
30622
|
-
onResponse:
|
|
30622
|
+
onResponse: resolve4
|
|
30623
30623
|
}));
|
|
30624
30624
|
}
|
|
30625
30625
|
};
|
|
@@ -35190,8 +35190,8 @@ var require_websocket_server2 = __commonJS({
|
|
|
35190
35190
|
});
|
|
35191
35191
|
|
|
35192
35192
|
// src/index.ts
|
|
35193
|
-
var
|
|
35194
|
-
var
|
|
35193
|
+
var import_node_fs22 = require("node:fs");
|
|
35194
|
+
var import_node_path18 = require("node:path");
|
|
35195
35195
|
|
|
35196
35196
|
// ../../node_modules/.pnpm/commander@12.1.0/node_modules/commander/esm.mjs
|
|
35197
35197
|
var import_index = __toESM(require_commander(), 1);
|
|
@@ -35211,16 +35211,19 @@ var {
|
|
|
35211
35211
|
} = import_index.default;
|
|
35212
35212
|
|
|
35213
35213
|
// ../sdk/dist/chains.js
|
|
35214
|
+
var CREATE2_KERNEL = "0x38b508756c976e876EFF05a29E731A4d348BA6ED";
|
|
35215
|
+
var CREATE2_MANDATE_FACTORY = "0x6d2C802ffa0d9A8Ed69A5Bf22c1b63ccB566B8Fc";
|
|
35216
|
+
var CREATE2_GOVERNANCE = "0x4315B37cA4A315A7042af1Fcb37F8436f4D24356";
|
|
35214
35217
|
var chains = {
|
|
35215
35218
|
// Ethereum mainnet
|
|
35216
35219
|
1: {
|
|
35217
35220
|
chainId: 1,
|
|
35218
35221
|
name: "Ethereum",
|
|
35219
35222
|
rpcEnvVar: "ETH_MAINNET_RPC_URL",
|
|
35220
|
-
|
|
35221
|
-
kernel:
|
|
35222
|
-
mandateFactory:
|
|
35223
|
-
governance:
|
|
35223
|
+
defaultRpcUrl: "https://eth.llamarpc.com",
|
|
35224
|
+
kernel: CREATE2_KERNEL,
|
|
35225
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35226
|
+
governance: CREATE2_GOVERNANCE,
|
|
35224
35227
|
dispatchModel: "selective",
|
|
35225
35228
|
protocols: {}
|
|
35226
35229
|
},
|
|
@@ -35229,11 +35232,10 @@ var chains = {
|
|
|
35229
35232
|
chainId: 8453,
|
|
35230
35233
|
name: "Base",
|
|
35231
35234
|
rpcEnvVar: "BASE_RPC_URL",
|
|
35232
|
-
|
|
35233
|
-
|
|
35234
|
-
|
|
35235
|
-
|
|
35236
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35235
|
+
defaultRpcUrl: "https://mainnet.base.org",
|
|
35236
|
+
kernel: CREATE2_KERNEL,
|
|
35237
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35238
|
+
governance: CREATE2_GOVERNANCE,
|
|
35237
35239
|
dispatchModel: "selective",
|
|
35238
35240
|
protocols: {}
|
|
35239
35241
|
},
|
|
@@ -35242,11 +35244,22 @@ var chains = {
|
|
|
35242
35244
|
chainId: 42161,
|
|
35243
35245
|
name: "Arbitrum",
|
|
35244
35246
|
rpcEnvVar: "ARBITRUM_RPC_URL",
|
|
35245
|
-
|
|
35246
|
-
|
|
35247
|
-
|
|
35248
|
-
|
|
35249
|
-
|
|
35247
|
+
defaultRpcUrl: "https://arb1.arbitrum.io/rpc",
|
|
35248
|
+
kernel: CREATE2_KERNEL,
|
|
35249
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35250
|
+
governance: CREATE2_GOVERNANCE,
|
|
35251
|
+
dispatchModel: "selective",
|
|
35252
|
+
protocols: {}
|
|
35253
|
+
},
|
|
35254
|
+
// Optimism mainnet
|
|
35255
|
+
10: {
|
|
35256
|
+
chainId: 10,
|
|
35257
|
+
name: "Optimism",
|
|
35258
|
+
rpcEnvVar: "OPTIMISM_RPC_URL",
|
|
35259
|
+
defaultRpcUrl: "https://mainnet.optimism.io",
|
|
35260
|
+
kernel: CREATE2_KERNEL,
|
|
35261
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35262
|
+
governance: CREATE2_GOVERNANCE,
|
|
35250
35263
|
dispatchModel: "selective",
|
|
35251
35264
|
protocols: {}
|
|
35252
35265
|
},
|
|
@@ -35255,11 +35268,58 @@ var chains = {
|
|
|
35255
35268
|
chainId: 130,
|
|
35256
35269
|
name: "Unichain",
|
|
35257
35270
|
rpcEnvVar: "UNICHAIN_RPC_URL",
|
|
35258
|
-
|
|
35259
|
-
|
|
35260
|
-
|
|
35261
|
-
|
|
35262
|
-
|
|
35271
|
+
defaultRpcUrl: "https://mainnet.unichain.org",
|
|
35272
|
+
kernel: CREATE2_KERNEL,
|
|
35273
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35274
|
+
governance: CREATE2_GOVERNANCE,
|
|
35275
|
+
dispatchModel: "selective",
|
|
35276
|
+
protocols: {}
|
|
35277
|
+
},
|
|
35278
|
+
// BSC mainnet
|
|
35279
|
+
56: {
|
|
35280
|
+
chainId: 56,
|
|
35281
|
+
name: "BSC",
|
|
35282
|
+
rpcEnvVar: "BSC_RPC_URL",
|
|
35283
|
+
defaultRpcUrl: "https://bsc-dataseed.binance.org",
|
|
35284
|
+
kernel: CREATE2_KERNEL,
|
|
35285
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35286
|
+
governance: CREATE2_GOVERNANCE,
|
|
35287
|
+
dispatchModel: "selective",
|
|
35288
|
+
protocols: {}
|
|
35289
|
+
},
|
|
35290
|
+
// World Chain mainnet
|
|
35291
|
+
480: {
|
|
35292
|
+
chainId: 480,
|
|
35293
|
+
name: "World Chain",
|
|
35294
|
+
rpcEnvVar: "WORLD_RPC_URL",
|
|
35295
|
+
defaultRpcUrl: "https://worldchain-mainnet.g.alchemy.com/public",
|
|
35296
|
+
kernel: CREATE2_KERNEL,
|
|
35297
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35298
|
+
governance: CREATE2_GOVERNANCE,
|
|
35299
|
+
dispatchModel: "selective",
|
|
35300
|
+
protocols: {}
|
|
35301
|
+
},
|
|
35302
|
+
// HyperEVM mainnet
|
|
35303
|
+
999: {
|
|
35304
|
+
chainId: 999,
|
|
35305
|
+
name: "HyperEVM",
|
|
35306
|
+
rpcEnvVar: "HYPEREVM_RPC_URL",
|
|
35307
|
+
defaultRpcUrl: "https://rpc.hyperliquid.xyz/evm",
|
|
35308
|
+
kernel: CREATE2_KERNEL,
|
|
35309
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35310
|
+
governance: CREATE2_GOVERNANCE,
|
|
35311
|
+
dispatchModel: "selective",
|
|
35312
|
+
protocols: {}
|
|
35313
|
+
},
|
|
35314
|
+
// MegaETH mainnet
|
|
35315
|
+
4326: {
|
|
35316
|
+
chainId: 4326,
|
|
35317
|
+
name: "MegaETH",
|
|
35318
|
+
rpcEnvVar: "MEGAETH_RPC_URL",
|
|
35319
|
+
defaultRpcUrl: "https://mainnet.megaeth.com/rpc",
|
|
35320
|
+
kernel: CREATE2_KERNEL,
|
|
35321
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35322
|
+
governance: CREATE2_GOVERNANCE,
|
|
35263
35323
|
dispatchModel: "selective",
|
|
35264
35324
|
protocols: {}
|
|
35265
35325
|
},
|
|
@@ -35268,11 +35328,10 @@ var chains = {
|
|
|
35268
35328
|
chainId: 84532,
|
|
35269
35329
|
name: "Base Sepolia",
|
|
35270
35330
|
rpcEnvVar: "BASE_SEPOLIA_RPC_URL",
|
|
35271
|
-
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
|
|
35275
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35331
|
+
defaultRpcUrl: "https://sepolia.base.org",
|
|
35332
|
+
kernel: CREATE2_KERNEL,
|
|
35333
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35334
|
+
governance: CREATE2_GOVERNANCE,
|
|
35276
35335
|
dispatchModel: "selective",
|
|
35277
35336
|
protocols: {}
|
|
35278
35337
|
},
|
|
@@ -35281,10 +35340,10 @@ var chains = {
|
|
|
35281
35340
|
chainId: 11155111,
|
|
35282
35341
|
name: "Eth Sepolia",
|
|
35283
35342
|
rpcEnvVar: "SEPOLIA_RPC_URL",
|
|
35284
|
-
|
|
35285
|
-
kernel:
|
|
35286
|
-
mandateFactory:
|
|
35287
|
-
governance:
|
|
35343
|
+
defaultRpcUrl: "https://ethereum-sepolia-rpc.publicnode.com",
|
|
35344
|
+
kernel: CREATE2_KERNEL,
|
|
35345
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35346
|
+
governance: CREATE2_GOVERNANCE,
|
|
35288
35347
|
dispatchModel: "selective",
|
|
35289
35348
|
protocols: {}
|
|
35290
35349
|
}
|
|
@@ -35292,10 +35351,11 @@ var chains = {
|
|
|
35292
35351
|
function getChain(chainId) {
|
|
35293
35352
|
const config = chains[chainId];
|
|
35294
35353
|
if (!config) {
|
|
35295
|
-
throw new Error(`Chain ${chainId} is not supported. Supported chains: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 130 (Unichain), 84532 (Base Sepolia), 11155111 (Eth Sepolia).`);
|
|
35354
|
+
throw new Error(`Chain ${chainId} is not supported. Supported chains: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 10 (Optimism), 130 (Unichain), 56 (BSC), 480 (World Chain), 999 (HyperEVM), 4326 (MegaETH), 84532 (Base Sepolia), 11155111 (Eth Sepolia).`);
|
|
35296
35355
|
}
|
|
35297
35356
|
return config;
|
|
35298
35357
|
}
|
|
35358
|
+
var defaultRpcUrls = Object.fromEntries(Object.values(chains).map((c) => [c.chainId, c.defaultRpcUrl]));
|
|
35299
35359
|
|
|
35300
35360
|
// ../sdk/dist/client.js
|
|
35301
35361
|
init_esm2();
|
|
@@ -35319,6 +35379,10 @@ var SailKernelAbi = [
|
|
|
35319
35379
|
],
|
|
35320
35380
|
outputs: [{ name: "account", type: "address" }]
|
|
35321
35381
|
},
|
|
35382
|
+
// Post-#53: two-step registration. Requires msg.sender == the Safe (trusted-proxy
|
|
35383
|
+
// codehash + trusted-singleton pin) and a Safe owner signature over the
|
|
35384
|
+
// RegisterAccount EIP-712 digest (verified via checkSignatures). Must be submitted
|
|
35385
|
+
// through the Safe's execTransaction, not the owner EOA. See buildRegisterAccountTypedData.
|
|
35322
35386
|
{
|
|
35323
35387
|
type: "function",
|
|
35324
35388
|
name: "registerAccount",
|
|
@@ -35326,7 +35390,10 @@ var SailKernelAbi = [
|
|
|
35326
35390
|
inputs: [
|
|
35327
35391
|
{ name: "permissionSigner", type: "address" },
|
|
35328
35392
|
{ name: "manager", type: "address" },
|
|
35329
|
-
{ name: "feePolicy", type: "address" }
|
|
35393
|
+
{ name: "feePolicy", type: "address" },
|
|
35394
|
+
{ name: "feeAsset", type: "address" },
|
|
35395
|
+
{ name: "deadline", type: "uint256" },
|
|
35396
|
+
{ name: "ownerSig", type: "bytes" }
|
|
35330
35397
|
],
|
|
35331
35398
|
outputs: []
|
|
35332
35399
|
},
|
|
@@ -35377,6 +35444,32 @@ var SailKernelAbi = [
|
|
|
35377
35444
|
],
|
|
35378
35445
|
outputs: []
|
|
35379
35446
|
},
|
|
35447
|
+
// ── Session kill switch ───────────────────────────────────────────────────
|
|
35448
|
+
// Suspend/resume manager dispatch rights. Both are permissionSigner-signed
|
|
35449
|
+
// (RevokeSession/ActivateSession EIP-712, nonce = signerNonces[account]) and
|
|
35450
|
+
// rotate the manager/batch nonce epochs so any pre-signed dispatch is invalidated.
|
|
35451
|
+
{
|
|
35452
|
+
type: "function",
|
|
35453
|
+
name: "revokeSession",
|
|
35454
|
+
stateMutability: "nonpayable",
|
|
35455
|
+
inputs: [
|
|
35456
|
+
{ name: "account", type: "address" },
|
|
35457
|
+
{ name: "deadline", type: "uint256" },
|
|
35458
|
+
{ name: "sig", type: "bytes" }
|
|
35459
|
+
],
|
|
35460
|
+
outputs: []
|
|
35461
|
+
},
|
|
35462
|
+
{
|
|
35463
|
+
type: "function",
|
|
35464
|
+
name: "activateSession",
|
|
35465
|
+
stateMutability: "nonpayable",
|
|
35466
|
+
inputs: [
|
|
35467
|
+
{ name: "account", type: "address" },
|
|
35468
|
+
{ name: "deadline", type: "uint256" },
|
|
35469
|
+
{ name: "sig", type: "bytes" }
|
|
35470
|
+
],
|
|
35471
|
+
outputs: []
|
|
35472
|
+
},
|
|
35380
35473
|
// ── Manager dispatch ──────────────────────────────────────────────────────
|
|
35381
35474
|
{
|
|
35382
35475
|
type: "function",
|
|
@@ -35516,6 +35609,7 @@ var SailKernelAbi = [
|
|
|
35516
35609
|
{ name: "permissionSigner", type: "address" },
|
|
35517
35610
|
{ name: "manager", type: "address" },
|
|
35518
35611
|
{ name: "feePolicy", type: "address" },
|
|
35612
|
+
{ name: "feeAsset", type: "address" },
|
|
35519
35613
|
{ name: "sessionActive", type: "bool" }
|
|
35520
35614
|
]
|
|
35521
35615
|
},
|
|
@@ -35709,148 +35803,142 @@ async function detectKernelCapabilities(publicClient, kernel, opts) {
|
|
|
35709
35803
|
}
|
|
35710
35804
|
|
|
35711
35805
|
// ../sdk/dist/deployments.js
|
|
35712
|
-
var
|
|
35713
|
-
var
|
|
35714
|
-
var CREATE2_TIMELOCK = "
|
|
35806
|
+
var CREATE2_KERNEL2 = "0x38b508756c976e876EFF05a29E731A4d348BA6ED";
|
|
35807
|
+
var CREATE2_GOVERNANCE2 = "0x4315B37cA4A315A7042af1Fcb37F8436f4D24356";
|
|
35808
|
+
var CREATE2_TIMELOCK = "0xC1E5F9A581D4100Aa949f80204540a33aD97A7b6";
|
|
35715
35809
|
var CREATE2_SAFE_MODULE_ENABLER = "0x7897Cb53a4be4a2eaAf46D60573C4Fd83b33fE1F";
|
|
35716
|
-
var
|
|
35717
|
-
var CREATE2_STANDARD_FEE_POLICY = "
|
|
35718
|
-
var
|
|
35810
|
+
var CREATE2_MANDATE_FACTORY2 = "0x6d2C802ffa0d9A8Ed69A5Bf22c1b63ccB566B8Fc";
|
|
35811
|
+
var CREATE2_STANDARD_FEE_POLICY = "0x1087312447C8a2BfA15EB9cE23590E3502DBA04b";
|
|
35812
|
+
var CREATE2_DEPLOYER = "0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6";
|
|
35813
|
+
var CREATE2_TREASURY = "0x7b37F85575F1568a37dBA342BC5FE6d393F0872f";
|
|
35814
|
+
var CREATE2_MAX_PERMISSION_FEE_WEI = 10000000000000000n;
|
|
35815
|
+
var CREATE2_TEMPLATES = {
|
|
35816
|
+
swap: "0x35cEEa0db96997Cc3CF3beB42FFa36A499342F7C",
|
|
35817
|
+
swapNoOracle: "0x34Ba96CbEd1f46c88A5265E645DC5fe41662b519",
|
|
35818
|
+
borrow: "0x3e2666051599223cEAb10De55C89A0842857d8AF",
|
|
35819
|
+
deposit: "0xBfB5e13a97b12Ee89d2F2b9B65eCf7e0E371911f",
|
|
35820
|
+
withdraw: "0xF5eF5dda450a130e3020d54f565E830e4a7531f8",
|
|
35821
|
+
transfer: "0xda909a1CC584fb7559Ce4A828b008B473Da095e1",
|
|
35822
|
+
approveAndCallBatch: "0x0535A4D51333484ef583103DAB1a9449756ab732"
|
|
35823
|
+
};
|
|
35824
|
+
var CREATE2_KNOWN_TEMPLATES = [
|
|
35825
|
+
{ kind: "SwapPermission", address: CREATE2_TEMPLATES.swap, label: "Swap" },
|
|
35826
|
+
{
|
|
35827
|
+
kind: "SwapPermissionNoOracle",
|
|
35828
|
+
address: CREATE2_TEMPLATES.swapNoOracle,
|
|
35829
|
+
label: "Swap (no oracle)"
|
|
35830
|
+
},
|
|
35831
|
+
{ kind: "BorrowPermission", address: CREATE2_TEMPLATES.borrow, label: "Borrow" },
|
|
35832
|
+
{ kind: "DepositPermission", address: CREATE2_TEMPLATES.deposit, label: "Deposit" },
|
|
35833
|
+
{ kind: "WithdrawPermission", address: CREATE2_TEMPLATES.withdraw, label: "Withdraw" },
|
|
35834
|
+
{ kind: "TransferPermission", address: CREATE2_TEMPLATES.transfer, label: "Transfer" },
|
|
35835
|
+
{
|
|
35836
|
+
kind: "ApproveAndCallBatchPermission",
|
|
35837
|
+
address: CREATE2_TEMPLATES.approveAndCallBatch,
|
|
35838
|
+
label: "Approve + call batch"
|
|
35839
|
+
}
|
|
35840
|
+
];
|
|
35841
|
+
var COMMON_DEPLOYMENT_FIELDS = {
|
|
35842
|
+
deployer: CREATE2_DEPLOYER,
|
|
35843
|
+
governance: CREATE2_GOVERNANCE2,
|
|
35844
|
+
timelock: CREATE2_TIMELOCK,
|
|
35845
|
+
kernel: CREATE2_KERNEL2,
|
|
35846
|
+
mandateFactory: CREATE2_MANDATE_FACTORY2,
|
|
35847
|
+
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35848
|
+
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35849
|
+
treasury: CREATE2_TREASURY,
|
|
35850
|
+
maxPermissionFeeWei: CREATE2_MAX_PERMISSION_FEE_WEI,
|
|
35851
|
+
initialBaseFee: 0n,
|
|
35852
|
+
initialComplexityRate: 0n,
|
|
35853
|
+
dispatchModel: "selective",
|
|
35854
|
+
// The seven launch templates are SHARED multi-tenant ConfigurablePermission instances
|
|
35855
|
+
// (registered by address, configured via configure()), NOT EIP-1167 clone logic. They
|
|
35856
|
+
// belong in knownTemplates only. standaloneTemplates is the clone-implementation registry
|
|
35857
|
+
// (the `impl` arg to MandateFactory.deployAndAttach) — empty until standalone clones deploy.
|
|
35858
|
+
// Populating it with shared templates mislabels them as unaudited community clones in
|
|
35859
|
+
// `sailor mandate templates` and makes capabilities advertise them as deployAndAttach-able.
|
|
35860
|
+
standaloneTemplates: {}
|
|
35861
|
+
};
|
|
35862
|
+
function knownTemplatesFor(chainId) {
|
|
35863
|
+
return CREATE2_KNOWN_TEMPLATES.map((t) => ({ ...t, chainId }));
|
|
35864
|
+
}
|
|
35719
35865
|
var sailDeployments = {
|
|
35720
35866
|
// ── Ethereum mainnet ─────────────────────────────────────────────────────────
|
|
35721
35867
|
1: {
|
|
35722
|
-
|
|
35723
|
-
// allowlistBootstrapped=true (genesis bootstrap), zero fees, 48h timelock.
|
|
35868
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35724
35869
|
chainId: 1,
|
|
35725
|
-
blockNumber:
|
|
35726
|
-
|
|
35727
|
-
governance: CREATE2_GOVERNANCE,
|
|
35728
|
-
timelock: CREATE2_TIMELOCK,
|
|
35729
|
-
kernel: CREATE2_KERNEL,
|
|
35730
|
-
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35731
|
-
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35732
|
-
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35733
|
-
treasury: CREATE2_TREASURY,
|
|
35734
|
-
maxPermissionFeeWei: 1000000000000000n,
|
|
35735
|
-
initialBaseFee: 0n,
|
|
35736
|
-
initialComplexityRate: 0n,
|
|
35737
|
-
dispatchModel: "selective",
|
|
35738
|
-
knownTemplates: [],
|
|
35739
|
-
standaloneTemplates: {}
|
|
35870
|
+
blockNumber: 25432741,
|
|
35871
|
+
knownTemplates: knownTemplatesFor(1)
|
|
35740
35872
|
},
|
|
35741
35873
|
// ── Base mainnet ─────────────────────────────────────────────────────────────
|
|
35742
35874
|
8453: {
|
|
35743
|
-
|
|
35744
|
-
// 0x6319d3dfDDe3804ba93D65752b00c52bFb05a1ab (SAIL-405 redeploy).
|
|
35745
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35875
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35746
35876
|
chainId: 8453,
|
|
35747
|
-
blockNumber:
|
|
35748
|
-
|
|
35749
|
-
governance: CREATE2_GOVERNANCE,
|
|
35750
|
-
timelock: CREATE2_TIMELOCK,
|
|
35751
|
-
kernel: CREATE2_KERNEL,
|
|
35752
|
-
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35753
|
-
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35754
|
-
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35755
|
-
treasury: CREATE2_TREASURY,
|
|
35756
|
-
maxPermissionFeeWei: 1000000000000000n,
|
|
35757
|
-
initialBaseFee: 0n,
|
|
35758
|
-
initialComplexityRate: 0n,
|
|
35759
|
-
dispatchModel: "selective",
|
|
35760
|
-
knownTemplates: [],
|
|
35761
|
-
standaloneTemplates: {}
|
|
35877
|
+
blockNumber: 48029413,
|
|
35878
|
+
knownTemplates: knownTemplatesFor(8453)
|
|
35762
35879
|
},
|
|
35763
35880
|
// ── Arbitrum mainnet ─────────────────────────────────────────────────────────
|
|
35764
35881
|
42161: {
|
|
35765
|
-
|
|
35766
|
-
// 0x2716B12832DED0EF5688519c5Fe069EFc0374E02 (SAIL-405 redeploy).
|
|
35767
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35882
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35768
35883
|
chainId: 42161,
|
|
35769
|
-
blockNumber:
|
|
35770
|
-
|
|
35771
|
-
|
|
35772
|
-
|
|
35773
|
-
|
|
35774
|
-
|
|
35775
|
-
|
|
35776
|
-
|
|
35777
|
-
|
|
35778
|
-
maxPermissionFeeWei: 1000000000000000n,
|
|
35779
|
-
initialBaseFee: 0n,
|
|
35780
|
-
initialComplexityRate: 0n,
|
|
35781
|
-
dispatchModel: "selective",
|
|
35782
|
-
knownTemplates: [],
|
|
35783
|
-
standaloneTemplates: {}
|
|
35884
|
+
blockNumber: 25432669,
|
|
35885
|
+
knownTemplates: knownTemplatesFor(42161)
|
|
35886
|
+
},
|
|
35887
|
+
// ── Optimism mainnet ─────────────────────────────────────────────────────────
|
|
35888
|
+
10: {
|
|
35889
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35890
|
+
chainId: 10,
|
|
35891
|
+
blockNumber: 153625159,
|
|
35892
|
+
knownTemplates: knownTemplatesFor(10)
|
|
35784
35893
|
},
|
|
35785
35894
|
// ── Unichain mainnet ─────────────────────────────────────────────────────────
|
|
35786
35895
|
130: {
|
|
35787
|
-
|
|
35788
|
-
// 0xD985029960a9B7C2E7E38e102C448b8b8539B156 (SAIL-406 deploy).
|
|
35789
|
-
// NOTE: knownTemplates and standaloneTemplates from SAIL-406 were deployed
|
|
35790
|
-
// against the old kernel 0xD985029... and are now invalid. They must be
|
|
35791
|
-
// redeployed against the new kernel 0x02ABC1... and re-populated here.
|
|
35896
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35792
35897
|
chainId: 130,
|
|
35793
|
-
blockNumber:
|
|
35794
|
-
|
|
35795
|
-
|
|
35796
|
-
|
|
35797
|
-
|
|
35798
|
-
|
|
35799
|
-
|
|
35800
|
-
|
|
35801
|
-
|
|
35802
|
-
|
|
35803
|
-
|
|
35804
|
-
|
|
35805
|
-
|
|
35806
|
-
|
|
35807
|
-
|
|
35808
|
-
|
|
35809
|
-
|
|
35810
|
-
|
|
35898
|
+
blockNumber: 52100873,
|
|
35899
|
+
knownTemplates: knownTemplatesFor(130)
|
|
35900
|
+
},
|
|
35901
|
+
// ── BSC mainnet ──────────────────────────────────────────────────────────────
|
|
35902
|
+
56: {
|
|
35903
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35904
|
+
chainId: 56,
|
|
35905
|
+
blockNumber: 107312662,
|
|
35906
|
+
knownTemplates: knownTemplatesFor(56)
|
|
35907
|
+
},
|
|
35908
|
+
// ── World Chain mainnet ──────────────────────────────────────────────────────
|
|
35909
|
+
480: {
|
|
35910
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35911
|
+
chainId: 480,
|
|
35912
|
+
blockNumber: 31756901,
|
|
35913
|
+
knownTemplates: knownTemplatesFor(480)
|
|
35914
|
+
},
|
|
35915
|
+
// ── HyperEVM mainnet ─────────────────────────────────────────────────────────
|
|
35916
|
+
999: {
|
|
35917
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35918
|
+
chainId: 999,
|
|
35919
|
+
blockNumber: 39238629,
|
|
35920
|
+
knownTemplates: knownTemplatesFor(999)
|
|
35921
|
+
},
|
|
35922
|
+
// ── MegaETH mainnet ──────────────────────────────────────────────────────────
|
|
35923
|
+
4326: {
|
|
35924
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35925
|
+
chainId: 4326,
|
|
35926
|
+
blockNumber: 20056530,
|
|
35927
|
+
knownTemplates: knownTemplatesFor(4326)
|
|
35811
35928
|
},
|
|
35812
35929
|
// ── Base Sepolia (testnet) ───────────────────────────────────────────────────
|
|
35813
35930
|
84532: {
|
|
35814
|
-
|
|
35815
|
-
// 0xf1D0F4C9893612627409948BAa9d82a01a373799 (SAIL-405 redeploy).
|
|
35816
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35931
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35817
35932
|
chainId: 84532,
|
|
35818
|
-
blockNumber:
|
|
35819
|
-
|
|
35820
|
-
governance: CREATE2_GOVERNANCE,
|
|
35821
|
-
timelock: CREATE2_TIMELOCK,
|
|
35822
|
-
kernel: CREATE2_KERNEL,
|
|
35823
|
-
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35824
|
-
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35825
|
-
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35826
|
-
treasury: CREATE2_TREASURY,
|
|
35827
|
-
maxPermissionFeeWei: 1000000000000000n,
|
|
35828
|
-
initialBaseFee: 0n,
|
|
35829
|
-
initialComplexityRate: 0n,
|
|
35830
|
-
dispatchModel: "selective",
|
|
35831
|
-
knownTemplates: [],
|
|
35832
|
-
standaloneTemplates: {}
|
|
35933
|
+
blockNumber: 43539604,
|
|
35934
|
+
knownTemplates: knownTemplatesFor(84532)
|
|
35833
35935
|
},
|
|
35834
35936
|
// ── Eth Sepolia (testnet) ────────────────────────────────────────────────────
|
|
35835
35937
|
11155111: {
|
|
35836
|
-
|
|
35837
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35938
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35838
35939
|
chainId: 11155111,
|
|
35839
|
-
blockNumber:
|
|
35840
|
-
|
|
35841
|
-
governance: CREATE2_GOVERNANCE,
|
|
35842
|
-
timelock: CREATE2_TIMELOCK,
|
|
35843
|
-
kernel: CREATE2_KERNEL,
|
|
35844
|
-
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35845
|
-
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35846
|
-
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35847
|
-
treasury: CREATE2_TREASURY,
|
|
35848
|
-
maxPermissionFeeWei: 1000000000000000n,
|
|
35849
|
-
initialBaseFee: 0n,
|
|
35850
|
-
initialComplexityRate: 0n,
|
|
35851
|
-
dispatchModel: "selective",
|
|
35852
|
-
knownTemplates: [],
|
|
35853
|
-
standaloneTemplates: {}
|
|
35940
|
+
blockNumber: 11174750,
|
|
35941
|
+
knownTemplates: knownTemplatesFor(11155111)
|
|
35854
35942
|
}
|
|
35855
35943
|
};
|
|
35856
35944
|
function getSailDeployment(chainId) {
|
|
@@ -35861,122 +35949,6 @@ function getSailDeployment(chainId) {
|
|
|
35861
35949
|
return deployment;
|
|
35862
35950
|
}
|
|
35863
35951
|
|
|
35864
|
-
// ../sdk/dist/errors.js
|
|
35865
|
-
init_esm2();
|
|
35866
|
-
var KERNEL_ERROR_SIGNATURES = [
|
|
35867
|
-
"error AccountAlreadyRegistered(address account)",
|
|
35868
|
-
"error AccountNotRegistered(address account)",
|
|
35869
|
-
"error AccountSelfTarget()",
|
|
35870
|
-
"error ArrayLengthMismatch()",
|
|
35871
|
-
"error BatchPermissionDenied()",
|
|
35872
|
-
"error BatchSubcallFailed(uint256 index, address target)",
|
|
35873
|
-
"error BatchTooLong(uint256 length)",
|
|
35874
|
-
"error BatchZeroTarget(uint256 index)",
|
|
35875
|
-
"error DeadlineExpired(uint256 deadline, uint256 current)",
|
|
35876
|
-
"error DistributorBpsTooLarge(uint256 bps)",
|
|
35877
|
-
"error EmptyBatch()",
|
|
35878
|
-
"error FeePolicyNotSet()",
|
|
35879
|
-
"error FeeTokenMismatch(address provided, address expected)",
|
|
35880
|
-
"error FeeTooLarge(uint256 requested, uint256 maxAllowed)",
|
|
35881
|
-
"error FeeTransferFailed()",
|
|
35882
|
-
"error InsufficientFee(uint256 required, uint256 provided)",
|
|
35883
|
-
"error InvalidInitializer()",
|
|
35884
|
-
"error InvalidManagerSignature()",
|
|
35885
|
-
"error InvalidSignerSignature()",
|
|
35886
|
-
"error KernelSelfTarget(uint256 index)",
|
|
35887
|
-
// SAIL-405: setManager rejects a no-op rotation (newManager == current).
|
|
35888
|
-
"error ManagerUnchanged()",
|
|
35889
|
-
"error ModuleNotEnabled()",
|
|
35890
|
-
// Present in the deployed conjunctive kernel; dropped in the latest source.
|
|
35891
|
-
"error NoPermissionsRegistered(address account)",
|
|
35892
|
-
"error NotAContract(address addr)",
|
|
35893
|
-
"error NotGovernance()",
|
|
35894
|
-
"error NotManager(address caller, address expected)",
|
|
35895
|
-
"error NotPermissionSigner()",
|
|
35896
|
-
"error NotTimelock()",
|
|
35897
|
-
"error PermissionAlreadyRegistered(address permission)",
|
|
35898
|
-
"error PermissionDenied(address permission)",
|
|
35899
|
-
"error PermissionNotBatchAware(address permission)",
|
|
35900
|
-
"error PermissionNotRegistered(address permission)",
|
|
35901
|
-
"error ProtocolPaused()",
|
|
35902
|
-
"error SafeExecutionFailed()",
|
|
35903
|
-
"error SessionInactive(address account)",
|
|
35904
|
-
"error TooManyPermissions(address account, uint256 limit)",
|
|
35905
|
-
"error UntrustedFactory(address factory)",
|
|
35906
|
-
"error UntrustedFeePolicy(address policy)",
|
|
35907
|
-
"error UntrustedModuleSetup(address setup)",
|
|
35908
|
-
"error UntrustedProxyCodehash(bytes32 codehash)",
|
|
35909
|
-
"error UntrustedSingleton(address singleton)",
|
|
35910
|
-
"error ZeroAddress()",
|
|
35911
|
-
"error ZeroFee()"
|
|
35912
|
-
];
|
|
35913
|
-
var KERNEL_ERROR_ABI = parseAbi(KERNEL_ERROR_SIGNATURES);
|
|
35914
|
-
var ERROR_HINTS = {
|
|
35915
|
-
InvalidManagerSignature: "The manager's EIP-712 Dispatch signature did not recover to the registered manager. Most common cause: a stale manager nonce (the kernel's managerNonces advanced between signing and submission \u2014 e.g. a load-balanced RPC returned a lagging value, or two dispatches were signed against the same nonce). Re-read managerNonces and re-sign, or track the nonce locally and increment it across sequential dispatches. Can also mean the wrong EIP-712 Dispatch type was used for this kernel version \u2014 see detectKernelCapabilities.",
|
|
35916
|
-
PermissionDenied: "A registered permission's evaluate() returned false (or reverted / ran out of gas) for this call. In a conjunctive kernel EVERY registered permission must approve EVERY call, so a permission that does not pass through calls outside its own domain will block unrelated dispatches. Check that each permission either matches this call or returns true for calls it doesn't govern.",
|
|
35917
|
-
NoPermissionsRegistered: "The account has zero registered permissions, so the kernel denies by default. Register at least one permission (kernel.registerPermission / registerPermissions) before dispatching.",
|
|
35918
|
-
PermissionNotRegistered: "The named permission is not registered for this account. Register it first, or (on a conjunctive kernel) drop the permission argument \u2014 that kernel checks all registered permissions automatically.",
|
|
35919
|
-
SessionInactive: "The manager's session is revoked. Re-activate it (session.activate) before dispatching.",
|
|
35920
|
-
DeadlineExpired: "The signature deadline is in the past. Use a deadline comfortably ahead of block.timestamp.",
|
|
35921
|
-
SafeExecutionFailed: "The underlying Safe module call reverted. The permission passed, but the target call itself failed (e.g. slippage too tight, insufficient allowance/balance, or a failing swap route).",
|
|
35922
|
-
ModuleNotEnabled: "The Sail module is not enabled on the Safe. Complete account onboarding (enable the module) first.",
|
|
35923
|
-
ProtocolPaused: "The protocol is paused by governance. Dispatches are blocked until it is unpaused.",
|
|
35924
|
-
NotManager: "The submitting address is not the registered manager for this account.",
|
|
35925
|
-
TooManyPermissions: "Registering this permission would exceed the kernel's per-account permission cap. Revoke an unused permission first."
|
|
35926
|
-
};
|
|
35927
|
-
async function decode2(data) {
|
|
35928
|
-
const { decodeErrorResult: decodeErrorResult2 } = await Promise.resolve().then(() => (init_esm2(), esm_exports2));
|
|
35929
|
-
try {
|
|
35930
|
-
const decoded = decodeErrorResult2({ abi: KERNEL_ERROR_ABI, data });
|
|
35931
|
-
const name = decoded.errorName;
|
|
35932
|
-
const args = decoded.args ?? [];
|
|
35933
|
-
const selector = data.slice(0, 10);
|
|
35934
|
-
const hint = ERROR_HINTS[name];
|
|
35935
|
-
const argStr = args.length ? `(${args.map(String).join(", ")})` : "()";
|
|
35936
|
-
const message = hint ? `${name}${argStr} \u2014 ${hint}` : `${name}${argStr}`;
|
|
35937
|
-
return { name, args, selector, hint, message };
|
|
35938
|
-
} catch {
|
|
35939
|
-
return null;
|
|
35940
|
-
}
|
|
35941
|
-
}
|
|
35942
|
-
function decodeKernelError(data) {
|
|
35943
|
-
if (!data || data === "0x")
|
|
35944
|
-
return Promise.resolve(null);
|
|
35945
|
-
return decode2(data);
|
|
35946
|
-
}
|
|
35947
|
-
async function explainKernelRevert(err) {
|
|
35948
|
-
const data = extractRevertData(err);
|
|
35949
|
-
if (!data)
|
|
35950
|
-
return null;
|
|
35951
|
-
return decodeKernelError(data);
|
|
35952
|
-
}
|
|
35953
|
-
function extractRevertData(err) {
|
|
35954
|
-
const seen = /* @__PURE__ */ new Set();
|
|
35955
|
-
let cursor = err;
|
|
35956
|
-
let depth = 0;
|
|
35957
|
-
while (cursor && typeof cursor === "object" && !seen.has(cursor) && depth < 12) {
|
|
35958
|
-
seen.add(cursor);
|
|
35959
|
-
depth++;
|
|
35960
|
-
const obj = cursor;
|
|
35961
|
-
const data = obj["data"];
|
|
35962
|
-
if (typeof data === "string" && data.startsWith("0x") && data.length >= 10) {
|
|
35963
|
-
return data;
|
|
35964
|
-
}
|
|
35965
|
-
if (data && typeof data === "object") {
|
|
35966
|
-
const inner = data["data"];
|
|
35967
|
-
if (typeof inner === "string" && inner.startsWith("0x") && inner.length >= 10) {
|
|
35968
|
-
return inner;
|
|
35969
|
-
}
|
|
35970
|
-
}
|
|
35971
|
-
const raw = obj["raw"];
|
|
35972
|
-
if (typeof raw === "string" && raw.startsWith("0x") && raw.length >= 10) {
|
|
35973
|
-
return raw;
|
|
35974
|
-
}
|
|
35975
|
-
cursor = obj["cause"];
|
|
35976
|
-
}
|
|
35977
|
-
return null;
|
|
35978
|
-
}
|
|
35979
|
-
|
|
35980
35952
|
// ../sdk/dist/eip712.js
|
|
35981
35953
|
init_esm2();
|
|
35982
35954
|
function sailKernelDomain(args) {
|
|
@@ -36112,7 +36084,198 @@ function buildRegisterPermissionsBatchTypedData(args) {
|
|
|
36112
36084
|
nonce: args.nonce.toString(),
|
|
36113
36085
|
deadline: deadline.toString()
|
|
36114
36086
|
}
|
|
36115
|
-
};
|
|
36087
|
+
};
|
|
36088
|
+
}
|
|
36089
|
+
var TEMPLATE_EIP712_DOMAIN_ABI = [
|
|
36090
|
+
{
|
|
36091
|
+
type: "function",
|
|
36092
|
+
name: "eip712Domain",
|
|
36093
|
+
stateMutability: "view",
|
|
36094
|
+
inputs: [],
|
|
36095
|
+
outputs: [
|
|
36096
|
+
{ name: "fields", type: "bytes1" },
|
|
36097
|
+
{ name: "name", type: "string" },
|
|
36098
|
+
{ name: "version", type: "string" },
|
|
36099
|
+
{ name: "chainId", type: "uint256" },
|
|
36100
|
+
{ name: "verifyingContract", type: "address" },
|
|
36101
|
+
{ name: "salt", type: "bytes32" },
|
|
36102
|
+
{ name: "extensions", type: "uint256[]" }
|
|
36103
|
+
]
|
|
36104
|
+
}
|
|
36105
|
+
];
|
|
36106
|
+
var REGISTRATION_EPOCH_ABI = [
|
|
36107
|
+
{
|
|
36108
|
+
type: "function",
|
|
36109
|
+
name: "registrationEpoch",
|
|
36110
|
+
stateMutability: "view",
|
|
36111
|
+
inputs: [
|
|
36112
|
+
{ name: "account", type: "address" },
|
|
36113
|
+
{ name: "permission", type: "address" }
|
|
36114
|
+
],
|
|
36115
|
+
outputs: [{ type: "uint256" }]
|
|
36116
|
+
}
|
|
36117
|
+
];
|
|
36118
|
+
var CONFIGURE_FIELDS_V1 = [
|
|
36119
|
+
{ name: "account", type: "address" },
|
|
36120
|
+
{ name: "paramsHash", type: "bytes32" },
|
|
36121
|
+
{ name: "nonce", type: "uint256" },
|
|
36122
|
+
{ name: "deadline", type: "uint256" }
|
|
36123
|
+
];
|
|
36124
|
+
var CONFIGURE_FIELDS_V2 = [...CONFIGURE_FIELDS_V1, { name: "epoch", type: "uint256" }];
|
|
36125
|
+
async function buildConfigureTypedData(args) {
|
|
36126
|
+
const [, name, version4, chainId] = await args.publicClient.readContract({
|
|
36127
|
+
address: args.template,
|
|
36128
|
+
abi: TEMPLATE_EIP712_DOMAIN_ABI,
|
|
36129
|
+
functionName: "eip712Domain"
|
|
36130
|
+
});
|
|
36131
|
+
if (version4 !== "1" && version4 !== "2") {
|
|
36132
|
+
throw new Error(`Unsupported template EIP-712 domain version "${version4}" for ${args.template}. This SDK signs Configure schema v1 or v2; upgrade the SDK for newer templates.`);
|
|
36133
|
+
}
|
|
36134
|
+
const isV2 = version4 === "2";
|
|
36135
|
+
const message = {
|
|
36136
|
+
account: args.account,
|
|
36137
|
+
paramsHash: keccak256(args.params),
|
|
36138
|
+
nonce: args.nonce.toString(),
|
|
36139
|
+
deadline: args.deadline.toString()
|
|
36140
|
+
};
|
|
36141
|
+
if (isV2) {
|
|
36142
|
+
const epoch = await args.publicClient.readContract({
|
|
36143
|
+
address: args.kernel,
|
|
36144
|
+
abi: REGISTRATION_EPOCH_ABI,
|
|
36145
|
+
functionName: "registrationEpoch",
|
|
36146
|
+
args: [args.account, args.template]
|
|
36147
|
+
});
|
|
36148
|
+
message.epoch = epoch.toString();
|
|
36149
|
+
}
|
|
36150
|
+
return {
|
|
36151
|
+
domain: {
|
|
36152
|
+
name,
|
|
36153
|
+
version: version4,
|
|
36154
|
+
chainId: Number(chainId),
|
|
36155
|
+
verifyingContract: args.template
|
|
36156
|
+
},
|
|
36157
|
+
types: {
|
|
36158
|
+
Configure: isV2 ? CONFIGURE_FIELDS_V2 : CONFIGURE_FIELDS_V1
|
|
36159
|
+
},
|
|
36160
|
+
primaryType: "Configure",
|
|
36161
|
+
message
|
|
36162
|
+
};
|
|
36163
|
+
}
|
|
36164
|
+
|
|
36165
|
+
// ../sdk/dist/errors.js
|
|
36166
|
+
init_esm2();
|
|
36167
|
+
var KERNEL_ERROR_SIGNATURES = [
|
|
36168
|
+
"error AccountAlreadyRegistered(address account)",
|
|
36169
|
+
"error AccountNotRegistered(address account)",
|
|
36170
|
+
"error AccountSelfTarget()",
|
|
36171
|
+
"error ArrayLengthMismatch()",
|
|
36172
|
+
"error BatchPermissionDenied()",
|
|
36173
|
+
"error BatchSubcallFailed(uint256 index, address target)",
|
|
36174
|
+
"error BatchTooLong(uint256 length)",
|
|
36175
|
+
"error BatchZeroTarget(uint256 index)",
|
|
36176
|
+
"error DeadlineExpired(uint256 deadline, uint256 current)",
|
|
36177
|
+
"error DistributorBpsTooLarge(uint256 bps)",
|
|
36178
|
+
"error EmptyBatch()",
|
|
36179
|
+
"error FeePolicyNotSet()",
|
|
36180
|
+
"error FeeTokenMismatch(address provided, address expected)",
|
|
36181
|
+
"error FeeTooLarge(uint256 requested, uint256 maxAllowed)",
|
|
36182
|
+
"error FeeTransferFailed()",
|
|
36183
|
+
"error InsufficientFee(uint256 required, uint256 provided)",
|
|
36184
|
+
"error InvalidInitializer()",
|
|
36185
|
+
"error InvalidManagerSignature()",
|
|
36186
|
+
"error InvalidSignerSignature()",
|
|
36187
|
+
"error KernelSelfTarget(uint256 index)",
|
|
36188
|
+
// SAIL-405: setManager rejects a no-op rotation (newManager == current).
|
|
36189
|
+
"error ManagerUnchanged()",
|
|
36190
|
+
"error ModuleNotEnabled()",
|
|
36191
|
+
// Present in the deployed conjunctive kernel; dropped in the latest source.
|
|
36192
|
+
"error NoPermissionsRegistered(address account)",
|
|
36193
|
+
"error NotAContract(address addr)",
|
|
36194
|
+
"error NotGovernance()",
|
|
36195
|
+
"error NotManager(address caller, address expected)",
|
|
36196
|
+
"error NotPermissionSigner()",
|
|
36197
|
+
"error NotTimelock()",
|
|
36198
|
+
"error PermissionAlreadyRegistered(address permission)",
|
|
36199
|
+
"error PermissionDenied(address permission)",
|
|
36200
|
+
"error PermissionNotBatchAware(address permission)",
|
|
36201
|
+
"error PermissionNotRegistered(address permission)",
|
|
36202
|
+
"error ProtocolPaused()",
|
|
36203
|
+
"error SafeExecutionFailed()",
|
|
36204
|
+
"error SessionInactive(address account)",
|
|
36205
|
+
"error TooManyPermissions(address account, uint256 limit)",
|
|
36206
|
+
"error UntrustedFactory(address factory)",
|
|
36207
|
+
"error UntrustedFeePolicy(address policy)",
|
|
36208
|
+
"error UntrustedModuleSetup(address setup)",
|
|
36209
|
+
"error UntrustedProxyCodehash(bytes32 codehash)",
|
|
36210
|
+
"error UntrustedSingleton(address singleton)",
|
|
36211
|
+
"error ZeroAddress()",
|
|
36212
|
+
"error ZeroFee()"
|
|
36213
|
+
];
|
|
36214
|
+
var KERNEL_ERROR_ABI = parseAbi(KERNEL_ERROR_SIGNATURES);
|
|
36215
|
+
var ERROR_HINTS = {
|
|
36216
|
+
InvalidManagerSignature: "The manager's EIP-712 Dispatch signature did not recover to the registered manager. Most common cause: a stale manager nonce (the kernel's managerNonces advanced between signing and submission \u2014 e.g. a load-balanced RPC returned a lagging value, or two dispatches were signed against the same nonce). Re-read managerNonces and re-sign, or track the nonce locally and increment it across sequential dispatches. Can also mean the wrong EIP-712 Dispatch type was used for this kernel version \u2014 see detectKernelCapabilities.",
|
|
36217
|
+
PermissionDenied: "A registered permission's evaluate() returned false (or reverted / ran out of gas) for this call. In a conjunctive kernel EVERY registered permission must approve EVERY call, so a permission that does not pass through calls outside its own domain will block unrelated dispatches. Check that each permission either matches this call or returns true for calls it doesn't govern.",
|
|
36218
|
+
NoPermissionsRegistered: "The account has zero registered permissions, so the kernel denies by default. Register at least one permission (kernel.registerPermission / registerPermissions) before dispatching.",
|
|
36219
|
+
PermissionNotRegistered: "The named permission is not registered for this account. Register it first, or (on a conjunctive kernel) drop the permission argument \u2014 that kernel checks all registered permissions automatically.",
|
|
36220
|
+
SessionInactive: "The manager's session is revoked. Re-activate it (session.activate) before dispatching.",
|
|
36221
|
+
DeadlineExpired: "The signature deadline is in the past. Use a deadline comfortably ahead of block.timestamp.",
|
|
36222
|
+
SafeExecutionFailed: "The underlying Safe module call reverted. The permission passed, but the target call itself failed (e.g. slippage too tight, insufficient allowance/balance, or a failing swap route).",
|
|
36223
|
+
ModuleNotEnabled: "The Sail module is not enabled on the Safe. Complete account onboarding (enable the module) first.",
|
|
36224
|
+
ProtocolPaused: "The protocol is paused by governance. Dispatches are blocked until it is unpaused.",
|
|
36225
|
+
NotManager: "The submitting address is not the registered manager for this account.",
|
|
36226
|
+
TooManyPermissions: "Registering this permission would exceed the kernel's per-account permission cap. Revoke an unused permission first."
|
|
36227
|
+
};
|
|
36228
|
+
async function decode2(data) {
|
|
36229
|
+
const { decodeErrorResult: decodeErrorResult2 } = await Promise.resolve().then(() => (init_esm2(), esm_exports2));
|
|
36230
|
+
try {
|
|
36231
|
+
const decoded = decodeErrorResult2({ abi: KERNEL_ERROR_ABI, data });
|
|
36232
|
+
const name = decoded.errorName;
|
|
36233
|
+
const args = decoded.args ?? [];
|
|
36234
|
+
const selector = data.slice(0, 10);
|
|
36235
|
+
const hint = ERROR_HINTS[name];
|
|
36236
|
+
const argStr = args.length ? `(${args.map(String).join(", ")})` : "()";
|
|
36237
|
+
const message = hint ? `${name}${argStr} \u2014 ${hint}` : `${name}${argStr}`;
|
|
36238
|
+
return { name, args, selector, hint, message };
|
|
36239
|
+
} catch {
|
|
36240
|
+
return null;
|
|
36241
|
+
}
|
|
36242
|
+
}
|
|
36243
|
+
function decodeKernelError(data) {
|
|
36244
|
+
if (!data || data === "0x")
|
|
36245
|
+
return Promise.resolve(null);
|
|
36246
|
+
return decode2(data);
|
|
36247
|
+
}
|
|
36248
|
+
async function explainKernelRevert(err) {
|
|
36249
|
+
const data = extractRevertData(err);
|
|
36250
|
+
if (!data)
|
|
36251
|
+
return null;
|
|
36252
|
+
return decodeKernelError(data);
|
|
36253
|
+
}
|
|
36254
|
+
function extractRevertData(err) {
|
|
36255
|
+
const seen = /* @__PURE__ */ new Set();
|
|
36256
|
+
let cursor = err;
|
|
36257
|
+
let depth = 0;
|
|
36258
|
+
while (cursor && typeof cursor === "object" && !seen.has(cursor) && depth < 12) {
|
|
36259
|
+
seen.add(cursor);
|
|
36260
|
+
depth++;
|
|
36261
|
+
const obj = cursor;
|
|
36262
|
+
const data = obj["data"];
|
|
36263
|
+
if (typeof data === "string" && data.startsWith("0x") && data.length >= 10) {
|
|
36264
|
+
return data;
|
|
36265
|
+
}
|
|
36266
|
+
if (data && typeof data === "object") {
|
|
36267
|
+
const inner = data["data"];
|
|
36268
|
+
if (typeof inner === "string" && inner.startsWith("0x") && inner.length >= 10) {
|
|
36269
|
+
return inner;
|
|
36270
|
+
}
|
|
36271
|
+
}
|
|
36272
|
+
const raw = obj["raw"];
|
|
36273
|
+
if (typeof raw === "string" && raw.startsWith("0x") && raw.length >= 10) {
|
|
36274
|
+
return raw;
|
|
36275
|
+
}
|
|
36276
|
+
cursor = obj["cause"];
|
|
36277
|
+
}
|
|
36278
|
+
return null;
|
|
36116
36279
|
}
|
|
36117
36280
|
|
|
36118
36281
|
// ../sdk/dist/lifi.js
|
|
@@ -36181,9 +36344,30 @@ function buildPublicClient(config) {
|
|
|
36181
36344
|
function defaultDeadline() {
|
|
36182
36345
|
return BigInt(Math.floor(Date.now() / 1e3) + 300);
|
|
36183
36346
|
}
|
|
36347
|
+
var CONFIGURABLE_PERMISSION_ABI = [
|
|
36348
|
+
{
|
|
36349
|
+
type: "function",
|
|
36350
|
+
name: "configNonces",
|
|
36351
|
+
stateMutability: "view",
|
|
36352
|
+
inputs: [{ name: "account", type: "address" }],
|
|
36353
|
+
outputs: [{ type: "uint256" }]
|
|
36354
|
+
},
|
|
36355
|
+
{
|
|
36356
|
+
type: "function",
|
|
36357
|
+
name: "configure",
|
|
36358
|
+
stateMutability: "nonpayable",
|
|
36359
|
+
inputs: [
|
|
36360
|
+
{ name: "account", type: "address" },
|
|
36361
|
+
{ name: "params", type: "bytes" },
|
|
36362
|
+
{ name: "deadline", type: "uint256" },
|
|
36363
|
+
{ name: "sig", type: "bytes" }
|
|
36364
|
+
],
|
|
36365
|
+
outputs: []
|
|
36366
|
+
}
|
|
36367
|
+
];
|
|
36184
36368
|
var DEFAULT_DISPATCH_GAS = 2000000n;
|
|
36185
36369
|
function delay(ms) {
|
|
36186
|
-
return new Promise((
|
|
36370
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
36187
36371
|
}
|
|
36188
36372
|
var CALL_COMPONENTS = [
|
|
36189
36373
|
{ name: "target", type: "address" },
|
|
@@ -36337,8 +36521,47 @@ var MandateNamespace = class extends KernelNamespace {
|
|
|
36337
36521
|
value: 0n
|
|
36338
36522
|
});
|
|
36339
36523
|
}
|
|
36340
|
-
|
|
36341
|
-
|
|
36524
|
+
/**
|
|
36525
|
+
* Re-configure the per-account bounds of an already-registered shared template.
|
|
36526
|
+
* The permission signer signs the template's `Configure` EIP-712 struct — built by
|
|
36527
|
+
* `buildConfigureTypedData`, which reads the template's live ERC-5267 domain and emits
|
|
36528
|
+
* the v1 or v2 (epoch-bound) schema to match whatever is deployed — and the attached
|
|
36529
|
+
* wallet submits `configure(account, params, deadline, sig)`.
|
|
36530
|
+
*
|
|
36531
|
+
* The config nonce is read fresh on-chain immediately before signing (the template
|
|
36532
|
+
* increments it only after a successful verify), so a re-config never reuses a stale nonce.
|
|
36533
|
+
*/
|
|
36534
|
+
async reconfigure(safe, template, params, signer) {
|
|
36535
|
+
const kernel = this.requireKernel();
|
|
36536
|
+
const wallet = this.requireSigner();
|
|
36537
|
+
const encoded = template.encoder.encode(params);
|
|
36538
|
+
const deadline = defaultDeadline();
|
|
36539
|
+
const nonce = await this.publicClient.readContract({
|
|
36540
|
+
address: template.address,
|
|
36541
|
+
abi: CONFIGURABLE_PERMISSION_ABI,
|
|
36542
|
+
functionName: "configNonces",
|
|
36543
|
+
args: [safe]
|
|
36544
|
+
});
|
|
36545
|
+
const td = await buildConfigureTypedData({
|
|
36546
|
+
publicClient: this.publicClient,
|
|
36547
|
+
kernel,
|
|
36548
|
+
template: template.address,
|
|
36549
|
+
account: safe,
|
|
36550
|
+
params: encoded,
|
|
36551
|
+
nonce,
|
|
36552
|
+
deadline
|
|
36553
|
+
});
|
|
36554
|
+
const sig = await signer.signTyped(td.domain, { primaryType: td.primaryType, types: td.types }, td.message);
|
|
36555
|
+
const txHash = await wallet.writeContract({
|
|
36556
|
+
address: template.address,
|
|
36557
|
+
abi: CONFIGURABLE_PERMISSION_ABI,
|
|
36558
|
+
functionName: "configure",
|
|
36559
|
+
args: [safe, encoded, deadline, sig]
|
|
36560
|
+
});
|
|
36561
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
36562
|
+
if (receipt.status !== "success") {
|
|
36563
|
+
throw new Error(`configure reverted (tx ${txHash})`);
|
|
36564
|
+
}
|
|
36342
36565
|
}
|
|
36343
36566
|
replace(_safe, _oldTemplate, _newTemplate, _params, _signer) {
|
|
36344
36567
|
return notImplemented();
|
|
@@ -36637,14 +36860,67 @@ var StrategyNamespace = class extends KernelNamespace {
|
|
|
36637
36860
|
}
|
|
36638
36861
|
};
|
|
36639
36862
|
var SessionNamespace = class extends KernelNamespace {
|
|
36640
|
-
|
|
36641
|
-
|
|
36863
|
+
/**
|
|
36864
|
+
* Suspend (`revokeSession`) or resume (`activateSession`) the manager's dispatch rights.
|
|
36865
|
+
* Both are permissionSigner-signed over the RevokeSession/ActivateSession EIP-712 struct,
|
|
36866
|
+
* with `nonce` read fresh from `signerNonces[account]` immediately before signing — the
|
|
36867
|
+
* kernel bumps that nonce by a full epoch on revoke (#70), so it must never be cached. The
|
|
36868
|
+
* kernel also rotates the manager/batch nonce epochs, invalidating any pre-signed dispatch.
|
|
36869
|
+
*/
|
|
36870
|
+
async revoke(safe, signer) {
|
|
36871
|
+
await this.#submitSessionOp(safe, signer, "RevokeSession", "revokeSession");
|
|
36642
36872
|
}
|
|
36643
|
-
activate(
|
|
36644
|
-
|
|
36873
|
+
async activate(safe, signer) {
|
|
36874
|
+
await this.#submitSessionOp(safe, signer, "ActivateSession", "activateSession");
|
|
36645
36875
|
}
|
|
36646
|
-
|
|
36647
|
-
|
|
36876
|
+
async #submitSessionOp(safe, signer, primaryType, fn) {
|
|
36877
|
+
const kernel = this.requireKernel();
|
|
36878
|
+
const wallet = this.requireSigner();
|
|
36879
|
+
const deadline = defaultDeadline();
|
|
36880
|
+
const nonce = await this.publicClient.readContract({
|
|
36881
|
+
address: kernel,
|
|
36882
|
+
abi: SailKernelAbi,
|
|
36883
|
+
functionName: "signerNonces",
|
|
36884
|
+
args: [safe]
|
|
36885
|
+
});
|
|
36886
|
+
const sig = await signer.signTyped(sailKernelDomain({ chainId: this.config.chainId, kernel }), {
|
|
36887
|
+
primaryType,
|
|
36888
|
+
types: {
|
|
36889
|
+
[primaryType]: [
|
|
36890
|
+
{ name: "account", type: "address" },
|
|
36891
|
+
{ name: "nonce", type: "uint256" },
|
|
36892
|
+
{ name: "deadline", type: "uint256" }
|
|
36893
|
+
]
|
|
36894
|
+
}
|
|
36895
|
+
}, { account: safe, nonce, deadline });
|
|
36896
|
+
const txHash = await wallet.writeContract({
|
|
36897
|
+
address: kernel,
|
|
36898
|
+
abi: SailKernelAbi,
|
|
36899
|
+
functionName: fn,
|
|
36900
|
+
args: [safe, deadline, sig]
|
|
36901
|
+
});
|
|
36902
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
36903
|
+
if (receipt.status !== "success") {
|
|
36904
|
+
throw new Error(`${fn} reverted (tx ${txHash})`);
|
|
36905
|
+
}
|
|
36906
|
+
}
|
|
36907
|
+
async status(safe) {
|
|
36908
|
+
const kernel = this.requireKernel();
|
|
36909
|
+
const cfg = await this.publicClient.readContract({
|
|
36910
|
+
address: kernel,
|
|
36911
|
+
abi: SailKernelAbi,
|
|
36912
|
+
functionName: "configs",
|
|
36913
|
+
args: [safe]
|
|
36914
|
+
});
|
|
36915
|
+
return {
|
|
36916
|
+
safe,
|
|
36917
|
+
active: cfg[4],
|
|
36918
|
+
manager: cfg[1],
|
|
36919
|
+
// Block-level markers require an event scan; expose live active/manager state and
|
|
36920
|
+
// leave the historical timestamps null.
|
|
36921
|
+
activatedAtBlock: null,
|
|
36922
|
+
revokedAtBlock: null
|
|
36923
|
+
};
|
|
36648
36924
|
}
|
|
36649
36925
|
};
|
|
36650
36926
|
var FeesNamespace = class extends KernelNamespace {
|
|
@@ -37613,6 +37889,60 @@ var SailGovernanceAbi = [
|
|
|
37613
37889
|
}
|
|
37614
37890
|
];
|
|
37615
37891
|
|
|
37892
|
+
// ../sdk/dist/abis/ConfigurablePermission.js
|
|
37893
|
+
var ConfigurablePermissionAbi = [
|
|
37894
|
+
{
|
|
37895
|
+
type: "function",
|
|
37896
|
+
name: "configure",
|
|
37897
|
+
stateMutability: "nonpayable",
|
|
37898
|
+
inputs: [
|
|
37899
|
+
{ name: "account", type: "address" },
|
|
37900
|
+
{ name: "params", type: "bytes" },
|
|
37901
|
+
{ name: "deadline", type: "uint256" },
|
|
37902
|
+
{ name: "sig", type: "bytes" }
|
|
37903
|
+
],
|
|
37904
|
+
outputs: []
|
|
37905
|
+
},
|
|
37906
|
+
{
|
|
37907
|
+
type: "function",
|
|
37908
|
+
name: "configureDirect",
|
|
37909
|
+
stateMutability: "nonpayable",
|
|
37910
|
+
inputs: [
|
|
37911
|
+
{ name: "account", type: "address" },
|
|
37912
|
+
{ name: "params", type: "bytes" }
|
|
37913
|
+
],
|
|
37914
|
+
outputs: []
|
|
37915
|
+
},
|
|
37916
|
+
{
|
|
37917
|
+
type: "function",
|
|
37918
|
+
name: "isConfigured",
|
|
37919
|
+
stateMutability: "view",
|
|
37920
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37921
|
+
outputs: [{ name: "", type: "bool" }]
|
|
37922
|
+
},
|
|
37923
|
+
{
|
|
37924
|
+
type: "function",
|
|
37925
|
+
name: "configNonces",
|
|
37926
|
+
stateMutability: "view",
|
|
37927
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37928
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
37929
|
+
},
|
|
37930
|
+
{
|
|
37931
|
+
type: "function",
|
|
37932
|
+
name: "configuredEpoch",
|
|
37933
|
+
stateMutability: "view",
|
|
37934
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37935
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
37936
|
+
},
|
|
37937
|
+
{
|
|
37938
|
+
type: "function",
|
|
37939
|
+
name: "hashTypedDataV4",
|
|
37940
|
+
stateMutability: "view",
|
|
37941
|
+
inputs: [{ name: "structHash", type: "bytes32" }],
|
|
37942
|
+
outputs: [{ name: "", type: "bytes32" }]
|
|
37943
|
+
}
|
|
37944
|
+
];
|
|
37945
|
+
|
|
37616
37946
|
// ../sdk/dist/safe.js
|
|
37617
37947
|
init_esm2();
|
|
37618
37948
|
var setManagerAbi = [
|
|
@@ -37858,6 +38188,9 @@ var SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
|
|
|
37858
38188
|
// src/commands/account.ts
|
|
37859
38189
|
init_esm2();
|
|
37860
38190
|
|
|
38191
|
+
// src/lib/chain.ts
|
|
38192
|
+
init_esm2();
|
|
38193
|
+
|
|
37861
38194
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/op-stack/contracts.js
|
|
37862
38195
|
var contracts = {
|
|
37863
38196
|
gasPriceOracle: { address: "0x420000000000000000000000000000000000000F" },
|
|
@@ -38129,6 +38462,35 @@ var baseSepoliaPreconf = /* @__PURE__ */ defineChain({
|
|
|
38129
38462
|
}
|
|
38130
38463
|
});
|
|
38131
38464
|
|
|
38465
|
+
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/bsc.js
|
|
38466
|
+
init_defineChain();
|
|
38467
|
+
var bsc = /* @__PURE__ */ defineChain({
|
|
38468
|
+
id: 56,
|
|
38469
|
+
name: "BNB Smart Chain",
|
|
38470
|
+
blockTime: 750,
|
|
38471
|
+
nativeCurrency: {
|
|
38472
|
+
decimals: 18,
|
|
38473
|
+
name: "BNB",
|
|
38474
|
+
symbol: "BNB"
|
|
38475
|
+
},
|
|
38476
|
+
rpcUrls: {
|
|
38477
|
+
default: { http: ["https://56.rpc.thirdweb.com"] }
|
|
38478
|
+
},
|
|
38479
|
+
blockExplorers: {
|
|
38480
|
+
default: {
|
|
38481
|
+
name: "BscScan",
|
|
38482
|
+
url: "https://bscscan.com",
|
|
38483
|
+
apiUrl: "https://api.bscscan.com/api"
|
|
38484
|
+
}
|
|
38485
|
+
},
|
|
38486
|
+
contracts: {
|
|
38487
|
+
multicall3: {
|
|
38488
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38489
|
+
blockCreated: 15921452
|
|
38490
|
+
}
|
|
38491
|
+
}
|
|
38492
|
+
});
|
|
38493
|
+
|
|
38132
38494
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/mainnet.js
|
|
38133
38495
|
init_defineChain();
|
|
38134
38496
|
var mainnet = /* @__PURE__ */ defineChain({
|
|
@@ -38160,6 +38522,56 @@ var mainnet = /* @__PURE__ */ defineChain({
|
|
|
38160
38522
|
}
|
|
38161
38523
|
});
|
|
38162
38524
|
|
|
38525
|
+
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/optimism.js
|
|
38526
|
+
init_defineChain();
|
|
38527
|
+
var sourceId3 = 1;
|
|
38528
|
+
var optimism = /* @__PURE__ */ defineChain({
|
|
38529
|
+
...chainConfig,
|
|
38530
|
+
id: 10,
|
|
38531
|
+
name: "OP Mainnet",
|
|
38532
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38533
|
+
rpcUrls: {
|
|
38534
|
+
default: {
|
|
38535
|
+
http: ["https://mainnet.optimism.io"]
|
|
38536
|
+
}
|
|
38537
|
+
},
|
|
38538
|
+
blockExplorers: {
|
|
38539
|
+
default: {
|
|
38540
|
+
name: "Optimism Explorer",
|
|
38541
|
+
url: "https://optimistic.etherscan.io",
|
|
38542
|
+
apiUrl: "https://api-optimistic.etherscan.io/api"
|
|
38543
|
+
}
|
|
38544
|
+
},
|
|
38545
|
+
contracts: {
|
|
38546
|
+
...chainConfig.contracts,
|
|
38547
|
+
disputeGameFactory: {
|
|
38548
|
+
[sourceId3]: {
|
|
38549
|
+
address: "0xe5965Ab5962eDc7477C8520243A95517CD252fA9"
|
|
38550
|
+
}
|
|
38551
|
+
},
|
|
38552
|
+
l2OutputOracle: {
|
|
38553
|
+
[sourceId3]: {
|
|
38554
|
+
address: "0xdfe97868233d1aa22e815a266982f2cf17685a27"
|
|
38555
|
+
}
|
|
38556
|
+
},
|
|
38557
|
+
multicall3: {
|
|
38558
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38559
|
+
blockCreated: 4286263
|
|
38560
|
+
},
|
|
38561
|
+
portal: {
|
|
38562
|
+
[sourceId3]: {
|
|
38563
|
+
address: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"
|
|
38564
|
+
}
|
|
38565
|
+
},
|
|
38566
|
+
l1StandardBridge: {
|
|
38567
|
+
[sourceId3]: {
|
|
38568
|
+
address: "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"
|
|
38569
|
+
}
|
|
38570
|
+
}
|
|
38571
|
+
},
|
|
38572
|
+
sourceId: sourceId3
|
|
38573
|
+
});
|
|
38574
|
+
|
|
38163
38575
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/sepolia.js
|
|
38164
38576
|
init_defineChain();
|
|
38165
38577
|
var sepolia = /* @__PURE__ */ defineChain({
|
|
@@ -38193,7 +38605,7 @@ var sepolia = /* @__PURE__ */ defineChain({
|
|
|
38193
38605
|
|
|
38194
38606
|
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/unichain.js
|
|
38195
38607
|
init_defineChain();
|
|
38196
|
-
var
|
|
38608
|
+
var sourceId4 = 1;
|
|
38197
38609
|
var unichain = /* @__PURE__ */ defineChain({
|
|
38198
38610
|
...chainConfig,
|
|
38199
38611
|
id: 130,
|
|
@@ -38219,22 +38631,77 @@ var unichain = /* @__PURE__ */ defineChain({
|
|
|
38219
38631
|
blockCreated: 0
|
|
38220
38632
|
},
|
|
38221
38633
|
disputeGameFactory: {
|
|
38222
|
-
[
|
|
38634
|
+
[sourceId4]: {
|
|
38223
38635
|
address: "0x2F12d621a16e2d3285929C9996f478508951dFe4"
|
|
38224
38636
|
}
|
|
38225
38637
|
},
|
|
38226
38638
|
portal: {
|
|
38227
|
-
[
|
|
38639
|
+
[sourceId4]: {
|
|
38228
38640
|
address: "0x0bd48f6B86a26D3a217d0Fa6FfE2B491B956A7a2"
|
|
38229
38641
|
}
|
|
38230
38642
|
},
|
|
38231
38643
|
l1StandardBridge: {
|
|
38232
|
-
[
|
|
38644
|
+
[sourceId4]: {
|
|
38233
38645
|
address: "0x81014F44b0a345033bB2b3B21C7a1A308B35fEeA"
|
|
38234
38646
|
}
|
|
38235
38647
|
}
|
|
38236
38648
|
},
|
|
38237
|
-
sourceId:
|
|
38649
|
+
sourceId: sourceId4
|
|
38650
|
+
});
|
|
38651
|
+
|
|
38652
|
+
// ../../node_modules/.pnpm/viem@2.51.3_bufferutil@4.1.0_typescript@5.9.3_utf-8-validate@5.0.10_zod@4.4.3/node_modules/viem/_esm/chains/definitions/worldchain.js
|
|
38653
|
+
init_defineChain();
|
|
38654
|
+
var sourceId5 = 1;
|
|
38655
|
+
var worldchain = /* @__PURE__ */ defineChain({
|
|
38656
|
+
...chainConfig,
|
|
38657
|
+
id: 480,
|
|
38658
|
+
name: "World Chain",
|
|
38659
|
+
network: "worldchain",
|
|
38660
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38661
|
+
rpcUrls: {
|
|
38662
|
+
default: { http: ["https://worldchain-mainnet.g.alchemy.com/public"] }
|
|
38663
|
+
},
|
|
38664
|
+
blockExplorers: {
|
|
38665
|
+
default: {
|
|
38666
|
+
name: "Worldscan",
|
|
38667
|
+
url: "https://worldscan.org",
|
|
38668
|
+
apiUrl: "https://api.worldscan.org/api"
|
|
38669
|
+
},
|
|
38670
|
+
blockscout: {
|
|
38671
|
+
name: "Blockscout",
|
|
38672
|
+
url: "https://worldchain-mainnet.explorer.alchemy.com",
|
|
38673
|
+
apiUrl: "https://worldchain-mainnet.explorer.alchemy.com/api"
|
|
38674
|
+
}
|
|
38675
|
+
},
|
|
38676
|
+
contracts: {
|
|
38677
|
+
...chainConfig.contracts,
|
|
38678
|
+
multicall3: {
|
|
38679
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38680
|
+
blockCreated: 0
|
|
38681
|
+
},
|
|
38682
|
+
disputeGameFactory: {
|
|
38683
|
+
[sourceId5]: {
|
|
38684
|
+
address: "0x069c4c579671f8c120b1327a73217D01Ea2EC5ea"
|
|
38685
|
+
}
|
|
38686
|
+
},
|
|
38687
|
+
l2OutputOracle: {
|
|
38688
|
+
[sourceId5]: {
|
|
38689
|
+
address: "0x19A6d1E9034596196295CF148509796978343c5D"
|
|
38690
|
+
}
|
|
38691
|
+
},
|
|
38692
|
+
portal: {
|
|
38693
|
+
[sourceId5]: {
|
|
38694
|
+
address: "0xd5ec14a83B7d95BE1E2Ac12523e2dEE12Cbeea6C"
|
|
38695
|
+
}
|
|
38696
|
+
},
|
|
38697
|
+
l1StandardBridge: {
|
|
38698
|
+
[sourceId5]: {
|
|
38699
|
+
address: "0x470458C91978D2d929704489Ad730DC3E3001113"
|
|
38700
|
+
}
|
|
38701
|
+
}
|
|
38702
|
+
},
|
|
38703
|
+
testnet: false,
|
|
38704
|
+
sourceId: sourceId5
|
|
38238
38705
|
});
|
|
38239
38706
|
|
|
38240
38707
|
// src/lib/io.ts
|
|
@@ -38358,14 +38825,14 @@ function getRl() {
|
|
|
38358
38825
|
function ask(query) {
|
|
38359
38826
|
getRl();
|
|
38360
38827
|
process.stdout.write(query);
|
|
38361
|
-
return new Promise((
|
|
38828
|
+
return new Promise((resolve4) => {
|
|
38362
38829
|
const buffered = lineQueue.shift();
|
|
38363
38830
|
if (buffered !== void 0) {
|
|
38364
|
-
|
|
38831
|
+
resolve4(buffered);
|
|
38365
38832
|
} else if (inputClosed) {
|
|
38366
|
-
|
|
38833
|
+
resolve4("");
|
|
38367
38834
|
} else {
|
|
38368
|
-
waiters.push(
|
|
38835
|
+
waiters.push(resolve4);
|
|
38369
38836
|
}
|
|
38370
38837
|
});
|
|
38371
38838
|
}
|
|
@@ -38397,11 +38864,28 @@ async function promptHidden(question) {
|
|
|
38397
38864
|
}
|
|
38398
38865
|
|
|
38399
38866
|
// src/lib/chain.ts
|
|
38867
|
+
var hyperevm = defineChain({
|
|
38868
|
+
id: 999,
|
|
38869
|
+
name: "HyperEVM",
|
|
38870
|
+
nativeCurrency: { name: "HYPE", symbol: "HYPE", decimals: 18 },
|
|
38871
|
+
rpcUrls: { default: { http: [chains[999].defaultRpcUrl] } }
|
|
38872
|
+
});
|
|
38873
|
+
var megaeth = defineChain({
|
|
38874
|
+
id: 4326,
|
|
38875
|
+
name: "MegaETH",
|
|
38876
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38877
|
+
rpcUrls: { default: { http: [chains[4326].defaultRpcUrl] } }
|
|
38878
|
+
});
|
|
38400
38879
|
var CHAINS = {
|
|
38401
38880
|
1: mainnet,
|
|
38402
38881
|
8453: base,
|
|
38403
38882
|
42161: arbitrum,
|
|
38883
|
+
10: optimism,
|
|
38404
38884
|
130: unichain,
|
|
38885
|
+
56: bsc,
|
|
38886
|
+
480: worldchain,
|
|
38887
|
+
999: hyperevm,
|
|
38888
|
+
4326: megaeth,
|
|
38405
38889
|
84532: baseSepolia,
|
|
38406
38890
|
11155111: sepolia
|
|
38407
38891
|
};
|
|
@@ -38409,7 +38893,7 @@ function getChainById(chainId) {
|
|
|
38409
38893
|
const chain2 = CHAINS[chainId];
|
|
38410
38894
|
if (!chain2) {
|
|
38411
38895
|
throw new Error(
|
|
38412
|
-
`Unsupported chainId: ${chainId}. Supported: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 130 (Unichain), 84532 (Base Sepolia), 11155111 (Eth Sepolia)`
|
|
38896
|
+
`Unsupported chainId: ${chainId}. Supported: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 10 (Optimism), 130 (Unichain), 56 (BSC), 480 (World Chain), 999 (HyperEVM), 4326 (MegaETH), 84532 (Base Sepolia), 11155111 (Eth Sepolia)`
|
|
38413
38897
|
);
|
|
38414
38898
|
}
|
|
38415
38899
|
return chain2;
|
|
@@ -38539,11 +39023,11 @@ function isProcessAlive(pid) {
|
|
|
38539
39023
|
}
|
|
38540
39024
|
}
|
|
38541
39025
|
function findFreePort(from14) {
|
|
38542
|
-
return new Promise((
|
|
39026
|
+
return new Promise((resolve4, reject) => {
|
|
38543
39027
|
const server = import_node_net.default.createServer();
|
|
38544
39028
|
server.unref();
|
|
38545
|
-
server.on("error", () => findFreePort(from14 + 1).then(
|
|
38546
|
-
server.listen(from14, "127.0.0.1", () => server.close(() =>
|
|
39029
|
+
server.on("error", () => findFreePort(from14 + 1).then(resolve4, reject));
|
|
39030
|
+
server.listen(from14, "127.0.0.1", () => server.close(() => resolve4(from14)));
|
|
38547
39031
|
});
|
|
38548
39032
|
}
|
|
38549
39033
|
|
|
@@ -39157,8 +39641,9 @@ var SigningServer = class {
|
|
|
39157
39641
|
}
|
|
39158
39642
|
}
|
|
39159
39643
|
if (!(0, import_node_fs6.existsSync)(this.runtimeDir)) (0, import_node_fs6.mkdirSync)(this.runtimeDir, { recursive: true });
|
|
39644
|
+
const serverStatePath = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
39160
39645
|
(0, import_node_fs6.writeFileSync)(
|
|
39161
|
-
|
|
39646
|
+
serverStatePath,
|
|
39162
39647
|
JSON.stringify(
|
|
39163
39648
|
{
|
|
39164
39649
|
url: this._url,
|
|
@@ -39170,8 +39655,10 @@ var SigningServer = class {
|
|
|
39170
39655
|
},
|
|
39171
39656
|
null,
|
|
39172
39657
|
2
|
|
39173
|
-
)
|
|
39658
|
+
),
|
|
39659
|
+
{ mode: 384 }
|
|
39174
39660
|
);
|
|
39661
|
+
(0, import_node_fs6.chmodSync)(serverStatePath, 384);
|
|
39175
39662
|
}
|
|
39176
39663
|
removeRuntimeState() {
|
|
39177
39664
|
const path11 = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
@@ -39300,7 +39787,7 @@ async function createSigningChannel(projectRoot = process.cwd()) {
|
|
|
39300
39787
|
}
|
|
39301
39788
|
|
|
39302
39789
|
// src/commands/account.ts
|
|
39303
|
-
var SAIL_MAINNET_CHAINS = [1, 8453, 42161, 130];
|
|
39790
|
+
var SAIL_MAINNET_CHAINS = [1, 8453, 42161, 10, 130, 56, 480, 999, 4326];
|
|
39304
39791
|
async function fetchProxyCreationCode(preferredChainId) {
|
|
39305
39792
|
const rpcUrl = getRpcUrl(preferredChainId) ?? void 0;
|
|
39306
39793
|
const publicClient = createPublicClient({
|
|
@@ -40070,15 +40557,36 @@ var IPERMISSION_ABI = [
|
|
|
40070
40557
|
{ name: "selector", type: "bytes4" },
|
|
40071
40558
|
{ name: "value", type: "uint256" },
|
|
40072
40559
|
{ name: "blockTimestamp", type: "uint256" },
|
|
40073
|
-
{ name: "blockNumber", type: "uint256" }
|
|
40560
|
+
{ name: "blockNumber", type: "uint256" },
|
|
40561
|
+
{ name: "configEpoch", type: "uint256" }
|
|
40074
40562
|
]
|
|
40075
40563
|
}
|
|
40076
40564
|
],
|
|
40077
40565
|
outputs: [{ type: "bool" }]
|
|
40078
40566
|
}
|
|
40079
40567
|
];
|
|
40568
|
+
var REGISTRATION_EPOCH_ABI2 = [
|
|
40569
|
+
{
|
|
40570
|
+
type: "function",
|
|
40571
|
+
name: "registrationEpoch",
|
|
40572
|
+
stateMutability: "view",
|
|
40573
|
+
inputs: [
|
|
40574
|
+
{ name: "account", type: "address" },
|
|
40575
|
+
{ name: "permission", type: "address" }
|
|
40576
|
+
],
|
|
40577
|
+
outputs: [{ type: "uint256" }]
|
|
40578
|
+
}
|
|
40579
|
+
];
|
|
40580
|
+
async function readRegistrationEpoch(publicClient, kernel, account2, permission) {
|
|
40581
|
+
return await publicClient.readContract({
|
|
40582
|
+
address: kernel,
|
|
40583
|
+
abi: REGISTRATION_EPOCH_ABI2,
|
|
40584
|
+
functionName: "registrationEpoch",
|
|
40585
|
+
args: [account2, permission]
|
|
40586
|
+
});
|
|
40587
|
+
}
|
|
40080
40588
|
function buildPermissionContext(params) {
|
|
40081
|
-
const { account: account2, manager, call: call2, blockInfo } = params;
|
|
40589
|
+
const { account: account2, manager, call: call2, blockInfo, configEpoch } = params;
|
|
40082
40590
|
const selector = call2.data.length >= 10 ? call2.data.slice(0, 10) : "0x00000000";
|
|
40083
40591
|
return {
|
|
40084
40592
|
account: account2,
|
|
@@ -40089,12 +40597,23 @@ function buildPermissionContext(params) {
|
|
|
40089
40597
|
selector,
|
|
40090
40598
|
value: call2.value,
|
|
40091
40599
|
blockTimestamp: blockInfo.timestamp,
|
|
40092
|
-
blockNumber: blockInfo.number
|
|
40600
|
+
blockNumber: blockInfo.number,
|
|
40601
|
+
configEpoch
|
|
40093
40602
|
};
|
|
40094
40603
|
}
|
|
40095
40604
|
async function probePermissionForCall(params) {
|
|
40096
|
-
const { publicClient, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40097
|
-
|
|
40605
|
+
const { publicClient, kernel, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40606
|
+
let configEpoch;
|
|
40607
|
+
try {
|
|
40608
|
+
configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40609
|
+
} catch (err) {
|
|
40610
|
+
return {
|
|
40611
|
+
accepted: false,
|
|
40612
|
+
reverted: true,
|
|
40613
|
+
error: `could not read registrationEpoch from kernel ${kernel} (${err.message.split("\n")[0]})`
|
|
40614
|
+
};
|
|
40615
|
+
}
|
|
40616
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40098
40617
|
try {
|
|
40099
40618
|
const accepted = await publicClient.readContract({
|
|
40100
40619
|
address: permission,
|
|
@@ -40108,10 +40627,11 @@ async function probePermissionForCall(params) {
|
|
|
40108
40627
|
}
|
|
40109
40628
|
}
|
|
40110
40629
|
async function resolvePermissionForCall(params) {
|
|
40111
|
-
const { publicClient, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40112
|
-
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo });
|
|
40630
|
+
const { publicClient, kernel, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40113
40631
|
for (const permission of registeredPermissions) {
|
|
40114
40632
|
try {
|
|
40633
|
+
const configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40634
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40115
40635
|
const accepted = await publicClient.readContract({
|
|
40116
40636
|
address: permission,
|
|
40117
40637
|
abi: IPERMISSION_ABI,
|
|
@@ -40181,7 +40701,10 @@ async function probePassThrough(pc, permission, account2) {
|
|
|
40181
40701
|
selector: PROBE_SELECTOR,
|
|
40182
40702
|
value: 0n,
|
|
40183
40703
|
blockTimestamp: 0n,
|
|
40184
|
-
blockNumber: 0n
|
|
40704
|
+
blockNumber: 0n,
|
|
40705
|
+
// Pass-through probes only run on conjunctive kernels, which predate
|
|
40706
|
+
// registrationEpoch — there is no live epoch to read, so probe with 0.
|
|
40707
|
+
configEpoch: 0n
|
|
40185
40708
|
}
|
|
40186
40709
|
]
|
|
40187
40710
|
});
|
|
@@ -40357,7 +40880,7 @@ async function doctor(options = {}) {
|
|
|
40357
40880
|
console.log(`Account: ${safe}`);
|
|
40358
40881
|
if (stored?.saltNonce != null) {
|
|
40359
40882
|
const saltNonce = BigInt(stored.saltNonce);
|
|
40360
|
-
const MAINNET_CHAINS = [1, 8453, 42161, 130];
|
|
40883
|
+
const MAINNET_CHAINS = [1, 8453, 42161, 10, 130, 56, 480, 999, 4326];
|
|
40361
40884
|
try {
|
|
40362
40885
|
const proxyCreationCode = await pc.readContract({
|
|
40363
40886
|
address: SAFE_V141.proxyFactory,
|
|
@@ -40477,6 +41000,10 @@ struct Context {
|
|
|
40477
41000
|
uint256 value; // native ETH forwarded (wei)
|
|
40478
41001
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40479
41002
|
uint256 blockNumber; // block.number at dispatch
|
|
41003
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch;
|
|
41004
|
+
// configurable permissions fail closed on a mismatch with the
|
|
41005
|
+
// epoch stamped at configure() time. Custom permissions that
|
|
41006
|
+
// take no post-deploy configuration can ignore it.
|
|
40480
41007
|
}
|
|
40481
41008
|
|
|
40482
41009
|
/// @title IPermission
|
|
@@ -40512,6 +41039,8 @@ struct BatchContext {
|
|
|
40512
41039
|
bytes32 batchHash; // keccak256(abi.encode(calls)) \u2014 stable id for the exact sequence
|
|
40513
41040
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40514
41041
|
uint256 blockNumber; // block.number at dispatch
|
|
41042
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch \u2014
|
|
41043
|
+
// same fail-closed freshness check as Context.configEpoch
|
|
40515
41044
|
}
|
|
40516
41045
|
|
|
40517
41046
|
/// @title IBatchPermission
|
|
@@ -40675,21 +41204,18 @@ This folder is the local workspace for one Sailor agent deployment.
|
|
|
40675
41204
|
|
|
40676
41205
|
AI coding agents should read the project's \`AGENTS.md\` and this folder's \`config.json\`
|
|
40677
41206
|
before changing strategy code or running commands that touch funds.
|
|
40678
|
-
`;
|
|
40679
|
-
var CANONICAL_PKG = "@sail.money/sailor";
|
|
40680
|
-
|
|
40681
|
-
|
|
40682
|
-
|
|
40683
|
-
|
|
40684
|
-
|
|
40685
|
-
|
|
40686
|
-
|
|
40687
|
-
name: pkg.name ?? CANONICAL_PKG,
|
|
40688
|
-
version: pkg.version ?? "0.0.0"
|
|
40689
|
-
};
|
|
40690
|
-
} catch {
|
|
40691
|
-
return { name: CANONICAL_PKG, version: "0.0.0" };
|
|
41207
|
+
`;
|
|
41208
|
+
var CANONICAL_PKG = "@sail.money/sailor";
|
|
41209
|
+
function cliVersion() {
|
|
41210
|
+
const manifest = import_node_path8.default.join(packageRoot(), "package.json");
|
|
41211
|
+
let version4;
|
|
41212
|
+
try {
|
|
41213
|
+
version4 = JSON.parse(import_node_fs10.default.readFileSync(manifest, "utf-8")).version;
|
|
41214
|
+
} catch (err) {
|
|
41215
|
+
throw new Error(`Cannot read CLI package manifest at ${manifest}: ${err.message}`);
|
|
40692
41216
|
}
|
|
41217
|
+
if (!version4) throw new Error(`CLI package manifest at ${manifest} has no version`);
|
|
41218
|
+
return version4;
|
|
40693
41219
|
}
|
|
40694
41220
|
function scaffoldProjectWorkspace(dest, name, options) {
|
|
40695
41221
|
const chainId = options.chain ? (() => {
|
|
@@ -40816,30 +41342,12 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
|
|
|
40816
41342
|
}
|
|
40817
41343
|
})() : null;
|
|
40818
41344
|
copyDirSync(templateSrc, dest);
|
|
40819
|
-
if (options.skills === false) {
|
|
40820
|
-
import_node_fs10.default.rmSync(import_node_path8.default.join(dest, ".agents", "skills"), { recursive: true, force: true });
|
|
40821
|
-
}
|
|
40822
|
-
const pkgRoot = packageRoot();
|
|
40823
|
-
const examplesPermSrc = import_node_path8.default.join(pkgRoot, "examples", "permissions");
|
|
40824
|
-
if (import_node_fs10.default.existsSync(examplesPermSrc)) {
|
|
40825
|
-
copyDirSync(examplesPermSrc, import_node_path8.default.join(dest, "examples", "permissions"));
|
|
40826
|
-
}
|
|
40827
|
-
const customMandateSrc = import_node_path8.default.join(pkgRoot, "examples", "custom-mandate");
|
|
40828
|
-
if (import_node_fs10.default.existsSync(customMandateSrc)) {
|
|
40829
|
-
copyDirSync(customMandateSrc, import_node_path8.default.join(dest, "examples", "custom-mandate"));
|
|
40830
|
-
}
|
|
40831
|
-
const permModelSrc = import_node_path8.default.join(pkgRoot, "docs", "PERMISSION_MODEL.md");
|
|
40832
|
-
if (import_node_fs10.default.existsSync(permModelSrc)) {
|
|
40833
|
-
import_node_fs10.default.mkdirSync(import_node_path8.default.join(dest, "docs"), { recursive: true });
|
|
40834
|
-
writeIfMissing2(import_node_path8.default.join(dest, "docs", "PERMISSION_MODEL.md"), import_node_fs10.default.readFileSync(permModelSrc, "utf-8"));
|
|
40835
|
-
}
|
|
40836
41345
|
const pkgPath = import_node_path8.default.join(dest, "package.json");
|
|
40837
41346
|
if (import_node_fs10.default.existsSync(pkgPath)) {
|
|
40838
41347
|
const pkg = JSON.parse(import_node_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
40839
41348
|
pkg.name = name;
|
|
40840
41349
|
const devDeps = pkg.devDependencies ?? {};
|
|
40841
|
-
|
|
40842
|
-
devDeps[CANONICAL_PKG] = cliName === DEV_PKG ? `npm:${DEV_PKG}@^${cliVer}` : `^${cliVer}`;
|
|
41350
|
+
devDeps[CANONICAL_PKG] = `^${cliVersion()}`;
|
|
40843
41351
|
pkg.devDependencies = devDeps;
|
|
40844
41352
|
import_node_fs10.default.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
40845
41353
|
`);
|
|
@@ -40927,7 +41435,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40927
41435
|
console.log("Next:");
|
|
40928
41436
|
console.log(" sailor ui start");
|
|
40929
41437
|
console.log(" Connect your wallet and deploy your SMA in the browser.\n");
|
|
40930
|
-
console.log('Or open this folder in your AI coding
|
|
41438
|
+
console.log('Or open this folder in your AI coding agent and say: "continue"');
|
|
40931
41439
|
return;
|
|
40932
41440
|
}
|
|
40933
41441
|
if (state.kind === "C") {
|
|
@@ -40944,7 +41452,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40944
41452
|
console.log(" forge build");
|
|
40945
41453
|
console.log(` sailor mandate deploy --contract <Name> --attach --sma ${state.sma}
|
|
40946
41454
|
`);
|
|
40947
|
-
console.log('Or open this folder in your AI coding
|
|
41455
|
+
console.log('Or open this folder in your AI coding agent and say: "continue"');
|
|
40948
41456
|
return;
|
|
40949
41457
|
}
|
|
40950
41458
|
if (state.kind === "D") {
|
|
@@ -40953,7 +41461,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40953
41461
|
console.log(`SMA: ${state.sma} on ${state.chain}`);
|
|
40954
41462
|
console.log(`Permissions: ${state.permissionCount} registered
|
|
40955
41463
|
`);
|
|
40956
|
-
console.log('Open this folder in your AI coding
|
|
41464
|
+
console.log('Open this folder in your AI coding agent and say: "continue"');
|
|
40957
41465
|
return;
|
|
40958
41466
|
}
|
|
40959
41467
|
if (!inPlace) console.log(`
|
|
@@ -41099,13 +41607,13 @@ Added (new in template):`);
|
|
|
41099
41607
|
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
41100
41608
|
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
41101
41609
|
function readStdin() {
|
|
41102
|
-
return new Promise((
|
|
41610
|
+
return new Promise((resolve4, reject) => {
|
|
41103
41611
|
let data = "";
|
|
41104
41612
|
process.stdin.setEncoding("utf8");
|
|
41105
41613
|
process.stdin.on("data", (c) => {
|
|
41106
41614
|
data += c;
|
|
41107
41615
|
});
|
|
41108
|
-
process.stdin.on("end", () =>
|
|
41616
|
+
process.stdin.on("end", () => resolve4(data));
|
|
41109
41617
|
process.stdin.on("error", reject);
|
|
41110
41618
|
});
|
|
41111
41619
|
}
|
|
@@ -41413,6 +41921,22 @@ var MandateStore = class {
|
|
|
41413
41921
|
this.write(data);
|
|
41414
41922
|
return mandate2;
|
|
41415
41923
|
}
|
|
41924
|
+
/**
|
|
41925
|
+
* Track a permission only if no record at its address exists yet, returning the
|
|
41926
|
+
* record either way. Used by `mandate attach` for addresses that were never
|
|
41927
|
+
* deployed from this project — e.g. a shared permission singleton the operator
|
|
41928
|
+
* attaches by address. Without a store record, `recordAttachment` is a no-op and
|
|
41929
|
+
* the permission stays invisible to `mandate prepare`/`sign`. Unlike `add`, this
|
|
41930
|
+
* never overwrites an existing record (so richer deploy-time metadata such as
|
|
41931
|
+
* `sourcePath` is preserved). For attach-only records, `txHash`/`deployedAt`
|
|
41932
|
+
* reflect the registration/first-tracked moment, not an on-chain deployment.
|
|
41933
|
+
*/
|
|
41934
|
+
ensureTracked(mandate2) {
|
|
41935
|
+
const existing = this.read().mandates.find(
|
|
41936
|
+
(m) => m.address.toLowerCase() === mandate2.address.toLowerCase()
|
|
41937
|
+
);
|
|
41938
|
+
return existing ?? this.add(mandate2);
|
|
41939
|
+
}
|
|
41416
41940
|
/** Update mutable metadata fields on a tracked mandate (name, sourcePath, artifactPath). */
|
|
41417
41941
|
update(addressOrName, patch) {
|
|
41418
41942
|
const data = this.read();
|
|
@@ -42059,6 +42583,14 @@ function publicClientFor(project) {
|
|
|
42059
42583
|
transport: http(getRpcUrl(project.chainId))
|
|
42060
42584
|
}).extend(publicActions);
|
|
42061
42585
|
}
|
|
42586
|
+
function knownTemplateLabel(chainId, address) {
|
|
42587
|
+
try {
|
|
42588
|
+
const known = getSailDeployment(chainId).knownTemplates ?? [];
|
|
42589
|
+
return known.find((t) => t.address.toLowerCase() === address.toLowerCase())?.label;
|
|
42590
|
+
} catch {
|
|
42591
|
+
return void 0;
|
|
42592
|
+
}
|
|
42593
|
+
}
|
|
42062
42594
|
async function mandateDeploy(options) {
|
|
42063
42595
|
const project = requireProject();
|
|
42064
42596
|
const channel = await createSigningChannel(process.cwd());
|
|
@@ -42528,7 +43060,14 @@ async function runAttach(project, channel, options) {
|
|
|
42528
43060
|
label,
|
|
42529
43061
|
json
|
|
42530
43062
|
);
|
|
42531
|
-
|
|
43063
|
+
store.ensureTracked({
|
|
43064
|
+
name: label,
|
|
43065
|
+
address: mandateAddress,
|
|
43066
|
+
txHash,
|
|
43067
|
+
chainId: project.chainId,
|
|
43068
|
+
deployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43069
|
+
});
|
|
43070
|
+
store.recordAttachment(mandateAddress, { sma, txHash });
|
|
42532
43071
|
emit(json, () => {
|
|
42533
43072
|
}, {
|
|
42534
43073
|
status: "ok",
|
|
@@ -42542,7 +43081,14 @@ async function runAttachBatch(project, channel, options, sma, store) {
|
|
|
42542
43081
|
announceSigningUrl(json);
|
|
42543
43082
|
const txHash = await attachBatchToSma(project, channel, publicClient, sma, permissions, json);
|
|
42544
43083
|
for (const permission of permissions) {
|
|
42545
|
-
|
|
43084
|
+
store.ensureTracked({
|
|
43085
|
+
name: knownTemplateLabel(project.chainId, permission) ?? permission,
|
|
43086
|
+
address: permission,
|
|
43087
|
+
txHash,
|
|
43088
|
+
chainId: project.chainId,
|
|
43089
|
+
deployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43090
|
+
});
|
|
43091
|
+
store.recordAttachment(permission, { sma, txHash });
|
|
42546
43092
|
}
|
|
42547
43093
|
emit(json, () => {
|
|
42548
43094
|
}, {
|
|
@@ -43138,14 +43684,37 @@ async function trackedPermissionsFor(account2, chainId, kernel) {
|
|
|
43138
43684
|
};
|
|
43139
43685
|
});
|
|
43140
43686
|
const onChain = kernel ? await fetchOnChainPermissions(account2.safe, chainId, kernel) : null;
|
|
43141
|
-
if (onChain
|
|
43142
|
-
|
|
43143
|
-
|
|
43144
|
-
|
|
43145
|
-
|
|
43687
|
+
if (onChain === null) return local;
|
|
43688
|
+
return mergeOnChainPermissions(local, onChain, knownTemplateLabeler(chainId));
|
|
43689
|
+
}
|
|
43690
|
+
function mergeOnChainPermissions(local, onChain, labelFor = () => void 0) {
|
|
43691
|
+
for (const p of local) {
|
|
43692
|
+
if (p.registeredOnSma && !onChain.has(p.address.toLowerCase())) {
|
|
43693
|
+
p.revokedOnChain = true;
|
|
43694
|
+
}
|
|
43695
|
+
}
|
|
43696
|
+
const localAddrs = new Set(local.map((p) => p.address.toLowerCase()));
|
|
43697
|
+
const extra = [];
|
|
43698
|
+
for (const addr of onChain) {
|
|
43699
|
+
if (!localAddrs.has(addr)) {
|
|
43700
|
+
extra.push({
|
|
43701
|
+
address: addr,
|
|
43702
|
+
label: labelFor(addr) ?? `permission ${addr.slice(0, 10)}\u2026`,
|
|
43703
|
+
registeredOnSma: true
|
|
43704
|
+
});
|
|
43705
|
+
}
|
|
43706
|
+
}
|
|
43707
|
+
return [...local, ...extra];
|
|
43708
|
+
}
|
|
43709
|
+
function knownTemplateLabeler(chainId) {
|
|
43710
|
+
const map = /* @__PURE__ */ new Map();
|
|
43711
|
+
try {
|
|
43712
|
+
for (const t of getSailDeployment(chainId).knownTemplates ?? []) {
|
|
43713
|
+
map.set(t.address.toLowerCase(), t.label);
|
|
43146
43714
|
}
|
|
43715
|
+
} catch {
|
|
43147
43716
|
}
|
|
43148
|
-
return
|
|
43717
|
+
return (addr) => map.get(addr.toLowerCase());
|
|
43149
43718
|
}
|
|
43150
43719
|
function printNoPermissionsGuidance() {
|
|
43151
43720
|
console.log(
|
|
@@ -43267,8 +43836,451 @@ ${unregistered.length} permission(s) are not yet registered on this SMA. Initiat
|
|
|
43267
43836
|
\u2713 Saved to .sail/mandate.json \u2014 agent is ready to run.`);
|
|
43268
43837
|
}
|
|
43269
43838
|
|
|
43270
|
-
// src/commands/mandate-
|
|
43839
|
+
// src/commands/mandate-configure.ts
|
|
43271
43840
|
var import_node_fs15 = require("node:fs");
|
|
43841
|
+
var import_node_path13 = require("node:path");
|
|
43842
|
+
|
|
43843
|
+
// ../sdk/dist/templates/boundedSwap.js
|
|
43844
|
+
init_esm2();
|
|
43845
|
+
var ABI = [
|
|
43846
|
+
{ name: "routers", type: "address[]" },
|
|
43847
|
+
{ name: "tokensIn", type: "address[]" },
|
|
43848
|
+
{ name: "tokensOut", type: "address[]" },
|
|
43849
|
+
{ name: "maxAmountPerTx", type: "uint256" },
|
|
43850
|
+
{ name: "maxSlippageBps", type: "uint256" },
|
|
43851
|
+
{ name: "priceOracle", type: "address" },
|
|
43852
|
+
{ name: "maxPriceAgeSec", type: "uint256" }
|
|
43853
|
+
];
|
|
43854
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
43855
|
+
var boundedSwapTemplate = {
|
|
43856
|
+
name: "SharedBoundedSwapPermission",
|
|
43857
|
+
address: "0x0000000000000000000000000000000000000000",
|
|
43858
|
+
encoder: {
|
|
43859
|
+
encode(params) {
|
|
43860
|
+
return encodeAbiParameters(ABI, [
|
|
43861
|
+
params.routers,
|
|
43862
|
+
params.tokensIn,
|
|
43863
|
+
params.tokensOut,
|
|
43864
|
+
params.maxAmountPerTx,
|
|
43865
|
+
BigInt(params.maxSlippageBps),
|
|
43866
|
+
params.priceOracle,
|
|
43867
|
+
BigInt(params.maxPriceAgeSec)
|
|
43868
|
+
]);
|
|
43869
|
+
},
|
|
43870
|
+
decode(data) {
|
|
43871
|
+
const decoded = decodeAbiParameters(ABI, data);
|
|
43872
|
+
return {
|
|
43873
|
+
routers: [...decoded[0]],
|
|
43874
|
+
tokensIn: [...decoded[1]],
|
|
43875
|
+
tokensOut: [...decoded[2]],
|
|
43876
|
+
maxAmountPerTx: decoded[3],
|
|
43877
|
+
maxSlippageBps: Number(decoded[4]),
|
|
43878
|
+
priceOracle: decoded[5],
|
|
43879
|
+
maxPriceAgeSec: Number(decoded[6])
|
|
43880
|
+
};
|
|
43881
|
+
}
|
|
43882
|
+
},
|
|
43883
|
+
explainer: {
|
|
43884
|
+
explain(params) {
|
|
43885
|
+
const warnings = [];
|
|
43886
|
+
if (params.maxSlippageBps > 100) {
|
|
43887
|
+
warnings.push(`High slippage tolerance: ${params.maxSlippageBps / 100}%`);
|
|
43888
|
+
}
|
|
43889
|
+
if (params.priceOracle === ZERO_ADDRESS) {
|
|
43890
|
+
warnings.push("No price oracle configured \u2014 swaps are not checked against a reference price");
|
|
43891
|
+
}
|
|
43892
|
+
return {
|
|
43893
|
+
templateName: "SharedBoundedSwapPermission",
|
|
43894
|
+
humanReadable: [
|
|
43895
|
+
`Maximum input per swap: ${params.maxAmountPerTx.toString()} (input-token base units)`,
|
|
43896
|
+
`Maximum slippage: ${params.maxSlippageBps / 100}%`,
|
|
43897
|
+
`Allowed routers: ${params.routers.join(", ")}`,
|
|
43898
|
+
`Allowed input tokens: ${params.tokensIn.join(", ")}`,
|
|
43899
|
+
`Allowed output tokens: ${params.tokensOut.join(", ")}`,
|
|
43900
|
+
params.priceOracle === ZERO_ADDRESS ? "Price oracle: none" : `Price oracle: ${params.priceOracle} (max age ${params.maxPriceAgeSec}s)`
|
|
43901
|
+
],
|
|
43902
|
+
warnings
|
|
43903
|
+
};
|
|
43904
|
+
}
|
|
43905
|
+
}
|
|
43906
|
+
};
|
|
43907
|
+
|
|
43908
|
+
// src/commands/mandate-configure.ts
|
|
43909
|
+
init_esm2();
|
|
43910
|
+
var TEMPLATE_REGISTRY = {
|
|
43911
|
+
SwapPermission: {
|
|
43912
|
+
label: "Bounded Swap (Uniswap V3)",
|
|
43913
|
+
bigintFields: ["maxAmountPerTx"],
|
|
43914
|
+
encode: (raw) => boundedSwapTemplate.encoder.encode(coerceSwapParams(raw)),
|
|
43915
|
+
decode: (blob) => {
|
|
43916
|
+
const p = boundedSwapTemplate.encoder.decode(blob);
|
|
43917
|
+
return {
|
|
43918
|
+
routers: p.routers,
|
|
43919
|
+
tokensIn: p.tokensIn,
|
|
43920
|
+
tokensOut: p.tokensOut,
|
|
43921
|
+
maxAmountPerTx: p.maxAmountPerTx.toString(),
|
|
43922
|
+
maxSlippageBps: p.maxSlippageBps,
|
|
43923
|
+
priceOracle: p.priceOracle,
|
|
43924
|
+
maxPriceAgeSec: p.maxPriceAgeSec
|
|
43925
|
+
};
|
|
43926
|
+
}
|
|
43927
|
+
}
|
|
43928
|
+
};
|
|
43929
|
+
function asAddressArray(v, field) {
|
|
43930
|
+
if (!Array.isArray(v)) throw new Error(`${field}: expected an array of addresses`);
|
|
43931
|
+
return v.map((x, i) => {
|
|
43932
|
+
if (typeof x !== "string" || !isAddress(x, { strict: false })) {
|
|
43933
|
+
throw new Error(`${field}[${i}]: invalid address "${String(x)}"`);
|
|
43934
|
+
}
|
|
43935
|
+
return getAddress(x);
|
|
43936
|
+
});
|
|
43937
|
+
}
|
|
43938
|
+
function asAddress(v, field) {
|
|
43939
|
+
if (typeof v !== "string" || !isAddress(v, { strict: false })) {
|
|
43940
|
+
throw new Error(`${field}: invalid address "${String(v)}"`);
|
|
43941
|
+
}
|
|
43942
|
+
return getAddress(v);
|
|
43943
|
+
}
|
|
43944
|
+
function asUint(v, field) {
|
|
43945
|
+
if (v === void 0 || v === null) throw new Error(`${field}: missing`);
|
|
43946
|
+
try {
|
|
43947
|
+
return BigInt(typeof v === "string" || typeof v === "number" ? v : String(v));
|
|
43948
|
+
} catch {
|
|
43949
|
+
throw new Error(`${field}: expected an integer, got "${String(v)}"`);
|
|
43950
|
+
}
|
|
43951
|
+
}
|
|
43952
|
+
function asInt(v, field) {
|
|
43953
|
+
const n = asUint(v, field);
|
|
43954
|
+
return Number(n);
|
|
43955
|
+
}
|
|
43956
|
+
function coerceSwapParams(raw) {
|
|
43957
|
+
return {
|
|
43958
|
+
routers: asAddressArray(raw.routers, "routers"),
|
|
43959
|
+
tokensIn: asAddressArray(raw.tokensIn, "tokensIn"),
|
|
43960
|
+
tokensOut: asAddressArray(raw.tokensOut, "tokensOut"),
|
|
43961
|
+
maxAmountPerTx: asUint(raw.maxAmountPerTx, "maxAmountPerTx"),
|
|
43962
|
+
maxSlippageBps: asInt(raw.maxSlippageBps, "maxSlippageBps"),
|
|
43963
|
+
priceOracle: asAddress(raw.priceOracle, "priceOracle"),
|
|
43964
|
+
maxPriceAgeSec: asInt(raw.maxPriceAgeSec, "maxPriceAgeSec")
|
|
43965
|
+
};
|
|
43966
|
+
}
|
|
43967
|
+
function requireProject2() {
|
|
43968
|
+
if (!ProjectContext.exists()) {
|
|
43969
|
+
console.log('No Sailor project found. Run "sailor init" first.');
|
|
43970
|
+
process.exit(1);
|
|
43971
|
+
}
|
|
43972
|
+
return new ProjectContext();
|
|
43973
|
+
}
|
|
43974
|
+
function fail2(err, json = false) {
|
|
43975
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43976
|
+
emit(json, () => console.error(`
|
|
43977
|
+
Mandate configure failed: ${msg}`), {
|
|
43978
|
+
status: "error",
|
|
43979
|
+
error: msg
|
|
43980
|
+
});
|
|
43981
|
+
process.exit(1);
|
|
43982
|
+
}
|
|
43983
|
+
function publicClientFor2(project) {
|
|
43984
|
+
return createPublicClient({
|
|
43985
|
+
chain: getChainById(project.chainId),
|
|
43986
|
+
transport: http(getRpcUrl(project.chainId))
|
|
43987
|
+
}).extend(publicActions);
|
|
43988
|
+
}
|
|
43989
|
+
function announceSigningUrl2(json) {
|
|
43990
|
+
const url = signingPageUrl(projectPort(process.cwd()));
|
|
43991
|
+
if (json) {
|
|
43992
|
+
process.stdout.write(`${JSON.stringify({ status: "waiting_for_signature", url })}
|
|
43993
|
+
`);
|
|
43994
|
+
} else {
|
|
43995
|
+
console.log(`
|
|
43996
|
+
\u2192 Open the Sailor dashboard to approve signing requests:
|
|
43997
|
+
${url}
|
|
43998
|
+
`);
|
|
43999
|
+
}
|
|
44000
|
+
}
|
|
44001
|
+
function resolveBlob(options) {
|
|
44002
|
+
const hasParams = options.params !== void 0;
|
|
44003
|
+
const hasArgsFile = options.argsFile !== void 0;
|
|
44004
|
+
if (hasParams && hasArgsFile) {
|
|
44005
|
+
throw new Error("Provide EITHER --params <hex> OR --args-file <path>, not both.");
|
|
44006
|
+
}
|
|
44007
|
+
if (!hasParams && !hasArgsFile) {
|
|
44008
|
+
throw new Error(
|
|
44009
|
+
"Provide the config blob as --params <0x-hex>, or as --args-file <path> paired with --template <Name>."
|
|
44010
|
+
);
|
|
44011
|
+
}
|
|
44012
|
+
if (hasParams) {
|
|
44013
|
+
const raw2 = options.params.trim();
|
|
44014
|
+
if (!isHex(raw2) || raw2.length <= 2) {
|
|
44015
|
+
throw new Error(`--params must be 0x-prefixed hex; got "${options.params}".`);
|
|
44016
|
+
}
|
|
44017
|
+
return { blob: raw2, via: "params" };
|
|
44018
|
+
}
|
|
44019
|
+
const templateName = options.template;
|
|
44020
|
+
if (!templateName) {
|
|
44021
|
+
throw new Error("--args-file requires --template <Name> (e.g. SwapPermission).");
|
|
44022
|
+
}
|
|
44023
|
+
const entry = TEMPLATE_REGISTRY[templateName];
|
|
44024
|
+
if (!entry) {
|
|
44025
|
+
throw new Error(
|
|
44026
|
+
`Unknown --template "${templateName}". Known: ${Object.keys(TEMPLATE_REGISTRY).join(", ")}. Pass a pre-encoded blob with --params for any other template.`
|
|
44027
|
+
);
|
|
44028
|
+
}
|
|
44029
|
+
const argsFilePath = (0, import_node_path13.resolve)(options.argsFile);
|
|
44030
|
+
let raw;
|
|
44031
|
+
try {
|
|
44032
|
+
raw = (0, import_node_fs15.readFileSync)(argsFilePath, "utf8").trim();
|
|
44033
|
+
} catch {
|
|
44034
|
+
throw new Error(`Cannot read --args-file: ${argsFilePath}`);
|
|
44035
|
+
}
|
|
44036
|
+
let parsed;
|
|
44037
|
+
try {
|
|
44038
|
+
parsed = JSON.parse(raw);
|
|
44039
|
+
} catch (err) {
|
|
44040
|
+
throw new Error(`--args-file is not valid JSON: ${err.message}`);
|
|
44041
|
+
}
|
|
44042
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
44043
|
+
throw new Error("--args-file must contain a JSON object of template params.");
|
|
44044
|
+
}
|
|
44045
|
+
const blob = entry.encode(parsed);
|
|
44046
|
+
return { blob, via: `template:${templateName}` };
|
|
44047
|
+
}
|
|
44048
|
+
async function mandateConfigure(options) {
|
|
44049
|
+
const project = requireProject2();
|
|
44050
|
+
const channel = await createSigningChannel(process.cwd());
|
|
44051
|
+
try {
|
|
44052
|
+
await channel.start();
|
|
44053
|
+
await runConfigure(project, channel, options);
|
|
44054
|
+
} catch (err) {
|
|
44055
|
+
fail2(err, options.json);
|
|
44056
|
+
} finally {
|
|
44057
|
+
channel.stop();
|
|
44058
|
+
}
|
|
44059
|
+
}
|
|
44060
|
+
async function runConfigure(project, channel, options) {
|
|
44061
|
+
const json = !!options.json;
|
|
44062
|
+
const say = (fn) => {
|
|
44063
|
+
if (!json) fn();
|
|
44064
|
+
};
|
|
44065
|
+
if (!isAddress(options.sma, { strict: false })) {
|
|
44066
|
+
throw new Error(`Invalid --sma address: ${options.sma}`);
|
|
44067
|
+
}
|
|
44068
|
+
if (!isAddress(options.address, { strict: false })) {
|
|
44069
|
+
throw new Error(
|
|
44070
|
+
`--address must be a deployed shared-template singleton address: ${options.address}`
|
|
44071
|
+
);
|
|
44072
|
+
}
|
|
44073
|
+
const sma = getAddress(options.sma);
|
|
44074
|
+
const singleton = getAddress(options.address);
|
|
44075
|
+
const { blob, via } = resolveBlob(options);
|
|
44076
|
+
const publicClient = publicClientFor2(project);
|
|
44077
|
+
const registered = await publicClient.readContract({
|
|
44078
|
+
address: project.contracts.kernel,
|
|
44079
|
+
abi: SailKernelAbi,
|
|
44080
|
+
functionName: "registered",
|
|
44081
|
+
args: [sma]
|
|
44082
|
+
});
|
|
44083
|
+
if (!registered) {
|
|
44084
|
+
throw new Error(`SMA ${sma} is not registered with SailKernel; cannot configure a permission for it.`);
|
|
44085
|
+
}
|
|
44086
|
+
const kernelConfig = await publicClient.readContract({
|
|
44087
|
+
address: project.contracts.kernel,
|
|
44088
|
+
abi: SailKernelAbi,
|
|
44089
|
+
functionName: "configs",
|
|
44090
|
+
args: [sma]
|
|
44091
|
+
});
|
|
44092
|
+
const permissionSigner = kernelConfig[0];
|
|
44093
|
+
if (!permissionSigner || permissionSigner === getAddress("0x0000000000000000000000000000000000000000")) {
|
|
44094
|
+
throw new Error(`SMA ${sma} has no on-chain permissionSigner; cannot configure.`);
|
|
44095
|
+
}
|
|
44096
|
+
const alreadyConfigured = await publicClient.readContract({
|
|
44097
|
+
address: singleton,
|
|
44098
|
+
abi: ConfigurablePermissionAbi,
|
|
44099
|
+
functionName: "isConfigured",
|
|
44100
|
+
args: [sma]
|
|
44101
|
+
});
|
|
44102
|
+
if (alreadyConfigured && !options.force) {
|
|
44103
|
+
say(
|
|
44104
|
+
() => console.log(
|
|
44105
|
+
`
|
|
44106
|
+
\u2713 ${singleton} is already configured for ${sma} (isConfigured == true).
|
|
44107
|
+
Re-run with --force to overwrite the current bounds.`
|
|
44108
|
+
)
|
|
44109
|
+
);
|
|
44110
|
+
emit(
|
|
44111
|
+
json,
|
|
44112
|
+
() => {
|
|
44113
|
+
},
|
|
44114
|
+
{ status: "ok", alreadyConfigured: true, singleton, sma, chainId: project.chainId }
|
|
44115
|
+
);
|
|
44116
|
+
return;
|
|
44117
|
+
}
|
|
44118
|
+
const nonce = await publicClient.readContract({
|
|
44119
|
+
address: singleton,
|
|
44120
|
+
abi: ConfigurablePermissionAbi,
|
|
44121
|
+
functionName: "configNonces",
|
|
44122
|
+
args: [sma]
|
|
44123
|
+
});
|
|
44124
|
+
say(() => {
|
|
44125
|
+
console.log(`
|
|
44126
|
+
configure ${singleton}`);
|
|
44127
|
+
console.log(` SMA: ${sma}`);
|
|
44128
|
+
console.log(` permissionSigner: ${permissionSigner} (must sign in the browser \u2014 owner tx)`);
|
|
44129
|
+
console.log(` current nonce: ${nonce}`);
|
|
44130
|
+
console.log(` already set: ${alreadyConfigured ? "yes (--force will overwrite)" : "no"}`);
|
|
44131
|
+
console.log(` config blob: ${blob} (via ${via}, ${Math.floor((blob.length - 2) / 2)} bytes)`);
|
|
44132
|
+
});
|
|
44133
|
+
const configureDirectData = encodeFunctionData({
|
|
44134
|
+
abi: ConfigurablePermissionAbi,
|
|
44135
|
+
functionName: "configureDirect",
|
|
44136
|
+
args: [sma, blob]
|
|
44137
|
+
});
|
|
44138
|
+
say(() => console.log(`
|
|
44139
|
+
Pre-flight (eth_call of configureDirect, no gas)\u2026`));
|
|
44140
|
+
try {
|
|
44141
|
+
await publicClient.simulateContract({
|
|
44142
|
+
address: singleton,
|
|
44143
|
+
abi: ConfigurablePermissionAbi,
|
|
44144
|
+
functionName: "configureDirect",
|
|
44145
|
+
args: [sma, blob],
|
|
44146
|
+
account: permissionSigner
|
|
44147
|
+
});
|
|
44148
|
+
} catch (err) {
|
|
44149
|
+
const ce = getContractError(err, {
|
|
44150
|
+
abi: ConfigurablePermissionAbi,
|
|
44151
|
+
address: singleton,
|
|
44152
|
+
args: [sma, blob],
|
|
44153
|
+
functionName: "configureDirect"
|
|
44154
|
+
});
|
|
44155
|
+
const reason = ce?.message ?? err?.message ?? String(err);
|
|
44156
|
+
throw new Error(
|
|
44157
|
+
`Pre-flight reverted \u2014 the config blob is invalid for ${singleton} on ${sma}.
|
|
44158
|
+
Revert: ${reason}
|
|
44159
|
+
This is the encoding gotcha (flat params vs wrapped struct) or an internal bound check. Re-encode per the template's _applyConfig tuple and retry.`
|
|
44160
|
+
);
|
|
44161
|
+
}
|
|
44162
|
+
say(() => console.log("\u2713 pre-flight passed (configureDirect would succeed)."));
|
|
44163
|
+
let decoded;
|
|
44164
|
+
if (options.template && TEMPLATE_REGISTRY[options.template]) {
|
|
44165
|
+
try {
|
|
44166
|
+
decoded = TEMPLATE_REGISTRY[options.template].decode(blob);
|
|
44167
|
+
say(() => {
|
|
44168
|
+
console.log("\nDecoded bounds (what the singleton will store):");
|
|
44169
|
+
for (const [k, v] of Object.entries(decoded)) {
|
|
44170
|
+
const display = Array.isArray(v) ? v.join(", ") : String(v);
|
|
44171
|
+
console.log(` ${k}: ${display}`);
|
|
44172
|
+
}
|
|
44173
|
+
});
|
|
44174
|
+
} catch {
|
|
44175
|
+
}
|
|
44176
|
+
}
|
|
44177
|
+
if (options.simulateOnly) {
|
|
44178
|
+
emit(
|
|
44179
|
+
json,
|
|
44180
|
+
() => {
|
|
44181
|
+
console.log("\n--simulate-only: stopping after pre-flight (no signing, no gas).");
|
|
44182
|
+
},
|
|
44183
|
+
{
|
|
44184
|
+
status: "ok",
|
|
44185
|
+
simulateOnly: true,
|
|
44186
|
+
singleton,
|
|
44187
|
+
sma,
|
|
44188
|
+
permissionSigner,
|
|
44189
|
+
nonce: nonce.toString(),
|
|
44190
|
+
alreadyConfigured,
|
|
44191
|
+
blob,
|
|
44192
|
+
blobBytes: Math.floor((blob.length - 2) / 2),
|
|
44193
|
+
decoded,
|
|
44194
|
+
chainId: project.chainId
|
|
44195
|
+
}
|
|
44196
|
+
);
|
|
44197
|
+
return;
|
|
44198
|
+
}
|
|
44199
|
+
const label = options.label ?? (options.template ?? "shared-template");
|
|
44200
|
+
announceSigningUrl2(json);
|
|
44201
|
+
say(
|
|
44202
|
+
() => console.log(
|
|
44203
|
+
`Pushing configure request \u2014 the mandate signer (${permissionSigner}) must approve in the browser\u2026`
|
|
44204
|
+
)
|
|
44205
|
+
);
|
|
44206
|
+
const response = await channel.requestSignature({
|
|
44207
|
+
type: "transaction",
|
|
44208
|
+
kind: "arbitrary-tx",
|
|
44209
|
+
title: `Configure "${label}"`,
|
|
44210
|
+
description: `Write per-account bounds on the shared permission ${singleton}.
|
|
44211
|
+
You (the mandate signer) send the transaction \u2014 configureDirect requires msg.sender to be the permissionSigner.`,
|
|
44212
|
+
chainId: project.chainId,
|
|
44213
|
+
to: singleton,
|
|
44214
|
+
data: configureDirectData,
|
|
44215
|
+
details: [
|
|
44216
|
+
{ label: "SMA", value: sma },
|
|
44217
|
+
{ label: "Singleton", value: singleton },
|
|
44218
|
+
{ label: "Template", value: options.template ?? "(raw blob)" },
|
|
44219
|
+
{ label: "Mandate signer", value: permissionSigner },
|
|
44220
|
+
{ label: "Config blob (bytes)", value: String(Math.floor((blob.length - 2) / 2)) },
|
|
44221
|
+
...decoded ? Object.entries(decoded).map(([k, v]) => ({
|
|
44222
|
+
label: k,
|
|
44223
|
+
value: Array.isArray(v) ? v.join(", ") : String(v)
|
|
44224
|
+
})) : []
|
|
44225
|
+
]
|
|
44226
|
+
});
|
|
44227
|
+
if (response.status === "rejected") {
|
|
44228
|
+
throw new Error(`User rejected configure: ${response.reason ?? "no reason given"}`);
|
|
44229
|
+
}
|
|
44230
|
+
if (response.status !== "signed") {
|
|
44231
|
+
throw new Error(`Expected a signed transaction, got: ${response.status}`);
|
|
44232
|
+
}
|
|
44233
|
+
say(() => console.log("Waiting for confirmation\u2026"));
|
|
44234
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: response.txHash });
|
|
44235
|
+
if (receipt.status !== "success") {
|
|
44236
|
+
throw new Error(`configureDirect transaction failed (tx ${response.txHash})`);
|
|
44237
|
+
}
|
|
44238
|
+
const configuredNow = await publicClient.readContract({
|
|
44239
|
+
address: singleton,
|
|
44240
|
+
abi: ConfigurablePermissionAbi,
|
|
44241
|
+
functionName: "isConfigured",
|
|
44242
|
+
args: [sma]
|
|
44243
|
+
});
|
|
44244
|
+
if (!configuredNow) {
|
|
44245
|
+
throw new Error(
|
|
44246
|
+
`Tx ${response.txHash} mined, but isConfigured(${sma}) is still false. Verify on-chain.`
|
|
44247
|
+
);
|
|
44248
|
+
}
|
|
44249
|
+
say(() => console.log("\u2713", `Configured ${singleton} for ${sma} (isConfigured == true).`));
|
|
44250
|
+
appendActivity({
|
|
44251
|
+
ts: nowIso(),
|
|
44252
|
+
actor: "owner",
|
|
44253
|
+
type: "permission_configured",
|
|
44254
|
+
permission: singleton,
|
|
44255
|
+
name: label,
|
|
44256
|
+
sma,
|
|
44257
|
+
txHash: response.txHash,
|
|
44258
|
+
chainId: project.chainId
|
|
44259
|
+
});
|
|
44260
|
+
emit(
|
|
44261
|
+
json,
|
|
44262
|
+
() => {
|
|
44263
|
+
console.log(
|
|
44264
|
+
`
|
|
44265
|
+
Next: prove it accepts/rejects the right calls before dispatching:
|
|
44266
|
+
sailor mandate simulate --address ${singleton} --sma ${sma} --calls ./probe.json`
|
|
44267
|
+
);
|
|
44268
|
+
},
|
|
44269
|
+
{
|
|
44270
|
+
status: "ok",
|
|
44271
|
+
singleton,
|
|
44272
|
+
sma,
|
|
44273
|
+
template: options.template,
|
|
44274
|
+
permissionSigner,
|
|
44275
|
+
txHash: response.txHash,
|
|
44276
|
+
blob,
|
|
44277
|
+
chainId: project.chainId
|
|
44278
|
+
}
|
|
44279
|
+
);
|
|
44280
|
+
}
|
|
44281
|
+
|
|
44282
|
+
// src/commands/mandate-simulate.ts
|
|
44283
|
+
var import_node_fs16 = require("node:fs");
|
|
43272
44284
|
init_esm2();
|
|
43273
44285
|
function parseExpect(raw, where) {
|
|
43274
44286
|
if (raw === void 0) return void 0;
|
|
@@ -43284,7 +44296,7 @@ function resolveSampleCalls(options) {
|
|
|
43284
44296
|
if (options.calls) {
|
|
43285
44297
|
let raw;
|
|
43286
44298
|
try {
|
|
43287
|
-
raw = JSON.parse((0,
|
|
44299
|
+
raw = JSON.parse((0, import_node_fs16.readFileSync)(options.calls, "utf8"));
|
|
43288
44300
|
} catch (err) {
|
|
43289
44301
|
throw new Error(`Could not read --calls file "${options.calls}": ${err.message}`);
|
|
43290
44302
|
}
|
|
@@ -43388,6 +44400,7 @@ async function mandateSimulate(options) {
|
|
|
43388
44400
|
const [probe, codeCheck] = await Promise.all([
|
|
43389
44401
|
probePermissionForCall({
|
|
43390
44402
|
publicClient: pc,
|
|
44403
|
+
kernel: project.contracts.kernel,
|
|
43391
44404
|
permission,
|
|
43392
44405
|
account: account2,
|
|
43393
44406
|
manager,
|
|
@@ -43500,7 +44513,7 @@ async function mandateSimulate(options) {
|
|
|
43500
44513
|
}
|
|
43501
44514
|
|
|
43502
44515
|
// src/commands/rotate-signer.ts
|
|
43503
|
-
var
|
|
44516
|
+
var import_node_fs17 = require("node:fs");
|
|
43504
44517
|
init_esm2();
|
|
43505
44518
|
var PENDING_REATTACH_FILE = ["state", "pending-reattach.json"];
|
|
43506
44519
|
async function rotateSigner(options) {
|
|
@@ -43886,7 +44899,7 @@ ensure the agent that signs dispatches holds this key.`
|
|
|
43886
44899
|
const keystore = await keyring.exportKeystore(password);
|
|
43887
44900
|
writeJsonFile(target, keystore, 384);
|
|
43888
44901
|
const perManagerPath = managerKeystorePath(keyring.address);
|
|
43889
|
-
(0,
|
|
44902
|
+
(0, import_node_fs17.mkdirSync)(sailPath("keys", "managers"), { recursive: true });
|
|
43890
44903
|
writeJsonFile(perManagerPath, keystore, 384);
|
|
43891
44904
|
say(
|
|
43892
44905
|
() => console.log(
|
|
@@ -43898,7 +44911,7 @@ ensure the agent that signs dispatches holds this key.`
|
|
|
43898
44911
|
function promoteManagerKeystore(newManager, say) {
|
|
43899
44912
|
const stored = readJsonFile(managerKeystorePath(newManager));
|
|
43900
44913
|
if (!stored) return;
|
|
43901
|
-
(0,
|
|
44914
|
+
(0, import_node_fs17.mkdirSync)(sailPath("keys", "managers"), { recursive: true });
|
|
43902
44915
|
const activeTarget = keyPath("manager");
|
|
43903
44916
|
const displaced = readJsonFile(activeTarget);
|
|
43904
44917
|
if (displaced?.address) {
|
|
@@ -43950,7 +44963,7 @@ function writePending(pending) {
|
|
|
43950
44963
|
}
|
|
43951
44964
|
function clearPending() {
|
|
43952
44965
|
try {
|
|
43953
|
-
(0,
|
|
44966
|
+
(0, import_node_fs17.rmSync)(sailPath(...PENDING_REATTACH_FILE), { force: true });
|
|
43954
44967
|
} catch {
|
|
43955
44968
|
}
|
|
43956
44969
|
}
|
|
@@ -44049,12 +45062,12 @@ function ownerShow(options) {
|
|
|
44049
45062
|
}
|
|
44050
45063
|
|
|
44051
45064
|
// src/commands/run.ts
|
|
44052
|
-
var
|
|
44053
|
-
var
|
|
45065
|
+
var import_node_fs18 = __toESM(require("node:fs"), 1);
|
|
45066
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
44054
45067
|
var import_node_url = require("node:url");
|
|
44055
45068
|
init_esm2();
|
|
44056
45069
|
var DEFAULT_INTERVAL_SEC = 60;
|
|
44057
|
-
var sleep2 = (ms) => new Promise((
|
|
45070
|
+
var sleep2 = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
44058
45071
|
var ERC20_READ_ABI = [
|
|
44059
45072
|
{
|
|
44060
45073
|
type: "function",
|
|
@@ -44084,7 +45097,7 @@ var ERC20_READ_ABI = [
|
|
|
44084
45097
|
function loadAgentData(filePath) {
|
|
44085
45098
|
if (!filePath) return {};
|
|
44086
45099
|
try {
|
|
44087
|
-
const parsed = JSON.parse(
|
|
45100
|
+
const parsed = JSON.parse(import_node_fs18.default.readFileSync(filePath, "utf-8"));
|
|
44088
45101
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
44089
45102
|
} catch {
|
|
44090
45103
|
return {};
|
|
@@ -44093,8 +45106,8 @@ function loadAgentData(filePath) {
|
|
|
44093
45106
|
async function loadAgent() {
|
|
44094
45107
|
const candidates = ["src/agent.ts", "src/agent.js", "dist/agent.js", "dist/src/agent.js"];
|
|
44095
45108
|
for (const rel of candidates) {
|
|
44096
|
-
const abs =
|
|
44097
|
-
if (!
|
|
45109
|
+
const abs = import_node_path14.default.join(process.cwd(), rel);
|
|
45110
|
+
if (!import_node_fs18.default.existsSync(abs)) continue;
|
|
44098
45111
|
let mod2;
|
|
44099
45112
|
if (abs.endsWith(".ts")) {
|
|
44100
45113
|
const { tsImport } = await import("tsx/esm/api");
|
|
@@ -44347,6 +45360,8 @@ Configure the chain in the SDK chain registry or set KERNEL_ADDRESS in .sail/.en
|
|
|
44347
45360
|
} else {
|
|
44348
45361
|
permission = await resolvePermissionForCall({
|
|
44349
45362
|
publicClient,
|
|
45363
|
+
kernel,
|
|
45364
|
+
// narrowed: runCommand validates kernel before runTick runs
|
|
44350
45365
|
account: accountAddr,
|
|
44351
45366
|
manager: agentManager.address,
|
|
44352
45367
|
call: firstCall,
|
|
@@ -44389,7 +45404,7 @@ Configure the chain in the SDK chain registry or set KERNEL_ADDRESS in .sail/.en
|
|
|
44389
45404
|
if (isConjunctive && result.txHash) {
|
|
44390
45405
|
try {
|
|
44391
45406
|
await publicClient.waitForTransactionReceipt({ hash: result.txHash, timeout: 3e4 });
|
|
44392
|
-
await new Promise((
|
|
45407
|
+
await new Promise((resolve4) => setTimeout(resolve4, 500));
|
|
44393
45408
|
} catch {
|
|
44394
45409
|
}
|
|
44395
45410
|
}
|
|
@@ -44522,7 +45537,7 @@ async function scan(options) {
|
|
|
44522
45537
|
args: [address]
|
|
44523
45538
|
})
|
|
44524
45539
|
]);
|
|
44525
|
-
const [permissionSigner, manager, , sessionActive] = config;
|
|
45540
|
+
const [permissionSigner, manager, , , sessionActive] = config;
|
|
44526
45541
|
smas.push({ address, registered: true, manager, permissionSigner, sessionActive, mandates });
|
|
44527
45542
|
} catch (err) {
|
|
44528
45543
|
smas.push({
|
|
@@ -44570,9 +45585,9 @@ async function scan(options) {
|
|
|
44570
45585
|
|
|
44571
45586
|
// src/commands/service.ts
|
|
44572
45587
|
var import_node_child_process2 = require("node:child_process");
|
|
44573
|
-
var
|
|
45588
|
+
var import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
44574
45589
|
var import_node_os = __toESM(require("node:os"), 1);
|
|
44575
|
-
var
|
|
45590
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
44576
45591
|
function sanitizeName(raw) {
|
|
44577
45592
|
const s = raw.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
44578
45593
|
return s || "agent";
|
|
@@ -44691,21 +45706,21 @@ function buildWindowsTaskXml(cfg) {
|
|
|
44691
45706
|
`;
|
|
44692
45707
|
}
|
|
44693
45708
|
function isTccProtected(projectDir, home = import_node_os.default.homedir()) {
|
|
44694
|
-
const rel =
|
|
44695
|
-
if (rel.startsWith("..") ||
|
|
44696
|
-
const top = rel.split(
|
|
45709
|
+
const rel = import_node_path15.default.relative(home, import_node_path15.default.resolve(projectDir));
|
|
45710
|
+
if (rel.startsWith("..") || import_node_path15.default.isAbsolute(rel)) return false;
|
|
45711
|
+
const top = rel.split(import_node_path15.default.sep)[0];
|
|
44697
45712
|
return ["Desktop", "Documents", "Downloads"].includes(top ?? "");
|
|
44698
45713
|
}
|
|
44699
45714
|
function resolveCliEntry() {
|
|
44700
45715
|
try {
|
|
44701
|
-
return
|
|
45716
|
+
return import_node_fs19.default.realpathSync(process.argv[1]);
|
|
44702
45717
|
} catch {
|
|
44703
|
-
return
|
|
45718
|
+
return import_node_path15.default.resolve(process.argv[1]);
|
|
44704
45719
|
}
|
|
44705
45720
|
}
|
|
44706
45721
|
function resolveProjectDir(explicit) {
|
|
44707
|
-
const dir =
|
|
44708
|
-
if (!
|
|
45722
|
+
const dir = import_node_path15.default.resolve(explicit ?? process.cwd());
|
|
45723
|
+
if (!import_node_fs19.default.existsSync(import_node_path15.default.join(dir, ".sail"))) {
|
|
44709
45724
|
throw new Error(
|
|
44710
45725
|
`No .sail/ found in ${dir}.
|
|
44711
45726
|
Run this from your Sailor project root, or pass --project <path>. (The installer does not search parent directories \u2014 that would risk targeting the wrong project.)`
|
|
@@ -44717,7 +45732,7 @@ function passphraseReadiness(projectDir) {
|
|
|
44717
45732
|
const account2 = (() => {
|
|
44718
45733
|
try {
|
|
44719
45734
|
return JSON.parse(
|
|
44720
|
-
|
|
45735
|
+
import_node_fs19.default.readFileSync(import_node_path15.default.join(projectDir, ".sail", "account.json"), "utf-8")
|
|
44721
45736
|
);
|
|
44722
45737
|
} catch {
|
|
44723
45738
|
return null;
|
|
@@ -44733,28 +45748,28 @@ function passphraseReadiness(projectDir) {
|
|
|
44733
45748
|
} finally {
|
|
44734
45749
|
process.chdir(prevCwd);
|
|
44735
45750
|
}
|
|
44736
|
-
const env = parseEnvFile(
|
|
45751
|
+
const env = parseEnvFile(import_node_path15.default.join(projectDir, ".sail", ".env.local"));
|
|
44737
45752
|
const passphraseInEnvFile = Boolean(env.SAIL_PASSPHRASE);
|
|
44738
45753
|
return { keystorePresent, passphraseInEnvFile, ready: keystorePresent && passphraseInEnvFile };
|
|
44739
45754
|
}
|
|
44740
45755
|
function buildConfig(opts) {
|
|
44741
45756
|
const projectDir = resolveProjectDir(opts.project);
|
|
44742
45757
|
return {
|
|
44743
|
-
projectName: sanitizeName(
|
|
45758
|
+
projectName: sanitizeName(import_node_path15.default.basename(projectDir)),
|
|
44744
45759
|
projectDir,
|
|
44745
45760
|
nodePath: process.execPath,
|
|
44746
45761
|
cliEntry: resolveCliEntry(),
|
|
44747
|
-
logPath:
|
|
45762
|
+
logPath: import_node_path15.default.join(projectDir, ".sail", "agent.log"),
|
|
44748
45763
|
interval: opts.interval != null ? Number(opts.interval) : void 0,
|
|
44749
45764
|
chain: opts.chain != null ? Number(opts.chain) : void 0,
|
|
44750
45765
|
restartSec: 30
|
|
44751
45766
|
};
|
|
44752
45767
|
}
|
|
44753
45768
|
function plistPath(projectName) {
|
|
44754
|
-
return
|
|
45769
|
+
return import_node_path15.default.join(import_node_os.default.homedir(), "Library", "LaunchAgents", `${launchdLabel(projectName)}.plist`);
|
|
44755
45770
|
}
|
|
44756
45771
|
function systemdPath(projectName) {
|
|
44757
|
-
return
|
|
45772
|
+
return import_node_path15.default.join(import_node_os.default.homedir(), ".config", "systemd", "user", systemdUnitName(projectName));
|
|
44758
45773
|
}
|
|
44759
45774
|
async function serviceInstall(opts = {}) {
|
|
44760
45775
|
const cfg = buildConfig(opts);
|
|
@@ -44778,12 +45793,12 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44778
45793
|
console.warn(`\u26A0 ${msg}
|
|
44779
45794
|
Proceeding because --force was given.`);
|
|
44780
45795
|
}
|
|
44781
|
-
|
|
45796
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(cfg.logPath), { recursive: true });
|
|
44782
45797
|
if (platform === "darwin") {
|
|
44783
45798
|
const plist = buildLaunchdPlist(cfg);
|
|
44784
45799
|
const dest = plistPath(cfg.projectName);
|
|
44785
|
-
|
|
44786
|
-
|
|
45800
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(dest), { recursive: true });
|
|
45801
|
+
import_node_fs19.default.writeFileSync(dest, plist);
|
|
44787
45802
|
const uid2 = process.getuid?.() ?? 0;
|
|
44788
45803
|
try {
|
|
44789
45804
|
try {
|
|
@@ -44802,8 +45817,8 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44802
45817
|
if (platform === "linux") {
|
|
44803
45818
|
const unit = buildSystemdUnit(cfg);
|
|
44804
45819
|
const dest = systemdPath(cfg.projectName);
|
|
44805
|
-
|
|
44806
|
-
|
|
45820
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(dest), { recursive: true });
|
|
45821
|
+
import_node_fs19.default.writeFileSync(dest, unit);
|
|
44807
45822
|
try {
|
|
44808
45823
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "daemon-reload"], { stdio: "inherit" });
|
|
44809
45824
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "enable", "--now", systemdUnitName(cfg.projectName)], {
|
|
@@ -44817,8 +45832,8 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44817
45832
|
}
|
|
44818
45833
|
if (platform === "win32") {
|
|
44819
45834
|
const xml = buildWindowsTaskXml(cfg);
|
|
44820
|
-
const dest =
|
|
44821
|
-
|
|
45835
|
+
const dest = import_node_path15.default.join(import_node_os.default.tmpdir(), `${windowsTaskName(cfg.projectName)}.xml`);
|
|
45836
|
+
import_node_fs19.default.writeFileSync(dest, xml, "utf-8");
|
|
44822
45837
|
try {
|
|
44823
45838
|
(0, import_node_child_process2.execFileSync)(
|
|
44824
45839
|
"schtasks",
|
|
@@ -44829,7 +45844,7 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44829
45844
|
throw new Error(`schtasks /Create failed: ${err.message}`);
|
|
44830
45845
|
} finally {
|
|
44831
45846
|
try {
|
|
44832
|
-
|
|
45847
|
+
import_node_fs19.default.rmSync(dest, { force: true });
|
|
44833
45848
|
} catch {
|
|
44834
45849
|
}
|
|
44835
45850
|
}
|
|
@@ -44855,14 +45870,14 @@ function okInstall(cfg, unit) {
|
|
|
44855
45870
|
);
|
|
44856
45871
|
}
|
|
44857
45872
|
async function serviceStatus(opts = {}) {
|
|
44858
|
-
const projectName = sanitizeName(
|
|
45873
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44859
45874
|
const platform = process.platform;
|
|
44860
45875
|
let installed = false;
|
|
44861
45876
|
let running = false;
|
|
44862
45877
|
let detail = "";
|
|
44863
45878
|
try {
|
|
44864
45879
|
if (platform === "darwin") {
|
|
44865
|
-
installed =
|
|
45880
|
+
installed = import_node_fs19.default.existsSync(plistPath(projectName));
|
|
44866
45881
|
const uid2 = process.getuid?.() ?? 0;
|
|
44867
45882
|
try {
|
|
44868
45883
|
detail = (0, import_node_child_process2.execFileSync)("launchctl", ["print", `gui/${uid2}/${launchdLabel(projectName)}`], {
|
|
@@ -44874,7 +45889,7 @@ async function serviceStatus(opts = {}) {
|
|
|
44874
45889
|
} catch {
|
|
44875
45890
|
}
|
|
44876
45891
|
} else if (platform === "linux") {
|
|
44877
|
-
installed =
|
|
45892
|
+
installed = import_node_fs19.default.existsSync(systemdPath(projectName));
|
|
44878
45893
|
try {
|
|
44879
45894
|
detail = (0, import_node_child_process2.execFileSync)("systemctl", ["--user", "is-active", systemdUnitName(projectName)], {
|
|
44880
45895
|
encoding: "utf-8",
|
|
@@ -44910,7 +45925,7 @@ async function serviceStatus(opts = {}) {
|
|
|
44910
45925
|
);
|
|
44911
45926
|
}
|
|
44912
45927
|
async function serviceStop(opts = {}) {
|
|
44913
|
-
const projectName = sanitizeName(
|
|
45928
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44914
45929
|
const platform = process.platform;
|
|
44915
45930
|
if (platform === "darwin") {
|
|
44916
45931
|
const uid2 = process.getuid?.() ?? 0;
|
|
@@ -44929,7 +45944,7 @@ async function serviceStop(opts = {}) {
|
|
|
44929
45944
|
});
|
|
44930
45945
|
}
|
|
44931
45946
|
async function serviceUninstall(opts = {}) {
|
|
44932
|
-
const projectName = sanitizeName(
|
|
45947
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44933
45948
|
const platform = process.platform;
|
|
44934
45949
|
if (platform === "darwin") {
|
|
44935
45950
|
const uid2 = process.getuid?.() ?? 0;
|
|
@@ -44939,7 +45954,7 @@ async function serviceUninstall(opts = {}) {
|
|
|
44939
45954
|
});
|
|
44940
45955
|
} catch {
|
|
44941
45956
|
}
|
|
44942
|
-
|
|
45957
|
+
import_node_fs19.default.rmSync(plistPath(projectName), { force: true });
|
|
44943
45958
|
} else if (platform === "linux") {
|
|
44944
45959
|
try {
|
|
44945
45960
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "disable", "--now", systemdUnitName(projectName)], {
|
|
@@ -44947,7 +45962,7 @@ async function serviceUninstall(opts = {}) {
|
|
|
44947
45962
|
});
|
|
44948
45963
|
} catch {
|
|
44949
45964
|
}
|
|
44950
|
-
|
|
45965
|
+
import_node_fs19.default.rmSync(systemdPath(projectName), { force: true });
|
|
44951
45966
|
try {
|
|
44952
45967
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
|
|
44953
45968
|
} catch {
|
|
@@ -44965,21 +45980,21 @@ async function serviceUninstall(opts = {}) {
|
|
|
44965
45980
|
}
|
|
44966
45981
|
async function serviceLogs(opts = {}) {
|
|
44967
45982
|
const projectDir = resolveProjectDir(opts.project);
|
|
44968
|
-
const logPath =
|
|
44969
|
-
if (!
|
|
45983
|
+
const logPath = import_node_path15.default.join(projectDir, ".sail", "agent.log");
|
|
45984
|
+
if (!import_node_fs19.default.existsSync(logPath)) {
|
|
44970
45985
|
console.log(`No log yet at ${logPath}. The service writes here once it runs.`);
|
|
44971
45986
|
return;
|
|
44972
45987
|
}
|
|
44973
45988
|
if (opts.follow) {
|
|
44974
45989
|
if (process.platform === "win32") {
|
|
44975
|
-
console.log(
|
|
45990
|
+
console.log(import_node_fs19.default.readFileSync(logPath, "utf-8"));
|
|
44976
45991
|
console.log("(follow mode is not supported on Windows here \u2014 re-run to refresh)");
|
|
44977
45992
|
return;
|
|
44978
45993
|
}
|
|
44979
45994
|
(0, import_node_child_process2.execFileSync)("tail", ["-f", logPath], { stdio: "inherit" });
|
|
44980
45995
|
return;
|
|
44981
45996
|
}
|
|
44982
|
-
const lines =
|
|
45997
|
+
const lines = import_node_fs19.default.readFileSync(logPath, "utf-8").split("\n");
|
|
44983
45998
|
console.log(lines.slice(-200).join("\n"));
|
|
44984
45999
|
}
|
|
44985
46000
|
|
|
@@ -45135,14 +46150,14 @@ async function sessionResume(opts = {}) {
|
|
|
45135
46150
|
}
|
|
45136
46151
|
|
|
45137
46152
|
// src/commands/station.ts
|
|
45138
|
-
var
|
|
45139
|
-
var
|
|
45140
|
-
var RUNTIME_SERVER_FILE2 = (0,
|
|
46153
|
+
var import_node_fs20 = require("node:fs");
|
|
46154
|
+
var import_node_path16 = require("node:path");
|
|
46155
|
+
var RUNTIME_SERVER_FILE2 = (0, import_node_path16.join)(".sail", "runtime", "server.json");
|
|
45141
46156
|
function readState(projectRoot) {
|
|
45142
|
-
const file = (0,
|
|
45143
|
-
if (!(0,
|
|
46157
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
46158
|
+
if (!(0, import_node_fs20.existsSync)(file)) return null;
|
|
45144
46159
|
try {
|
|
45145
|
-
return JSON.parse((0,
|
|
46160
|
+
return JSON.parse((0, import_node_fs20.readFileSync)(file, "utf8"));
|
|
45146
46161
|
} catch {
|
|
45147
46162
|
return null;
|
|
45148
46163
|
}
|
|
@@ -45214,9 +46229,9 @@ async function stationStop(options) {
|
|
|
45214
46229
|
}
|
|
45215
46230
|
const daemon = await discoverDaemon(projectRoot);
|
|
45216
46231
|
if (!daemon) {
|
|
45217
|
-
const file = (0,
|
|
46232
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
45218
46233
|
try {
|
|
45219
|
-
if ((0,
|
|
46234
|
+
if ((0, import_node_fs20.existsSync)(file)) (0, import_node_fs20.rmSync)(file);
|
|
45220
46235
|
} catch {
|
|
45221
46236
|
}
|
|
45222
46237
|
emit(options.json, () => console.log("Station process not found; cleared stale state."), {
|
|
@@ -45232,9 +46247,9 @@ async function stationStop(options) {
|
|
|
45232
46247
|
pid: state.pid
|
|
45233
46248
|
});
|
|
45234
46249
|
} catch {
|
|
45235
|
-
const file = (0,
|
|
46250
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
45236
46251
|
try {
|
|
45237
|
-
if ((0,
|
|
46252
|
+
if ((0, import_node_fs20.existsSync)(file)) (0, import_node_fs20.rmSync)(file);
|
|
45238
46253
|
} catch {
|
|
45239
46254
|
}
|
|
45240
46255
|
emit(options.json, () => console.log("Station process not found; cleared stale state."), {
|
|
@@ -45296,9 +46311,9 @@ async function status() {
|
|
|
45296
46311
|
|
|
45297
46312
|
// src/commands/ui.ts
|
|
45298
46313
|
var import_node_child_process5 = require("node:child_process");
|
|
45299
|
-
var
|
|
46314
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
45300
46315
|
var import_node_net2 = __toESM(require("node:net"), 1);
|
|
45301
|
-
var
|
|
46316
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
45302
46317
|
|
|
45303
46318
|
// src/lib/tailscale.ts
|
|
45304
46319
|
var import_node_child_process4 = require("node:child_process");
|
|
@@ -45344,12 +46359,12 @@ function tailscaleServeDown() {
|
|
|
45344
46359
|
}
|
|
45345
46360
|
|
|
45346
46361
|
// src/commands/ui.ts
|
|
45347
|
-
var UI_STATE_FILE =
|
|
46362
|
+
var UI_STATE_FILE = import_node_path17.default.join(".sail", "runtime", "ui.json");
|
|
45348
46363
|
function readState2(projectRoot) {
|
|
45349
|
-
const file =
|
|
45350
|
-
if (!
|
|
46364
|
+
const file = import_node_path17.default.join(projectRoot, UI_STATE_FILE);
|
|
46365
|
+
if (!import_node_fs21.default.existsSync(file)) return null;
|
|
45351
46366
|
try {
|
|
45352
|
-
return JSON.parse(
|
|
46367
|
+
return JSON.parse(import_node_fs21.default.readFileSync(file, "utf-8"));
|
|
45353
46368
|
} catch {
|
|
45354
46369
|
return null;
|
|
45355
46370
|
}
|
|
@@ -45357,7 +46372,7 @@ function readState2(projectRoot) {
|
|
|
45357
46372
|
function installedCliVersion() {
|
|
45358
46373
|
try {
|
|
45359
46374
|
const pkg = JSON.parse(
|
|
45360
|
-
|
|
46375
|
+
import_node_fs21.default.readFileSync(import_node_path17.default.join(packageRoot(), "package.json"), "utf-8")
|
|
45361
46376
|
);
|
|
45362
46377
|
return pkg.version ?? null;
|
|
45363
46378
|
} catch {
|
|
@@ -45384,16 +46399,16 @@ async function warnIfVersionSkew(port) {
|
|
|
45384
46399
|
}
|
|
45385
46400
|
function waitForPort(port, timeoutMs) {
|
|
45386
46401
|
const deadline = Date.now() + timeoutMs;
|
|
45387
|
-
return new Promise((
|
|
46402
|
+
return new Promise((resolve4) => {
|
|
45388
46403
|
const attempt = () => {
|
|
45389
46404
|
const socket = import_node_net2.default.connect(port, "127.0.0.1");
|
|
45390
46405
|
socket.once("connect", () => {
|
|
45391
46406
|
socket.destroy();
|
|
45392
|
-
|
|
46407
|
+
resolve4(true);
|
|
45393
46408
|
});
|
|
45394
46409
|
socket.once("error", () => {
|
|
45395
46410
|
socket.destroy();
|
|
45396
|
-
if (Date.now() > deadline)
|
|
46411
|
+
if (Date.now() > deadline) resolve4(false);
|
|
45397
46412
|
else setTimeout(attempt, 150);
|
|
45398
46413
|
});
|
|
45399
46414
|
};
|
|
@@ -45402,16 +46417,16 @@ function waitForPort(port, timeoutMs) {
|
|
|
45402
46417
|
}
|
|
45403
46418
|
async function uiCommand(opts = {}) {
|
|
45404
46419
|
const distDir = cliDistDir();
|
|
45405
|
-
const uiDistDir =
|
|
45406
|
-
const serverBundle =
|
|
46420
|
+
const uiDistDir = import_node_path17.default.join(packageRoot(), "packages", "ui", "dist");
|
|
46421
|
+
const serverBundle = import_node_path17.default.resolve(distDir, "server.cjs");
|
|
45407
46422
|
const projectRoot = process.cwd();
|
|
45408
|
-
const sailDir2 =
|
|
46423
|
+
const sailDir2 = import_node_path17.default.join(projectRoot, ".sail");
|
|
45409
46424
|
const envPort = Number(process.env.PORT);
|
|
45410
46425
|
const port = await findFreePort(Number.isInteger(envPort) && envPort > 0 && envPort <= 65535 ? envPort : projectPort(projectRoot));
|
|
45411
|
-
if (!
|
|
46426
|
+
if (!import_node_fs21.default.existsSync(serverBundle)) {
|
|
45412
46427
|
throw new Error(`Server bundle not found at ${serverBundle}. Re-run the sailor build.`);
|
|
45413
46428
|
}
|
|
45414
|
-
if (!
|
|
46429
|
+
if (!import_node_fs21.default.existsSync(import_node_path17.default.join(uiDistDir, "index.html"))) {
|
|
45415
46430
|
throw new Error(`UI dist not found at ${uiDistDir}. Re-run the sailor build.`);
|
|
45416
46431
|
}
|
|
45417
46432
|
let tailnetUrl = null;
|
|
@@ -45441,10 +46456,10 @@ async function uiCommand(opts = {}) {
|
|
|
45441
46456
|
await warnIfVersionSkew(existing.port);
|
|
45442
46457
|
return;
|
|
45443
46458
|
}
|
|
45444
|
-
const runtimeDir =
|
|
45445
|
-
|
|
45446
|
-
const logFile =
|
|
45447
|
-
const logFd =
|
|
46459
|
+
const runtimeDir = import_node_path17.default.join(projectRoot, ".sail", "runtime");
|
|
46460
|
+
import_node_fs21.default.mkdirSync(runtimeDir, { recursive: true });
|
|
46461
|
+
const logFile = import_node_path17.default.join(runtimeDir, "ui.log");
|
|
46462
|
+
const logFd = import_node_fs21.default.openSync(logFile, "a");
|
|
45448
46463
|
const corsOrigins = [process.env.SAILOR_CORS_ORIGINS, tailnetUrl].filter(Boolean).join(",");
|
|
45449
46464
|
const child = (0, import_node_child_process5.spawn)(process.execPath, [serverBundle], {
|
|
45450
46465
|
detached: true,
|
|
@@ -45459,7 +46474,7 @@ async function uiCommand(opts = {}) {
|
|
|
45459
46474
|
}
|
|
45460
46475
|
});
|
|
45461
46476
|
child.unref();
|
|
45462
|
-
|
|
46477
|
+
import_node_fs21.default.closeSync(logFd);
|
|
45463
46478
|
const READY_TIMEOUT_MS = 1e4;
|
|
45464
46479
|
const deadline = Date.now() + READY_TIMEOUT_MS;
|
|
45465
46480
|
let ready = false;
|
|
@@ -45473,14 +46488,14 @@ async function uiCommand(opts = {}) {
|
|
|
45473
46488
|
if (!ready) {
|
|
45474
46489
|
let tail = "";
|
|
45475
46490
|
try {
|
|
45476
|
-
tail =
|
|
46491
|
+
tail = import_node_fs21.default.readFileSync(logFile, "utf-8").split("\n").filter(Boolean).slice(-15).join("\n");
|
|
45477
46492
|
} catch {
|
|
45478
46493
|
}
|
|
45479
46494
|
throw new Error(
|
|
45480
46495
|
`Sailor UI failed to start within ${READY_TIMEOUT_MS / 1e3}s on port ${port}.` + (tail ? `
|
|
45481
46496
|
|
|
45482
46497
|
Server output:
|
|
45483
|
-
${tail}` : ` See ${
|
|
46498
|
+
${tail}` : ` See ${import_node_path17.default.relative(projectRoot, logFile)}.`)
|
|
45484
46499
|
);
|
|
45485
46500
|
}
|
|
45486
46501
|
let exposed = false;
|
|
@@ -45495,8 +46510,8 @@ ${tail}` : ` See ${import_node_path16.default.relative(projectRoot, logFile)}.`)
|
|
|
45495
46510
|
);
|
|
45496
46511
|
}
|
|
45497
46512
|
}
|
|
45498
|
-
|
|
45499
|
-
|
|
46513
|
+
import_node_fs21.default.writeFileSync(
|
|
46514
|
+
import_node_path17.default.join(projectRoot, UI_STATE_FILE),
|
|
45500
46515
|
JSON.stringify({ pid: child.pid, port, startedAt: (/* @__PURE__ */ new Date()).toISOString(), exposed }, null, 2)
|
|
45501
46516
|
);
|
|
45502
46517
|
console.log(`Sailor UI started at http://localhost:${port} (pid ${child.pid})`);
|
|
@@ -45509,7 +46524,7 @@ async function uiStatus() {
|
|
|
45509
46524
|
console.log(`\u25CF running http://localhost:${state.port} (pid ${state.pid})`);
|
|
45510
46525
|
await warnIfVersionSkew(state.port);
|
|
45511
46526
|
} else {
|
|
45512
|
-
if (state)
|
|
46527
|
+
if (state) import_node_fs21.default.rmSync(import_node_path17.default.join(process.cwd(), UI_STATE_FILE), { force: true });
|
|
45513
46528
|
console.log("\u25CB Sailor UI is not running");
|
|
45514
46529
|
}
|
|
45515
46530
|
}
|
|
@@ -45521,7 +46536,7 @@ function uiStop() {
|
|
|
45521
46536
|
return;
|
|
45522
46537
|
}
|
|
45523
46538
|
if (!isProcessAlive(state.pid)) {
|
|
45524
|
-
|
|
46539
|
+
import_node_fs21.default.rmSync(import_node_path17.default.join(projectRoot, UI_STATE_FILE), { force: true });
|
|
45525
46540
|
console.log("Sailor UI is not running (stale state file removed).");
|
|
45526
46541
|
return;
|
|
45527
46542
|
}
|
|
@@ -45530,21 +46545,21 @@ function uiStop() {
|
|
|
45530
46545
|
tailscaleServeDown();
|
|
45531
46546
|
console.log("Tailnet exposure removed.");
|
|
45532
46547
|
}
|
|
45533
|
-
|
|
46548
|
+
import_node_fs21.default.rmSync(import_node_path17.default.join(projectRoot, UI_STATE_FILE), { force: true });
|
|
45534
46549
|
console.log(`Stopped Sailor UI (pid ${state.pid}).`);
|
|
45535
46550
|
}
|
|
45536
46551
|
|
|
45537
46552
|
// src/index.ts
|
|
45538
|
-
function
|
|
46553
|
+
function cliVersion2() {
|
|
45539
46554
|
try {
|
|
45540
|
-
const pkg = JSON.parse((0,
|
|
46555
|
+
const pkg = JSON.parse((0, import_node_fs22.readFileSync)((0, import_node_path18.join)(packageRoot(), "package.json"), "utf-8"));
|
|
45541
46556
|
return pkg.version ?? "0.0.0";
|
|
45542
46557
|
} catch {
|
|
45543
46558
|
return "0.0.0";
|
|
45544
46559
|
}
|
|
45545
46560
|
}
|
|
45546
46561
|
var program2 = new Command();
|
|
45547
|
-
program2.name("sailor").description("Operator toolkit for Sail Protocol").version(
|
|
46562
|
+
program2.name("sailor").description("Operator toolkit for Sail Protocol").version(cliVersion2());
|
|
45548
46563
|
function action(fn) {
|
|
45549
46564
|
return async () => {
|
|
45550
46565
|
try {
|
|
@@ -45569,7 +46584,7 @@ function actionWith(fn) {
|
|
|
45569
46584
|
closePrompts();
|
|
45570
46585
|
};
|
|
45571
46586
|
}
|
|
45572
|
-
program2.command("init [dir]").description("Scaffold a new Sail agent into the current directory (or [dir] subdirectory)").option("--template <name>", "Template to scaffold from (default: default)").option("--chain <id>", "Default EVM chain id written to .sail/config.json and .env.example").option("--rpc-url <url>", "Default RPC_URL written to .sail/.env.local").option("--force", "Re-initialize even if already initialized (overwrites scaffold files; keys/ and state/ are preserved)").
|
|
46587
|
+
program2.command("init [dir]").description("Scaffold a new Sail agent into the current directory (or [dir] subdirectory)").option("--template <name>", "Template to scaffold from (default: default)").option("--chain <id>", "Default EVM chain id written to .sail/config.json and .env.example").option("--rpc-url <url>", "Default RPC_URL written to .sail/.env.local").option("--force", "Re-initialize even if already initialized (overwrites scaffold files; keys/ and state/ are preserved)").action(
|
|
45573
46588
|
async (name, opts) => {
|
|
45574
46589
|
try {
|
|
45575
46590
|
await initCommand(name, opts);
|
|
@@ -45608,6 +46623,9 @@ mandate.command("attach").description("Register one or more already-deployed per
|
|
|
45608
46623
|
"--address <mandateOrName>",
|
|
45609
46624
|
"Permission address or locally-tracked name; or a comma-separated list of addresses to register together in one signature"
|
|
45610
46625
|
).requiredOption("--sma <address>", "SMA to register the permission on").option("--label <label>", "Human-readable label shown in the signing UI").option("--json", "Emit machine-readable JSON").action(actionWith(mandateAttach));
|
|
46626
|
+
mandate.command("configure").description(
|
|
46627
|
+
"Write per-account bounds on an already-deployed shared permission singleton (configureDirect; owner tx via the signing station). Pairs with `mandate attach`, which only registers \u2014 a registered-but-unconfigured singleton denies every call."
|
|
46628
|
+
).requiredOption("--address <singleton>", "Shared permission singleton address (deployed on this chain)").requiredOption("--sma <address>", "SMA to configure the singleton for").option("--params <hex>", "Pre-encoded config blob (0x-prefixed hex)").option("--args-file <path>", "JSON file of typed params (paired with --template)").option("--template <name>", "Template name (e.g. SwapPermission) \u2014 resolves the encoder for --args-file").option("--label <label>", "Human-readable label shown in the signing UI").option("--simulate-only", "Stop after the off-chain pre-flight (no signing, no gas)").option("--force", "Re-configure even if isConfigured is already true").option("--json", "Emit machine-readable JSON").action(actionWith(mandateConfigure));
|
|
45611
46629
|
mandate.command("deploy-clone").description("[currently unavailable \u2014 no clone templates deployed on any chain; use `mandate deploy`] Deploy + register a standalone clone permission via the signing UI").requiredOption("--template <key>", "Standalone clone template key (e.g. boundedApprove)").requiredOption("--sma <address>", "SMA to deploy the clone for and register it on").option("--tokens <csv>", "Comma-separated allowed token addresses").option("--spenders <csv>", "Comma-separated allowed spender addresses").option("--max <amount>", "Max amount per tx in base units (default: uint256 max)").option("--label <label>", "Human-readable label to track this permission under").option("--json", "Emit machine-readable JSON").action(actionWith(mandateDeployClone));
|
|
45612
46630
|
mandate.command("revoke").description("Revoke permission(s) from an SMA (EIP-712 RevokePermissions, owner-authorized)").option("--address <permissionOrName>", "Permission address, or a name tracked locally").requiredOption("--sma <address>", "Safe (SMA) to revoke the permission(s) from").option("--all", "Revoke every permission currently registered on the SMA").option("--json", "Output JSON").action(actionWith(mandateRevoke));
|
|
45613
46631
|
mandate.command("templates").description("Show how to author your own permission contract (and any community-deployed addresses)").option("--json", "Emit machine-readable JSON").action(actionWith(mandateTemplates));
|