@dev.sail.money/sailor 1.3.0-95 → 1.4.0-242
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 +10 -7
- package/LICENSE +1 -1
- package/README.md +64 -472
- package/package.json +12 -8
- package/packages/cli/README.md +1 -1
- package/packages/cli/dist/index.cjs +1633 -535
- package/packages/cli/dist/server.cjs +19791 -21738
- 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/SailGovernance.d.ts +6 -5
- package/packages/sdk/dist/abis/SailGovernance.d.ts.map +1 -1
- package/packages/sdk/dist/abis/SailGovernance.js +6 -5
- package/packages/sdk/dist/abis/SailGovernance.js.map +1 -1
- 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 +0 -7
- package/packages/sdk/dist/chains.d.ts.map +1 -1
- package/packages/sdk/dist/chains.js +81 -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 +59 -10
- package/packages/sdk/dist/fees.d.ts.map +1 -1
- package/packages/sdk/dist/fees.js +74 -41
- package/packages/sdk/dist/fees.js.map +1 -1
- package/packages/sdk/dist/index.d.ts +5 -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 +7 -2
- package/packages/sdk/dist/intelligence.d.ts.map +1 -1
- package/packages/sdk/dist/intelligence.js +2 -2
- package/packages/sdk/dist/intelligence.js.map +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/signing.d.ts +14 -0
- package/packages/sdk/dist/signing.d.ts.map +1 -1
- package/packages/sdk/package.json +6 -2
- package/packages/ui/dist/assets/{add-CLs0-B0p.js → add-CBbu2pe_.js} +2 -2
- package/packages/ui/dist/assets/{all-wallets-CDOk28sj.js → all-wallets-C1oy4NUu.js} +2 -2
- package/packages/ui/dist/assets/{app-store-DVzpi1qN.js → app-store-DKqyf0Zv.js} +1 -1
- package/packages/ui/dist/assets/{apple-C9U9iH1l.js → apple-DyoIbCFy.js} +2 -2
- package/packages/ui/dist/assets/{arrow-bottom-circle-jxial9Si.js → arrow-bottom-circle-CMS-OqZQ.js} +2 -2
- package/packages/ui/dist/assets/arrow-bottom-pUWeEqYu.js +8 -0
- package/packages/ui/dist/assets/arrow-left-B81HMJNL.js +8 -0
- package/packages/ui/dist/assets/arrow-right-Z5czoKlC.js +8 -0
- package/packages/ui/dist/assets/arrow-top-C6ym1oll.js +8 -0
- package/packages/ui/dist/assets/{bank-B98it1qN.js → bank-B41nlslf.js} +2 -2
- package/packages/ui/dist/assets/{basic-DsgeyPNu.js → basic-CWqOb7CV.js} +177 -177
- package/packages/ui/dist/assets/{browser-j4vCeHwE.js → browser-DDKdqoZ9.js} +2 -2
- package/packages/ui/dist/assets/{card-CzxbMvEd.js → card-BgOmTajq.js} +2 -2
- package/packages/ui/dist/assets/ccip-CtJUKWRd.js +1 -0
- package/packages/ui/dist/assets/{checkmark-D5sWBbk3.js → checkmark-CGqQipH4.js} +2 -2
- package/packages/ui/dist/assets/{checkmark-bold-BW6w3KCC.js → checkmark-bold-Ci5xf90j.js} +2 -2
- package/packages/ui/dist/assets/chevron-bottom-D7Xert17.js +8 -0
- package/packages/ui/dist/assets/chevron-left-BGbUebR2.js +8 -0
- package/packages/ui/dist/assets/chevron-right-xVsESnHU.js +8 -0
- package/packages/ui/dist/assets/chevron-top-DEA9cR6v.js +8 -0
- package/packages/ui/dist/assets/{chrome-store-B1OMtzC-.js → chrome-store-BsyI-4PI.js} +2 -2
- package/packages/ui/dist/assets/{clock-e0HueehS.js → clock-Dct9oQ3M.js} +2 -2
- package/packages/ui/dist/assets/{close-Cy1ytr26.js → close-BvSCnI2y.js} +2 -2
- package/packages/ui/dist/assets/{coinPlaceholder-DqJu3ZPV.js → coinPlaceholder-p7RiWkon.js} +2 -2
- package/packages/ui/dist/assets/{compass-XDz_N2Hg.js → compass-BUeeZqX4.js} +2 -2
- package/packages/ui/dist/assets/{copy-DmDo3Nob.js → copy-C5jXbxLq.js} +2 -2
- package/packages/ui/dist/assets/core-CiAm42Mq.js +907 -0
- package/packages/ui/dist/assets/cursor-C0T7JWFO.js +3 -0
- package/packages/ui/dist/assets/{cursor-transparent-DF2aA10D.js → cursor-transparent-BZp3-JmA.js} +2 -2
- package/packages/ui/dist/assets/{desktop-CVydOWLn.js → desktop-BIui_Lzb.js} +2 -2
- package/packages/ui/dist/assets/{disconnect-BuN2Whnz.js → disconnect-B3Bxdchp.js} +2 -2
- package/packages/ui/dist/assets/{discord-DMNPvTB2.js → discord-VWI0yDyx.js} +2 -2
- package/packages/ui/dist/assets/{etherscan-CacW-93f.js → etherscan-BpBvUT9i.js} +2 -2
- package/packages/ui/dist/assets/events-DQ172AOg.js +1 -0
- package/packages/ui/dist/assets/{exclamation-triangle-B26hIvqO.js → exclamation-triangle-o1TJHIUw.js} +2 -2
- package/packages/ui/dist/assets/{extension-B7rI0gv7.js → extension-4RaLvbh5.js} +2 -2
- package/packages/ui/dist/assets/external-link-BHIwjDgj.js +8 -0
- package/packages/ui/dist/assets/{facebook-BDqbE6kl.js → facebook-Bes5g-wN.js} +2 -2
- package/packages/ui/dist/assets/{farcaster-zQ3oQzZ8.js → farcaster-CiJ-352m.js} +2 -2
- package/packages/ui/dist/assets/{filters-DCglZYsM.js → filters-DMOteumb.js} +2 -2
- package/packages/ui/dist/assets/{github-BH-BYjss.js → github-D2nDec9X.js} +2 -2
- package/packages/ui/dist/assets/{google-DYFWxZbC.js → google-lZZlQZPQ.js} +2 -2
- package/packages/ui/dist/assets/{help-circle-BXH_DtZ_.js → help-circle-D4cSSziR.js} +1 -1
- package/packages/ui/dist/assets/{id-Dr2yTeX1.js → id-BmhXZq5P.js} +2 -2
- package/packages/ui/dist/assets/{image-DeJey1Eg.js → image-Dz4FPeET.js} +2 -2
- package/packages/ui/dist/assets/index-B07bCKJ8.css +1 -0
- package/packages/ui/dist/assets/index-BV8s6ez1.js +1 -0
- package/packages/ui/dist/assets/index-BeUp3nOq.js +1 -0
- package/packages/ui/dist/assets/index-CvRylmZJ.js +16 -0
- package/packages/ui/dist/assets/{index-DVjAiPHI.js → index-DeoQO45V.js} +3 -3
- package/packages/ui/dist/assets/index-Et5S3ZaW.js +47 -0
- package/packages/ui/dist/assets/index-LiKeH8Cd.js +1780 -0
- package/packages/ui/dist/assets/index.es-dfpEui-9.js +26 -0
- package/packages/ui/dist/assets/{info-B91pD5Rw.js → info-77RSvIMg.js} +2 -2
- package/packages/ui/dist/assets/{info-circle-CySl3_on.js → info-circle-CWsII-NN.js} +2 -2
- package/packages/ui/dist/assets/{lightbulb-wwG8LQLo.js → lightbulb-BZXzm7XE.js} +2 -2
- package/packages/ui/dist/assets/{mail-D617YZ8y.js → mail-DMG1YqB0.js} +2 -2
- package/packages/ui/dist/assets/metamask-sdk-K1x_iqcc.js +542 -0
- package/packages/ui/dist/assets/{mobile-CD9KlA0m.js → mobile-DuJfOBSk.js} +2 -2
- package/packages/ui/dist/assets/{more-BQ_rpPXo.js → more-Cs9ySK2F.js} +2 -2
- package/packages/ui/dist/assets/{network-placeholder-BA7nl9e6.js → network-placeholder-CMDPmB1E.js} +2 -2
- package/packages/ui/dist/assets/{nftPlaceholder-D1EaaeDn.js → nftPlaceholder-Cj0f9y2u.js} +2 -2
- package/packages/ui/dist/assets/{off-DnGG35_w.js → off-9zSSsm-e.js} +2 -2
- package/packages/ui/dist/assets/{play-store-C5u2FvYB.js → play-store-CPwIb8Gj.js} +2 -2
- package/packages/ui/dist/assets/{plus-CM4xJkvI.js → plus-BOHQri8o.js} +2 -2
- package/packages/ui/dist/assets/{qr-code-kM3FUIdR.js → qr-code-DqhbK276.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-DWrRWIBM.js → recycle-horizontal-BpGM56Qz.js} +2 -2
- package/packages/ui/dist/assets/{refresh-CztbjK2d.js → refresh-BPzZlhTP.js} +2 -2
- package/packages/ui/dist/assets/{reown-logo-DUHEIodF.js → reown-logo-OCkI0xzo.js} +2 -2
- package/packages/ui/dist/assets/{search-BJtb4mn1.js → search-B1JEJvwq.js} +2 -2
- package/packages/ui/dist/assets/{secp256k1-BjrTZpQx.js → secp256k1-BqUeV9Cb.js} +1 -1
- package/packages/ui/dist/assets/{send-B3_kavG1.js → send-JNsDlNoq.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontal-BrF9POiv.js → swapHorizontal-C3Z1FImK.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalBold-Dgf8OjXj.js → swapHorizontalBold-Cmdy2iAn.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalMedium-C6wX0JZj.js → swapHorizontalMedium-DFX57Nn9.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-DTAVw6oF.js → swapHorizontalRoundedBold-baB389c8.js} +2 -2
- package/packages/ui/dist/assets/{swapVertical-KGlTFNoi.js → swapVertical-DmAYGfK1.js} +2 -2
- package/packages/ui/dist/assets/{telegram-DnLrK-4y.js → telegram-BHbYE-nI.js} +2 -2
- package/packages/ui/dist/assets/{three-dots-C6_oMJfw.js → three-dots-BwRWl6qJ.js} +2 -2
- package/packages/ui/dist/assets/{twitch-DvPqPD4f.js → twitch-Drx0q6B6.js} +2 -2
- package/packages/ui/dist/assets/{twitterIcon-BZdk82Am.js → twitterIcon-AuJ2KQ6p.js} +2 -2
- package/packages/ui/dist/assets/{verify-CbESD5G0.js → verify-Dkrd3q7o.js} +2 -2
- package/packages/ui/dist/assets/{verify-filled-BRjTrLxw.js → verify-filled-B9e3-nz-.js} +2 -2
- package/packages/ui/dist/assets/{w3m-modal-D9b2TGHc.js → w3m-modal-DtkEjQA7.js} +1 -1
- package/packages/ui/dist/assets/{wallet-B87E5UId.js → wallet-CqYzSiBd.js} +2 -2
- package/packages/ui/dist/assets/{wallet-placeholder-DmssSbYf.js → wallet-placeholder-B05kTN_K.js} +2 -2
- package/packages/ui/dist/assets/{walletconnect-CZkLKWMZ.js → walletconnect-BwoPXLaS.js} +3 -3
- package/packages/ui/dist/assets/{warning-circle-BPTpHB1P.js → warning-circle-DK9Ai8rT.js} +2 -2
- package/packages/ui/dist/assets/{x-D_dEtEDU.js → x-BNdh5DVW.js} +2 -2
- package/packages/ui/dist/index.html +2 -2
- package/templates/default/.agents/skills/sail-mandates/SKILL.md +13 -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 +2 -2
- package/templates/default/.agents/skills/sail-project-info/SKILL.md +2 -0
- 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 +21 -2
- 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/cli/dist/mcp.cjs +0 -15534
- package/packages/ui/dist/assets/arrow-bottom-DjQ4jGMe.js +0 -8
- package/packages/ui/dist/assets/arrow-left-BjAyI8D1.js +0 -8
- package/packages/ui/dist/assets/arrow-right-BlFO4Tcx.js +0 -8
- package/packages/ui/dist/assets/arrow-top-DJ3oh3DH.js +0 -8
- package/packages/ui/dist/assets/ccip-U9yiu_EK.js +0 -1
- package/packages/ui/dist/assets/chevron-bottom-BbHhmTQq.js +0 -8
- package/packages/ui/dist/assets/chevron-left-D8BDH4Wo.js +0 -8
- package/packages/ui/dist/assets/chevron-right-BQuQk5zc.js +0 -8
- package/packages/ui/dist/assets/chevron-top-1oeSXkx4.js +0 -8
- package/packages/ui/dist/assets/core-DbkMGSYW.js +0 -907
- package/packages/ui/dist/assets/cursor-DRFqL8nZ.js +0 -3
- package/packages/ui/dist/assets/events-CZkVDFih.js +0 -1
- package/packages/ui/dist/assets/external-link-CX8skCbH.js +0 -8
- package/packages/ui/dist/assets/fallback-DWQYKf3l.js +0 -1
- package/packages/ui/dist/assets/index-BP-UuQ8g.js +0 -1
- package/packages/ui/dist/assets/index-BksbyFjf.js +0 -1
- package/packages/ui/dist/assets/index-C55-Ne92.js +0 -16
- package/packages/ui/dist/assets/index-D6_Zei-R.js +0 -1790
- package/packages/ui/dist/assets/index-DZ2C2rHq.css +0 -1
- package/packages/ui/dist/assets/index-uSdXE5b_.js +0 -1
- package/packages/ui/dist/assets/index.es-dZlNPpfR.js +0 -26
- package/packages/ui/dist/assets/metamask-sdk-RbLbxUgF.js +0 -542
- package/packages/ui/dist/assets/native-CJ5et6AR.js +0 -1
- package/packages/ui/dist/assets/parseSignature-E29x8poM.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/{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
|
@@ -4581,8 +4581,8 @@ var init_encoding = __esm({
|
|
|
4581
4581
|
"../../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/errors/encoding.js"() {
|
|
4582
4582
|
init_base();
|
|
4583
4583
|
IntegerOutOfRangeError = class extends BaseError2 {
|
|
4584
|
-
constructor({ max, min
|
|
4585
|
-
super(`Number "${value}" is not in safe ${size5 ? `${size5 * 8}-bit ${signed ? "signed" : "unsigned"} ` : ""}integer range ${max ? `(${
|
|
4584
|
+
constructor({ max, min, signed, size: size5, value }) {
|
|
4585
|
+
super(`Number "${value}" is not in safe ${size5 ? `${size5 * 8}-bit ${signed ? "signed" : "unsigned"} ` : ""}integer range ${max ? `(${min} to ${max})` : `(above ${min})`}`, { name: "IntegerOutOfRangeError" });
|
|
4586
4586
|
}
|
|
4587
4587
|
};
|
|
4588
4588
|
InvalidBytesBooleanError = class extends BaseError2 {
|
|
@@ -4945,9 +4945,9 @@ function aexists(instance, checkFinished = true) {
|
|
|
4945
4945
|
}
|
|
4946
4946
|
function aoutput(out, instance) {
|
|
4947
4947
|
abytes(out);
|
|
4948
|
-
const
|
|
4949
|
-
if (out.length <
|
|
4950
|
-
throw new Error("digestInto() expects output buffer of length at least " +
|
|
4948
|
+
const min = instance.outputLen;
|
|
4949
|
+
if (out.length < min) {
|
|
4950
|
+
throw new Error("digestInto() expects output buffer of length at least " + min);
|
|
4951
4951
|
}
|
|
4952
4952
|
}
|
|
4953
4953
|
function u32(arr) {
|
|
@@ -5751,11 +5751,11 @@ function encodeBool(value) {
|
|
|
5751
5751
|
function encodeNumber(value, { signed, size: size5 = 256 }) {
|
|
5752
5752
|
if (typeof size5 === "number") {
|
|
5753
5753
|
const max = 2n ** (BigInt(size5) - (signed ? 1n : 0n)) - 1n;
|
|
5754
|
-
const
|
|
5755
|
-
if (value > max || value <
|
|
5754
|
+
const min = signed ? -max - 1n : 0n;
|
|
5755
|
+
if (value > max || value < min)
|
|
5756
5756
|
throw new IntegerOutOfRangeError({
|
|
5757
5757
|
max: max.toString(),
|
|
5758
|
-
min:
|
|
5758
|
+
min: min.toString(),
|
|
5759
5759
|
signed,
|
|
5760
5760
|
size: size5 / 8,
|
|
5761
5761
|
value: value.toString()
|
|
@@ -8574,12 +8574,12 @@ function utf8ToBytes2(str) {
|
|
|
8574
8574
|
throw new Error("string expected");
|
|
8575
8575
|
return new Uint8Array(new TextEncoder().encode(str));
|
|
8576
8576
|
}
|
|
8577
|
-
function inRange(n,
|
|
8578
|
-
return isPosBig(n) && isPosBig(
|
|
8577
|
+
function inRange(n, min, max) {
|
|
8578
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
8579
8579
|
}
|
|
8580
|
-
function aInRange(title, n,
|
|
8581
|
-
if (!inRange(n,
|
|
8582
|
-
throw new Error("expected valid " + title + ": " +
|
|
8580
|
+
function aInRange(title, n, min, max) {
|
|
8581
|
+
if (!inRange(n, min, max))
|
|
8582
|
+
throw new Error("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
8583
8583
|
}
|
|
8584
8584
|
function bitLen(n) {
|
|
8585
8585
|
let len;
|
|
@@ -13526,8 +13526,8 @@ var init_Hex = __esm({
|
|
|
13526
13526
|
encoder4 = /* @__PURE__ */ new TextEncoder();
|
|
13527
13527
|
hexes4 = /* @__PURE__ */ Array.from({ length: 256 }, (_v, i) => i.toString(16).padStart(2, "0"));
|
|
13528
13528
|
IntegerOutOfRangeError2 = class extends BaseError3 {
|
|
13529
|
-
constructor({ max, min
|
|
13530
|
-
super(`Number \`${value}\` is not in safe${size5 ? ` ${size5 * 8}-bit` : ""}${signed ? " signed" : " unsigned"} integer range ${max ? `(\`${
|
|
13529
|
+
constructor({ max, min, signed, size: size5, value }) {
|
|
13530
|
+
super(`Number \`${value}\` is not in safe${size5 ? ` ${size5 * 8}-bit` : ""}${signed ? " signed" : " unsigned"} integer range ${max ? `(\`${min}\` to \`${max}\`)` : `(above \`${min}\`)`}`);
|
|
13531
13531
|
Object.defineProperty(this, "name", {
|
|
13532
13532
|
enumerable: true,
|
|
13533
13533
|
configurable: true,
|
|
@@ -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
|
}
|
|
@@ -25269,11 +25269,11 @@ function encodeBoolean(value) {
|
|
|
25269
25269
|
function encodeNumber2(value, { signed, size: size5 }) {
|
|
25270
25270
|
if (typeof size5 === "number") {
|
|
25271
25271
|
const max = 2n ** (BigInt(size5) - (signed ? 1n : 0n)) - 1n;
|
|
25272
|
-
const
|
|
25273
|
-
if (value > max || value <
|
|
25272
|
+
const min = signed ? -max - 1n : 0n;
|
|
25273
|
+
if (value > max || value < min)
|
|
25274
25274
|
throw new IntegerOutOfRangeError2({
|
|
25275
25275
|
max: max.toString(),
|
|
25276
|
-
min:
|
|
25276
|
+
min: min.toString(),
|
|
25277
25277
|
signed,
|
|
25278
25278
|
size: size5 / 8,
|
|
25279
25279
|
value: value.toString()
|
|
@@ -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,18 @@ 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
|
-
|
|
35222
|
-
|
|
35223
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35223
|
+
kernel: CREATE2_KERNEL,
|
|
35224
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35225
|
+
governance: CREATE2_GOVERNANCE,
|
|
35224
35226
|
dispatchModel: "selective",
|
|
35225
35227
|
protocols: {}
|
|
35226
35228
|
},
|
|
@@ -35229,11 +35231,9 @@ var chains = {
|
|
|
35229
35231
|
chainId: 8453,
|
|
35230
35232
|
name: "Base",
|
|
35231
35233
|
rpcEnvVar: "BASE_RPC_URL",
|
|
35232
|
-
|
|
35233
|
-
|
|
35234
|
-
|
|
35235
|
-
mandateFactory: "0x14EDd6c2a56EfC0d71E215ab13094B9AF90543d2",
|
|
35236
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35234
|
+
kernel: CREATE2_KERNEL,
|
|
35235
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35236
|
+
governance: CREATE2_GOVERNANCE,
|
|
35237
35237
|
dispatchModel: "selective",
|
|
35238
35238
|
protocols: {}
|
|
35239
35239
|
},
|
|
@@ -35242,11 +35242,20 @@ var chains = {
|
|
|
35242
35242
|
chainId: 42161,
|
|
35243
35243
|
name: "Arbitrum",
|
|
35244
35244
|
rpcEnvVar: "ARBITRUM_RPC_URL",
|
|
35245
|
-
|
|
35246
|
-
|
|
35247
|
-
|
|
35248
|
-
|
|
35249
|
-
|
|
35245
|
+
kernel: CREATE2_KERNEL,
|
|
35246
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35247
|
+
governance: CREATE2_GOVERNANCE,
|
|
35248
|
+
dispatchModel: "selective",
|
|
35249
|
+
protocols: {}
|
|
35250
|
+
},
|
|
35251
|
+
// Optimism mainnet
|
|
35252
|
+
10: {
|
|
35253
|
+
chainId: 10,
|
|
35254
|
+
name: "Optimism",
|
|
35255
|
+
rpcEnvVar: "OPTIMISM_RPC_URL",
|
|
35256
|
+
kernel: CREATE2_KERNEL,
|
|
35257
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35258
|
+
governance: CREATE2_GOVERNANCE,
|
|
35250
35259
|
dispatchModel: "selective",
|
|
35251
35260
|
protocols: {}
|
|
35252
35261
|
},
|
|
@@ -35255,11 +35264,53 @@ var chains = {
|
|
|
35255
35264
|
chainId: 130,
|
|
35256
35265
|
name: "Unichain",
|
|
35257
35266
|
rpcEnvVar: "UNICHAIN_RPC_URL",
|
|
35258
|
-
|
|
35259
|
-
|
|
35260
|
-
|
|
35261
|
-
|
|
35262
|
-
|
|
35267
|
+
kernel: CREATE2_KERNEL,
|
|
35268
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35269
|
+
governance: CREATE2_GOVERNANCE,
|
|
35270
|
+
dispatchModel: "selective",
|
|
35271
|
+
protocols: {}
|
|
35272
|
+
},
|
|
35273
|
+
// BSC mainnet
|
|
35274
|
+
56: {
|
|
35275
|
+
chainId: 56,
|
|
35276
|
+
name: "BSC",
|
|
35277
|
+
rpcEnvVar: "BSC_RPC_URL",
|
|
35278
|
+
kernel: CREATE2_KERNEL,
|
|
35279
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35280
|
+
governance: CREATE2_GOVERNANCE,
|
|
35281
|
+
dispatchModel: "selective",
|
|
35282
|
+
protocols: {}
|
|
35283
|
+
},
|
|
35284
|
+
// World Chain mainnet
|
|
35285
|
+
480: {
|
|
35286
|
+
chainId: 480,
|
|
35287
|
+
name: "World Chain",
|
|
35288
|
+
rpcEnvVar: "WORLD_RPC_URL",
|
|
35289
|
+
kernel: CREATE2_KERNEL,
|
|
35290
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35291
|
+
governance: CREATE2_GOVERNANCE,
|
|
35292
|
+
dispatchModel: "selective",
|
|
35293
|
+
protocols: {}
|
|
35294
|
+
},
|
|
35295
|
+
// HyperEVM mainnet
|
|
35296
|
+
999: {
|
|
35297
|
+
chainId: 999,
|
|
35298
|
+
name: "HyperEVM",
|
|
35299
|
+
rpcEnvVar: "HYPEREVM_RPC_URL",
|
|
35300
|
+
kernel: CREATE2_KERNEL,
|
|
35301
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35302
|
+
governance: CREATE2_GOVERNANCE,
|
|
35303
|
+
dispatchModel: "selective",
|
|
35304
|
+
protocols: {}
|
|
35305
|
+
},
|
|
35306
|
+
// MegaETH mainnet
|
|
35307
|
+
4326: {
|
|
35308
|
+
chainId: 4326,
|
|
35309
|
+
name: "MegaETH",
|
|
35310
|
+
rpcEnvVar: "MEGAETH_RPC_URL",
|
|
35311
|
+
kernel: CREATE2_KERNEL,
|
|
35312
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35313
|
+
governance: CREATE2_GOVERNANCE,
|
|
35263
35314
|
dispatchModel: "selective",
|
|
35264
35315
|
protocols: {}
|
|
35265
35316
|
},
|
|
@@ -35268,11 +35319,9 @@ var chains = {
|
|
|
35268
35319
|
chainId: 84532,
|
|
35269
35320
|
name: "Base Sepolia",
|
|
35270
35321
|
rpcEnvVar: "BASE_SEPOLIA_RPC_URL",
|
|
35271
|
-
|
|
35272
|
-
|
|
35273
|
-
|
|
35274
|
-
mandateFactory: "0x14EDd6c2a56EfC0d71E215ab13094B9AF90543d2",
|
|
35275
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35322
|
+
kernel: CREATE2_KERNEL,
|
|
35323
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35324
|
+
governance: CREATE2_GOVERNANCE,
|
|
35276
35325
|
dispatchModel: "selective",
|
|
35277
35326
|
protocols: {}
|
|
35278
35327
|
},
|
|
@@ -35281,10 +35330,9 @@ var chains = {
|
|
|
35281
35330
|
chainId: 11155111,
|
|
35282
35331
|
name: "Eth Sepolia",
|
|
35283
35332
|
rpcEnvVar: "SEPOLIA_RPC_URL",
|
|
35284
|
-
|
|
35285
|
-
|
|
35286
|
-
|
|
35287
|
-
governance: "0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC",
|
|
35333
|
+
kernel: CREATE2_KERNEL,
|
|
35334
|
+
mandateFactory: CREATE2_MANDATE_FACTORY,
|
|
35335
|
+
governance: CREATE2_GOVERNANCE,
|
|
35288
35336
|
dispatchModel: "selective",
|
|
35289
35337
|
protocols: {}
|
|
35290
35338
|
}
|
|
@@ -35292,7 +35340,7 @@ var chains = {
|
|
|
35292
35340
|
function getChain(chainId) {
|
|
35293
35341
|
const config = chains[chainId];
|
|
35294
35342
|
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).`);
|
|
35343
|
+
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
35344
|
}
|
|
35297
35345
|
return config;
|
|
35298
35346
|
}
|
|
@@ -35319,6 +35367,10 @@ var SailKernelAbi = [
|
|
|
35319
35367
|
],
|
|
35320
35368
|
outputs: [{ name: "account", type: "address" }]
|
|
35321
35369
|
},
|
|
35370
|
+
// Post-#53: two-step registration. Requires msg.sender == the Safe (trusted-proxy
|
|
35371
|
+
// codehash + trusted-singleton pin) and a Safe owner signature over the
|
|
35372
|
+
// RegisterAccount EIP-712 digest (verified via checkSignatures). Must be submitted
|
|
35373
|
+
// through the Safe's execTransaction, not the owner EOA. See buildRegisterAccountTypedData.
|
|
35322
35374
|
{
|
|
35323
35375
|
type: "function",
|
|
35324
35376
|
name: "registerAccount",
|
|
@@ -35326,7 +35378,10 @@ var SailKernelAbi = [
|
|
|
35326
35378
|
inputs: [
|
|
35327
35379
|
{ name: "permissionSigner", type: "address" },
|
|
35328
35380
|
{ name: "manager", type: "address" },
|
|
35329
|
-
{ name: "feePolicy", type: "address" }
|
|
35381
|
+
{ name: "feePolicy", type: "address" },
|
|
35382
|
+
{ name: "feeAsset", type: "address" },
|
|
35383
|
+
{ name: "deadline", type: "uint256" },
|
|
35384
|
+
{ name: "ownerSig", type: "bytes" }
|
|
35330
35385
|
],
|
|
35331
35386
|
outputs: []
|
|
35332
35387
|
},
|
|
@@ -35377,6 +35432,32 @@ var SailKernelAbi = [
|
|
|
35377
35432
|
],
|
|
35378
35433
|
outputs: []
|
|
35379
35434
|
},
|
|
35435
|
+
// ── Session kill switch ───────────────────────────────────────────────────
|
|
35436
|
+
// Suspend/resume manager dispatch rights. Both are permissionSigner-signed
|
|
35437
|
+
// (RevokeSession/ActivateSession EIP-712, nonce = signerNonces[account]) and
|
|
35438
|
+
// rotate the manager/batch nonce epochs so any pre-signed dispatch is invalidated.
|
|
35439
|
+
{
|
|
35440
|
+
type: "function",
|
|
35441
|
+
name: "revokeSession",
|
|
35442
|
+
stateMutability: "nonpayable",
|
|
35443
|
+
inputs: [
|
|
35444
|
+
{ name: "account", type: "address" },
|
|
35445
|
+
{ name: "deadline", type: "uint256" },
|
|
35446
|
+
{ name: "sig", type: "bytes" }
|
|
35447
|
+
],
|
|
35448
|
+
outputs: []
|
|
35449
|
+
},
|
|
35450
|
+
{
|
|
35451
|
+
type: "function",
|
|
35452
|
+
name: "activateSession",
|
|
35453
|
+
stateMutability: "nonpayable",
|
|
35454
|
+
inputs: [
|
|
35455
|
+
{ name: "account", type: "address" },
|
|
35456
|
+
{ name: "deadline", type: "uint256" },
|
|
35457
|
+
{ name: "sig", type: "bytes" }
|
|
35458
|
+
],
|
|
35459
|
+
outputs: []
|
|
35460
|
+
},
|
|
35380
35461
|
// ── Manager dispatch ──────────────────────────────────────────────────────
|
|
35381
35462
|
{
|
|
35382
35463
|
type: "function",
|
|
@@ -35516,6 +35597,7 @@ var SailKernelAbi = [
|
|
|
35516
35597
|
{ name: "permissionSigner", type: "address" },
|
|
35517
35598
|
{ name: "manager", type: "address" },
|
|
35518
35599
|
{ name: "feePolicy", type: "address" },
|
|
35600
|
+
{ name: "feeAsset", type: "address" },
|
|
35519
35601
|
{ name: "sessionActive", type: "bool" }
|
|
35520
35602
|
]
|
|
35521
35603
|
},
|
|
@@ -35709,148 +35791,142 @@ async function detectKernelCapabilities(publicClient, kernel, opts) {
|
|
|
35709
35791
|
}
|
|
35710
35792
|
|
|
35711
35793
|
// ../sdk/dist/deployments.js
|
|
35712
|
-
var
|
|
35713
|
-
var
|
|
35714
|
-
var CREATE2_TIMELOCK = "
|
|
35794
|
+
var CREATE2_KERNEL2 = "0x38b508756c976e876EFF05a29E731A4d348BA6ED";
|
|
35795
|
+
var CREATE2_GOVERNANCE2 = "0x4315B37cA4A315A7042af1Fcb37F8436f4D24356";
|
|
35796
|
+
var CREATE2_TIMELOCK = "0xC1E5F9A581D4100Aa949f80204540a33aD97A7b6";
|
|
35715
35797
|
var CREATE2_SAFE_MODULE_ENABLER = "0x7897Cb53a4be4a2eaAf46D60573C4Fd83b33fE1F";
|
|
35716
|
-
var
|
|
35717
|
-
var CREATE2_STANDARD_FEE_POLICY = "
|
|
35718
|
-
var
|
|
35798
|
+
var CREATE2_MANDATE_FACTORY2 = "0x6d2C802ffa0d9A8Ed69A5Bf22c1b63ccB566B8Fc";
|
|
35799
|
+
var CREATE2_STANDARD_FEE_POLICY = "0x1087312447C8a2BfA15EB9cE23590E3502DBA04b";
|
|
35800
|
+
var CREATE2_DEPLOYER = "0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6";
|
|
35801
|
+
var CREATE2_TREASURY = "0x7b37F85575F1568a37dBA342BC5FE6d393F0872f";
|
|
35802
|
+
var CREATE2_MAX_PERMISSION_FEE_WEI = 10000000000000000n;
|
|
35803
|
+
var CREATE2_TEMPLATES = {
|
|
35804
|
+
swap: "0x35cEEa0db96997Cc3CF3beB42FFa36A499342F7C",
|
|
35805
|
+
swapNoOracle: "0x34Ba96CbEd1f46c88A5265E645DC5fe41662b519",
|
|
35806
|
+
borrow: "0x3e2666051599223cEAb10De55C89A0842857d8AF",
|
|
35807
|
+
deposit: "0xBfB5e13a97b12Ee89d2F2b9B65eCf7e0E371911f",
|
|
35808
|
+
withdraw: "0xF5eF5dda450a130e3020d54f565E830e4a7531f8",
|
|
35809
|
+
transfer: "0xda909a1CC584fb7559Ce4A828b008B473Da095e1",
|
|
35810
|
+
approveAndCallBatch: "0x0535A4D51333484ef583103DAB1a9449756ab732"
|
|
35811
|
+
};
|
|
35812
|
+
var CREATE2_KNOWN_TEMPLATES = [
|
|
35813
|
+
{ kind: "SwapPermission", address: CREATE2_TEMPLATES.swap, label: "Swap" },
|
|
35814
|
+
{
|
|
35815
|
+
kind: "SwapPermissionNoOracle",
|
|
35816
|
+
address: CREATE2_TEMPLATES.swapNoOracle,
|
|
35817
|
+
label: "Swap (no oracle)"
|
|
35818
|
+
},
|
|
35819
|
+
{ kind: "BorrowPermission", address: CREATE2_TEMPLATES.borrow, label: "Borrow" },
|
|
35820
|
+
{ kind: "DepositPermission", address: CREATE2_TEMPLATES.deposit, label: "Deposit" },
|
|
35821
|
+
{ kind: "WithdrawPermission", address: CREATE2_TEMPLATES.withdraw, label: "Withdraw" },
|
|
35822
|
+
{ kind: "TransferPermission", address: CREATE2_TEMPLATES.transfer, label: "Transfer" },
|
|
35823
|
+
{
|
|
35824
|
+
kind: "ApproveAndCallBatchPermission",
|
|
35825
|
+
address: CREATE2_TEMPLATES.approveAndCallBatch,
|
|
35826
|
+
label: "Approve + call batch"
|
|
35827
|
+
}
|
|
35828
|
+
];
|
|
35829
|
+
var COMMON_DEPLOYMENT_FIELDS = {
|
|
35830
|
+
deployer: CREATE2_DEPLOYER,
|
|
35831
|
+
governance: CREATE2_GOVERNANCE2,
|
|
35832
|
+
timelock: CREATE2_TIMELOCK,
|
|
35833
|
+
kernel: CREATE2_KERNEL2,
|
|
35834
|
+
mandateFactory: CREATE2_MANDATE_FACTORY2,
|
|
35835
|
+
standardFeePolicy: CREATE2_STANDARD_FEE_POLICY,
|
|
35836
|
+
safeModuleEnabler: CREATE2_SAFE_MODULE_ENABLER,
|
|
35837
|
+
treasury: CREATE2_TREASURY,
|
|
35838
|
+
maxPermissionFeeWei: CREATE2_MAX_PERMISSION_FEE_WEI,
|
|
35839
|
+
initialBaseFee: 0n,
|
|
35840
|
+
initialComplexityRate: 0n,
|
|
35841
|
+
dispatchModel: "selective",
|
|
35842
|
+
// The seven launch templates are SHARED multi-tenant ConfigurablePermission instances
|
|
35843
|
+
// (registered by address, configured via configure()), NOT EIP-1167 clone logic. They
|
|
35844
|
+
// belong in knownTemplates only. standaloneTemplates is the clone-implementation registry
|
|
35845
|
+
// (the `impl` arg to MandateFactory.deployAndAttach) — empty until standalone clones deploy.
|
|
35846
|
+
// Populating it with shared templates mislabels them as unaudited community clones in
|
|
35847
|
+
// `sailor mandate templates` and makes capabilities advertise them as deployAndAttach-able.
|
|
35848
|
+
standaloneTemplates: {}
|
|
35849
|
+
};
|
|
35850
|
+
function knownTemplatesFor(chainId) {
|
|
35851
|
+
return CREATE2_KNOWN_TEMPLATES.map((t) => ({ ...t, chainId }));
|
|
35852
|
+
}
|
|
35719
35853
|
var sailDeployments = {
|
|
35720
35854
|
// ── Ethereum mainnet ─────────────────────────────────────────────────────────
|
|
35721
35855
|
1: {
|
|
35722
|
-
|
|
35723
|
-
// allowlistBootstrapped=true (genesis bootstrap), zero fees, 48h timelock.
|
|
35856
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35724
35857
|
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: {}
|
|
35858
|
+
blockNumber: 25432741,
|
|
35859
|
+
knownTemplates: knownTemplatesFor(1)
|
|
35740
35860
|
},
|
|
35741
35861
|
// ── Base mainnet ─────────────────────────────────────────────────────────────
|
|
35742
35862
|
8453: {
|
|
35743
|
-
|
|
35744
|
-
// 0x6319d3dfDDe3804ba93D65752b00c52bFb05a1ab (SAIL-405 redeploy).
|
|
35745
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35863
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35746
35864
|
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: {}
|
|
35865
|
+
blockNumber: 48029413,
|
|
35866
|
+
knownTemplates: knownTemplatesFor(8453)
|
|
35762
35867
|
},
|
|
35763
35868
|
// ── Arbitrum mainnet ─────────────────────────────────────────────────────────
|
|
35764
35869
|
42161: {
|
|
35765
|
-
|
|
35766
|
-
// 0x2716B12832DED0EF5688519c5Fe069EFc0374E02 (SAIL-405 redeploy).
|
|
35767
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35870
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35768
35871
|
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: {}
|
|
35872
|
+
blockNumber: 25432669,
|
|
35873
|
+
knownTemplates: knownTemplatesFor(42161)
|
|
35874
|
+
},
|
|
35875
|
+
// ── Optimism mainnet ─────────────────────────────────────────────────────────
|
|
35876
|
+
10: {
|
|
35877
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35878
|
+
chainId: 10,
|
|
35879
|
+
blockNumber: 153625159,
|
|
35880
|
+
knownTemplates: knownTemplatesFor(10)
|
|
35784
35881
|
},
|
|
35785
35882
|
// ── Unichain mainnet ─────────────────────────────────────────────────────────
|
|
35786
35883
|
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.
|
|
35884
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35792
35885
|
chainId: 130,
|
|
35793
|
-
blockNumber:
|
|
35794
|
-
|
|
35795
|
-
|
|
35796
|
-
|
|
35797
|
-
|
|
35798
|
-
|
|
35799
|
-
|
|
35800
|
-
|
|
35801
|
-
|
|
35802
|
-
|
|
35803
|
-
|
|
35804
|
-
|
|
35805
|
-
|
|
35806
|
-
|
|
35807
|
-
|
|
35808
|
-
|
|
35809
|
-
|
|
35810
|
-
|
|
35886
|
+
blockNumber: 52100873,
|
|
35887
|
+
knownTemplates: knownTemplatesFor(130)
|
|
35888
|
+
},
|
|
35889
|
+
// ── BSC mainnet ──────────────────────────────────────────────────────────────
|
|
35890
|
+
56: {
|
|
35891
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35892
|
+
chainId: 56,
|
|
35893
|
+
blockNumber: 107312662,
|
|
35894
|
+
knownTemplates: knownTemplatesFor(56)
|
|
35895
|
+
},
|
|
35896
|
+
// ── World Chain mainnet ──────────────────────────────────────────────────────
|
|
35897
|
+
480: {
|
|
35898
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35899
|
+
chainId: 480,
|
|
35900
|
+
blockNumber: 31756901,
|
|
35901
|
+
knownTemplates: knownTemplatesFor(480)
|
|
35902
|
+
},
|
|
35903
|
+
// ── HyperEVM mainnet ─────────────────────────────────────────────────────────
|
|
35904
|
+
999: {
|
|
35905
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35906
|
+
chainId: 999,
|
|
35907
|
+
blockNumber: 39238629,
|
|
35908
|
+
knownTemplates: knownTemplatesFor(999)
|
|
35909
|
+
},
|
|
35910
|
+
// ── MegaETH mainnet ──────────────────────────────────────────────────────────
|
|
35911
|
+
4326: {
|
|
35912
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35913
|
+
chainId: 4326,
|
|
35914
|
+
blockNumber: 20056530,
|
|
35915
|
+
knownTemplates: knownTemplatesFor(4326)
|
|
35811
35916
|
},
|
|
35812
35917
|
// ── Base Sepolia (testnet) ───────────────────────────────────────────────────
|
|
35813
35918
|
84532: {
|
|
35814
|
-
|
|
35815
|
-
// 0xf1D0F4C9893612627409948BAa9d82a01a373799 (SAIL-405 redeploy).
|
|
35816
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35919
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35817
35920
|
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: {}
|
|
35921
|
+
blockNumber: 43539604,
|
|
35922
|
+
knownTemplates: knownTemplatesFor(84532)
|
|
35833
35923
|
},
|
|
35834
35924
|
// ── Eth Sepolia (testnet) ────────────────────────────────────────────────────
|
|
35835
35925
|
11155111: {
|
|
35836
|
-
|
|
35837
|
-
// allowlistBootstrapped=true, zero fees, 48h timelock.
|
|
35926
|
+
...COMMON_DEPLOYMENT_FIELDS,
|
|
35838
35927
|
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: {}
|
|
35928
|
+
blockNumber: 11174750,
|
|
35929
|
+
knownTemplates: knownTemplatesFor(11155111)
|
|
35854
35930
|
}
|
|
35855
35931
|
};
|
|
35856
35932
|
function getSailDeployment(chainId) {
|
|
@@ -35861,122 +35937,6 @@ function getSailDeployment(chainId) {
|
|
|
35861
35937
|
return deployment;
|
|
35862
35938
|
}
|
|
35863
35939
|
|
|
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
35940
|
// ../sdk/dist/eip712.js
|
|
35981
35941
|
init_esm2();
|
|
35982
35942
|
function sailKernelDomain(args) {
|
|
@@ -36114,6 +36074,197 @@ function buildRegisterPermissionsBatchTypedData(args) {
|
|
|
36114
36074
|
}
|
|
36115
36075
|
};
|
|
36116
36076
|
}
|
|
36077
|
+
var TEMPLATE_EIP712_DOMAIN_ABI = [
|
|
36078
|
+
{
|
|
36079
|
+
type: "function",
|
|
36080
|
+
name: "eip712Domain",
|
|
36081
|
+
stateMutability: "view",
|
|
36082
|
+
inputs: [],
|
|
36083
|
+
outputs: [
|
|
36084
|
+
{ name: "fields", type: "bytes1" },
|
|
36085
|
+
{ name: "name", type: "string" },
|
|
36086
|
+
{ name: "version", type: "string" },
|
|
36087
|
+
{ name: "chainId", type: "uint256" },
|
|
36088
|
+
{ name: "verifyingContract", type: "address" },
|
|
36089
|
+
{ name: "salt", type: "bytes32" },
|
|
36090
|
+
{ name: "extensions", type: "uint256[]" }
|
|
36091
|
+
]
|
|
36092
|
+
}
|
|
36093
|
+
];
|
|
36094
|
+
var REGISTRATION_EPOCH_ABI = [
|
|
36095
|
+
{
|
|
36096
|
+
type: "function",
|
|
36097
|
+
name: "registrationEpoch",
|
|
36098
|
+
stateMutability: "view",
|
|
36099
|
+
inputs: [
|
|
36100
|
+
{ name: "account", type: "address" },
|
|
36101
|
+
{ name: "permission", type: "address" }
|
|
36102
|
+
],
|
|
36103
|
+
outputs: [{ type: "uint256" }]
|
|
36104
|
+
}
|
|
36105
|
+
];
|
|
36106
|
+
var CONFIGURE_FIELDS_V1 = [
|
|
36107
|
+
{ name: "account", type: "address" },
|
|
36108
|
+
{ name: "paramsHash", type: "bytes32" },
|
|
36109
|
+
{ name: "nonce", type: "uint256" },
|
|
36110
|
+
{ name: "deadline", type: "uint256" }
|
|
36111
|
+
];
|
|
36112
|
+
var CONFIGURE_FIELDS_V2 = [...CONFIGURE_FIELDS_V1, { name: "epoch", type: "uint256" }];
|
|
36113
|
+
async function buildConfigureTypedData(args) {
|
|
36114
|
+
const [, name, version4, chainId] = await args.publicClient.readContract({
|
|
36115
|
+
address: args.template,
|
|
36116
|
+
abi: TEMPLATE_EIP712_DOMAIN_ABI,
|
|
36117
|
+
functionName: "eip712Domain"
|
|
36118
|
+
});
|
|
36119
|
+
if (version4 !== "1" && version4 !== "2") {
|
|
36120
|
+
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.`);
|
|
36121
|
+
}
|
|
36122
|
+
const isV2 = version4 === "2";
|
|
36123
|
+
const message = {
|
|
36124
|
+
account: args.account,
|
|
36125
|
+
paramsHash: keccak256(args.params),
|
|
36126
|
+
nonce: args.nonce.toString(),
|
|
36127
|
+
deadline: args.deadline.toString()
|
|
36128
|
+
};
|
|
36129
|
+
if (isV2) {
|
|
36130
|
+
const epoch = await args.publicClient.readContract({
|
|
36131
|
+
address: args.kernel,
|
|
36132
|
+
abi: REGISTRATION_EPOCH_ABI,
|
|
36133
|
+
functionName: "registrationEpoch",
|
|
36134
|
+
args: [args.account, args.template]
|
|
36135
|
+
});
|
|
36136
|
+
message.epoch = epoch.toString();
|
|
36137
|
+
}
|
|
36138
|
+
return {
|
|
36139
|
+
domain: {
|
|
36140
|
+
name,
|
|
36141
|
+
version: version4,
|
|
36142
|
+
chainId: Number(chainId),
|
|
36143
|
+
verifyingContract: args.template
|
|
36144
|
+
},
|
|
36145
|
+
types: {
|
|
36146
|
+
Configure: isV2 ? CONFIGURE_FIELDS_V2 : CONFIGURE_FIELDS_V1
|
|
36147
|
+
},
|
|
36148
|
+
primaryType: "Configure",
|
|
36149
|
+
message
|
|
36150
|
+
};
|
|
36151
|
+
}
|
|
36152
|
+
|
|
36153
|
+
// ../sdk/dist/errors.js
|
|
36154
|
+
init_esm2();
|
|
36155
|
+
var KERNEL_ERROR_SIGNATURES = [
|
|
36156
|
+
"error AccountAlreadyRegistered(address account)",
|
|
36157
|
+
"error AccountNotRegistered(address account)",
|
|
36158
|
+
"error AccountSelfTarget()",
|
|
36159
|
+
"error ArrayLengthMismatch()",
|
|
36160
|
+
"error BatchPermissionDenied()",
|
|
36161
|
+
"error BatchSubcallFailed(uint256 index, address target)",
|
|
36162
|
+
"error BatchTooLong(uint256 length)",
|
|
36163
|
+
"error BatchZeroTarget(uint256 index)",
|
|
36164
|
+
"error DeadlineExpired(uint256 deadline, uint256 current)",
|
|
36165
|
+
"error DistributorBpsTooLarge(uint256 bps)",
|
|
36166
|
+
"error EmptyBatch()",
|
|
36167
|
+
"error FeePolicyNotSet()",
|
|
36168
|
+
"error FeeTokenMismatch(address provided, address expected)",
|
|
36169
|
+
"error FeeTooLarge(uint256 requested, uint256 maxAllowed)",
|
|
36170
|
+
"error FeeTransferFailed()",
|
|
36171
|
+
"error InsufficientFee(uint256 required, uint256 provided)",
|
|
36172
|
+
"error InvalidInitializer()",
|
|
36173
|
+
"error InvalidManagerSignature()",
|
|
36174
|
+
"error InvalidSignerSignature()",
|
|
36175
|
+
"error KernelSelfTarget(uint256 index)",
|
|
36176
|
+
// SAIL-405: setManager rejects a no-op rotation (newManager == current).
|
|
36177
|
+
"error ManagerUnchanged()",
|
|
36178
|
+
"error ModuleNotEnabled()",
|
|
36179
|
+
// Present in the deployed conjunctive kernel; dropped in the latest source.
|
|
36180
|
+
"error NoPermissionsRegistered(address account)",
|
|
36181
|
+
"error NotAContract(address addr)",
|
|
36182
|
+
"error NotGovernance()",
|
|
36183
|
+
"error NotManager(address caller, address expected)",
|
|
36184
|
+
"error NotPermissionSigner()",
|
|
36185
|
+
"error NotTimelock()",
|
|
36186
|
+
"error PermissionAlreadyRegistered(address permission)",
|
|
36187
|
+
"error PermissionDenied(address permission)",
|
|
36188
|
+
"error PermissionNotBatchAware(address permission)",
|
|
36189
|
+
"error PermissionNotRegistered(address permission)",
|
|
36190
|
+
"error ProtocolPaused()",
|
|
36191
|
+
"error SafeExecutionFailed()",
|
|
36192
|
+
"error SessionInactive(address account)",
|
|
36193
|
+
"error TooManyPermissions(address account, uint256 limit)",
|
|
36194
|
+
"error UntrustedFactory(address factory)",
|
|
36195
|
+
"error UntrustedFeePolicy(address policy)",
|
|
36196
|
+
"error UntrustedModuleSetup(address setup)",
|
|
36197
|
+
"error UntrustedProxyCodehash(bytes32 codehash)",
|
|
36198
|
+
"error UntrustedSingleton(address singleton)",
|
|
36199
|
+
"error ZeroAddress()",
|
|
36200
|
+
"error ZeroFee()"
|
|
36201
|
+
];
|
|
36202
|
+
var KERNEL_ERROR_ABI = parseAbi(KERNEL_ERROR_SIGNATURES);
|
|
36203
|
+
var ERROR_HINTS = {
|
|
36204
|
+
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.",
|
|
36205
|
+
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.",
|
|
36206
|
+
NoPermissionsRegistered: "The account has zero registered permissions, so the kernel denies by default. Register at least one permission (kernel.registerPermission / registerPermissions) before dispatching.",
|
|
36207
|
+
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.",
|
|
36208
|
+
SessionInactive: "The manager's session is revoked. Re-activate it (session.activate) before dispatching.",
|
|
36209
|
+
DeadlineExpired: "The signature deadline is in the past. Use a deadline comfortably ahead of block.timestamp.",
|
|
36210
|
+
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).",
|
|
36211
|
+
ModuleNotEnabled: "The Sail module is not enabled on the Safe. Complete account onboarding (enable the module) first.",
|
|
36212
|
+
ProtocolPaused: "The protocol is paused by governance. Dispatches are blocked until it is unpaused.",
|
|
36213
|
+
NotManager: "The submitting address is not the registered manager for this account.",
|
|
36214
|
+
TooManyPermissions: "Registering this permission would exceed the kernel's per-account permission cap. Revoke an unused permission first."
|
|
36215
|
+
};
|
|
36216
|
+
async function decode2(data) {
|
|
36217
|
+
const { decodeErrorResult: decodeErrorResult2 } = await Promise.resolve().then(() => (init_esm2(), esm_exports2));
|
|
36218
|
+
try {
|
|
36219
|
+
const decoded = decodeErrorResult2({ abi: KERNEL_ERROR_ABI, data });
|
|
36220
|
+
const name = decoded.errorName;
|
|
36221
|
+
const args = decoded.args ?? [];
|
|
36222
|
+
const selector = data.slice(0, 10);
|
|
36223
|
+
const hint = ERROR_HINTS[name];
|
|
36224
|
+
const argStr = args.length ? `(${args.map(String).join(", ")})` : "()";
|
|
36225
|
+
const message = hint ? `${name}${argStr} \u2014 ${hint}` : `${name}${argStr}`;
|
|
36226
|
+
return { name, args, selector, hint, message };
|
|
36227
|
+
} catch {
|
|
36228
|
+
return null;
|
|
36229
|
+
}
|
|
36230
|
+
}
|
|
36231
|
+
function decodeKernelError(data) {
|
|
36232
|
+
if (!data || data === "0x")
|
|
36233
|
+
return Promise.resolve(null);
|
|
36234
|
+
return decode2(data);
|
|
36235
|
+
}
|
|
36236
|
+
async function explainKernelRevert(err) {
|
|
36237
|
+
const data = extractRevertData(err);
|
|
36238
|
+
if (!data)
|
|
36239
|
+
return null;
|
|
36240
|
+
return decodeKernelError(data);
|
|
36241
|
+
}
|
|
36242
|
+
function extractRevertData(err) {
|
|
36243
|
+
const seen = /* @__PURE__ */ new Set();
|
|
36244
|
+
let cursor = err;
|
|
36245
|
+
let depth = 0;
|
|
36246
|
+
while (cursor && typeof cursor === "object" && !seen.has(cursor) && depth < 12) {
|
|
36247
|
+
seen.add(cursor);
|
|
36248
|
+
depth++;
|
|
36249
|
+
const obj = cursor;
|
|
36250
|
+
const data = obj["data"];
|
|
36251
|
+
if (typeof data === "string" && data.startsWith("0x") && data.length >= 10) {
|
|
36252
|
+
return data;
|
|
36253
|
+
}
|
|
36254
|
+
if (data && typeof data === "object") {
|
|
36255
|
+
const inner = data["data"];
|
|
36256
|
+
if (typeof inner === "string" && inner.startsWith("0x") && inner.length >= 10) {
|
|
36257
|
+
return inner;
|
|
36258
|
+
}
|
|
36259
|
+
}
|
|
36260
|
+
const raw = obj["raw"];
|
|
36261
|
+
if (typeof raw === "string" && raw.startsWith("0x") && raw.length >= 10) {
|
|
36262
|
+
return raw;
|
|
36263
|
+
}
|
|
36264
|
+
cursor = obj["cause"];
|
|
36265
|
+
}
|
|
36266
|
+
return null;
|
|
36267
|
+
}
|
|
36117
36268
|
|
|
36118
36269
|
// ../sdk/dist/lifi.js
|
|
36119
36270
|
init_esm2();
|
|
@@ -36181,9 +36332,30 @@ function buildPublicClient(config) {
|
|
|
36181
36332
|
function defaultDeadline() {
|
|
36182
36333
|
return BigInt(Math.floor(Date.now() / 1e3) + 300);
|
|
36183
36334
|
}
|
|
36335
|
+
var CONFIGURABLE_PERMISSION_ABI = [
|
|
36336
|
+
{
|
|
36337
|
+
type: "function",
|
|
36338
|
+
name: "configNonces",
|
|
36339
|
+
stateMutability: "view",
|
|
36340
|
+
inputs: [{ name: "account", type: "address" }],
|
|
36341
|
+
outputs: [{ type: "uint256" }]
|
|
36342
|
+
},
|
|
36343
|
+
{
|
|
36344
|
+
type: "function",
|
|
36345
|
+
name: "configure",
|
|
36346
|
+
stateMutability: "nonpayable",
|
|
36347
|
+
inputs: [
|
|
36348
|
+
{ name: "account", type: "address" },
|
|
36349
|
+
{ name: "params", type: "bytes" },
|
|
36350
|
+
{ name: "deadline", type: "uint256" },
|
|
36351
|
+
{ name: "sig", type: "bytes" }
|
|
36352
|
+
],
|
|
36353
|
+
outputs: []
|
|
36354
|
+
}
|
|
36355
|
+
];
|
|
36184
36356
|
var DEFAULT_DISPATCH_GAS = 2000000n;
|
|
36185
36357
|
function delay(ms) {
|
|
36186
|
-
return new Promise((
|
|
36358
|
+
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
36187
36359
|
}
|
|
36188
36360
|
var CALL_COMPONENTS = [
|
|
36189
36361
|
{ name: "target", type: "address" },
|
|
@@ -36337,8 +36509,47 @@ var MandateNamespace = class extends KernelNamespace {
|
|
|
36337
36509
|
value: 0n
|
|
36338
36510
|
});
|
|
36339
36511
|
}
|
|
36340
|
-
|
|
36341
|
-
|
|
36512
|
+
/**
|
|
36513
|
+
* Re-configure the per-account bounds of an already-registered shared template.
|
|
36514
|
+
* The permission signer signs the template's `Configure` EIP-712 struct — built by
|
|
36515
|
+
* `buildConfigureTypedData`, which reads the template's live ERC-5267 domain and emits
|
|
36516
|
+
* the v1 or v2 (epoch-bound) schema to match whatever is deployed — and the attached
|
|
36517
|
+
* wallet submits `configure(account, params, deadline, sig)`.
|
|
36518
|
+
*
|
|
36519
|
+
* The config nonce is read fresh on-chain immediately before signing (the template
|
|
36520
|
+
* increments it only after a successful verify), so a re-config never reuses a stale nonce.
|
|
36521
|
+
*/
|
|
36522
|
+
async reconfigure(safe, template, params, signer) {
|
|
36523
|
+
const kernel = this.requireKernel();
|
|
36524
|
+
const wallet = this.requireSigner();
|
|
36525
|
+
const encoded = template.encoder.encode(params);
|
|
36526
|
+
const deadline = defaultDeadline();
|
|
36527
|
+
const nonce = await this.publicClient.readContract({
|
|
36528
|
+
address: template.address,
|
|
36529
|
+
abi: CONFIGURABLE_PERMISSION_ABI,
|
|
36530
|
+
functionName: "configNonces",
|
|
36531
|
+
args: [safe]
|
|
36532
|
+
});
|
|
36533
|
+
const td = await buildConfigureTypedData({
|
|
36534
|
+
publicClient: this.publicClient,
|
|
36535
|
+
kernel,
|
|
36536
|
+
template: template.address,
|
|
36537
|
+
account: safe,
|
|
36538
|
+
params: encoded,
|
|
36539
|
+
nonce,
|
|
36540
|
+
deadline
|
|
36541
|
+
});
|
|
36542
|
+
const sig = await signer.signTyped(td.domain, { primaryType: td.primaryType, types: td.types }, td.message);
|
|
36543
|
+
const txHash = await wallet.writeContract({
|
|
36544
|
+
address: template.address,
|
|
36545
|
+
abi: CONFIGURABLE_PERMISSION_ABI,
|
|
36546
|
+
functionName: "configure",
|
|
36547
|
+
args: [safe, encoded, deadline, sig]
|
|
36548
|
+
});
|
|
36549
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
36550
|
+
if (receipt.status !== "success") {
|
|
36551
|
+
throw new Error(`configure reverted (tx ${txHash})`);
|
|
36552
|
+
}
|
|
36342
36553
|
}
|
|
36343
36554
|
replace(_safe, _oldTemplate, _newTemplate, _params, _signer) {
|
|
36344
36555
|
return notImplemented();
|
|
@@ -36637,14 +36848,67 @@ var StrategyNamespace = class extends KernelNamespace {
|
|
|
36637
36848
|
}
|
|
36638
36849
|
};
|
|
36639
36850
|
var SessionNamespace = class extends KernelNamespace {
|
|
36640
|
-
|
|
36641
|
-
|
|
36851
|
+
/**
|
|
36852
|
+
* Suspend (`revokeSession`) or resume (`activateSession`) the manager's dispatch rights.
|
|
36853
|
+
* Both are permissionSigner-signed over the RevokeSession/ActivateSession EIP-712 struct,
|
|
36854
|
+
* with `nonce` read fresh from `signerNonces[account]` immediately before signing — the
|
|
36855
|
+
* kernel bumps that nonce by a full epoch on revoke (#70), so it must never be cached. The
|
|
36856
|
+
* kernel also rotates the manager/batch nonce epochs, invalidating any pre-signed dispatch.
|
|
36857
|
+
*/
|
|
36858
|
+
async revoke(safe, signer) {
|
|
36859
|
+
await this.#submitSessionOp(safe, signer, "RevokeSession", "revokeSession");
|
|
36642
36860
|
}
|
|
36643
|
-
activate(
|
|
36644
|
-
|
|
36861
|
+
async activate(safe, signer) {
|
|
36862
|
+
await this.#submitSessionOp(safe, signer, "ActivateSession", "activateSession");
|
|
36645
36863
|
}
|
|
36646
|
-
|
|
36647
|
-
|
|
36864
|
+
async #submitSessionOp(safe, signer, primaryType, fn) {
|
|
36865
|
+
const kernel = this.requireKernel();
|
|
36866
|
+
const wallet = this.requireSigner();
|
|
36867
|
+
const deadline = defaultDeadline();
|
|
36868
|
+
const nonce = await this.publicClient.readContract({
|
|
36869
|
+
address: kernel,
|
|
36870
|
+
abi: SailKernelAbi,
|
|
36871
|
+
functionName: "signerNonces",
|
|
36872
|
+
args: [safe]
|
|
36873
|
+
});
|
|
36874
|
+
const sig = await signer.signTyped(sailKernelDomain({ chainId: this.config.chainId, kernel }), {
|
|
36875
|
+
primaryType,
|
|
36876
|
+
types: {
|
|
36877
|
+
[primaryType]: [
|
|
36878
|
+
{ name: "account", type: "address" },
|
|
36879
|
+
{ name: "nonce", type: "uint256" },
|
|
36880
|
+
{ name: "deadline", type: "uint256" }
|
|
36881
|
+
]
|
|
36882
|
+
}
|
|
36883
|
+
}, { account: safe, nonce, deadline });
|
|
36884
|
+
const txHash = await wallet.writeContract({
|
|
36885
|
+
address: kernel,
|
|
36886
|
+
abi: SailKernelAbi,
|
|
36887
|
+
functionName: fn,
|
|
36888
|
+
args: [safe, deadline, sig]
|
|
36889
|
+
});
|
|
36890
|
+
const receipt = await this.publicClient.waitForTransactionReceipt({ hash: txHash });
|
|
36891
|
+
if (receipt.status !== "success") {
|
|
36892
|
+
throw new Error(`${fn} reverted (tx ${txHash})`);
|
|
36893
|
+
}
|
|
36894
|
+
}
|
|
36895
|
+
async status(safe) {
|
|
36896
|
+
const kernel = this.requireKernel();
|
|
36897
|
+
const cfg = await this.publicClient.readContract({
|
|
36898
|
+
address: kernel,
|
|
36899
|
+
abi: SailKernelAbi,
|
|
36900
|
+
functionName: "configs",
|
|
36901
|
+
args: [safe]
|
|
36902
|
+
});
|
|
36903
|
+
return {
|
|
36904
|
+
safe,
|
|
36905
|
+
active: cfg[4],
|
|
36906
|
+
manager: cfg[1],
|
|
36907
|
+
// Block-level markers require an event scan; expose live active/manager state and
|
|
36908
|
+
// leave the historical timestamps null.
|
|
36909
|
+
activatedAtBlock: null,
|
|
36910
|
+
revokedAtBlock: null
|
|
36911
|
+
};
|
|
36648
36912
|
}
|
|
36649
36913
|
};
|
|
36650
36914
|
var FeesNamespace = class extends KernelNamespace {
|
|
@@ -37613,6 +37877,60 @@ var SailGovernanceAbi = [
|
|
|
37613
37877
|
}
|
|
37614
37878
|
];
|
|
37615
37879
|
|
|
37880
|
+
// ../sdk/dist/abis/ConfigurablePermission.js
|
|
37881
|
+
var ConfigurablePermissionAbi = [
|
|
37882
|
+
{
|
|
37883
|
+
type: "function",
|
|
37884
|
+
name: "configure",
|
|
37885
|
+
stateMutability: "nonpayable",
|
|
37886
|
+
inputs: [
|
|
37887
|
+
{ name: "account", type: "address" },
|
|
37888
|
+
{ name: "params", type: "bytes" },
|
|
37889
|
+
{ name: "deadline", type: "uint256" },
|
|
37890
|
+
{ name: "sig", type: "bytes" }
|
|
37891
|
+
],
|
|
37892
|
+
outputs: []
|
|
37893
|
+
},
|
|
37894
|
+
{
|
|
37895
|
+
type: "function",
|
|
37896
|
+
name: "configureDirect",
|
|
37897
|
+
stateMutability: "nonpayable",
|
|
37898
|
+
inputs: [
|
|
37899
|
+
{ name: "account", type: "address" },
|
|
37900
|
+
{ name: "params", type: "bytes" }
|
|
37901
|
+
],
|
|
37902
|
+
outputs: []
|
|
37903
|
+
},
|
|
37904
|
+
{
|
|
37905
|
+
type: "function",
|
|
37906
|
+
name: "isConfigured",
|
|
37907
|
+
stateMutability: "view",
|
|
37908
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37909
|
+
outputs: [{ name: "", type: "bool" }]
|
|
37910
|
+
},
|
|
37911
|
+
{
|
|
37912
|
+
type: "function",
|
|
37913
|
+
name: "configNonces",
|
|
37914
|
+
stateMutability: "view",
|
|
37915
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37916
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
37917
|
+
},
|
|
37918
|
+
{
|
|
37919
|
+
type: "function",
|
|
37920
|
+
name: "configuredEpoch",
|
|
37921
|
+
stateMutability: "view",
|
|
37922
|
+
inputs: [{ name: "account", type: "address" }],
|
|
37923
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
37924
|
+
},
|
|
37925
|
+
{
|
|
37926
|
+
type: "function",
|
|
37927
|
+
name: "hashTypedDataV4",
|
|
37928
|
+
stateMutability: "view",
|
|
37929
|
+
inputs: [{ name: "structHash", type: "bytes32" }],
|
|
37930
|
+
outputs: [{ name: "", type: "bytes32" }]
|
|
37931
|
+
}
|
|
37932
|
+
];
|
|
37933
|
+
|
|
37616
37934
|
// ../sdk/dist/safe.js
|
|
37617
37935
|
init_esm2();
|
|
37618
37936
|
var setManagerAbi = [
|
|
@@ -37811,38 +38129,43 @@ async function discoverSafesForOwner(owner2, chainId) {
|
|
|
37811
38129
|
}
|
|
37812
38130
|
|
|
37813
38131
|
// ../sdk/dist/fees.js
|
|
37814
|
-
|
|
37815
|
-
|
|
38132
|
+
init_esm2();
|
|
38133
|
+
async function readPermissionRegistrationFee(publicClient, governance) {
|
|
38134
|
+
return publicClient.readContract({
|
|
38135
|
+
address: governance,
|
|
38136
|
+
abi: SailGovernanceAbi,
|
|
38137
|
+
functionName: "permissionRegistrationFee"
|
|
38138
|
+
});
|
|
37816
38139
|
}
|
|
37817
|
-
async function
|
|
37818
|
-
|
|
37819
|
-
|
|
37820
|
-
|
|
37821
|
-
|
|
37822
|
-
|
|
37823
|
-
|
|
37824
|
-
|
|
37825
|
-
|
|
37826
|
-
|
|
37827
|
-
|
|
37828
|
-
|
|
37829
|
-
|
|
37830
|
-
|
|
37831
|
-
|
|
37832
|
-
|
|
37833
|
-
|
|
37834
|
-
|
|
37835
|
-
|
|
37836
|
-
|
|
37837
|
-
|
|
37838
|
-
|
|
37839
|
-
|
|
37840
|
-
|
|
37841
|
-
|
|
37842
|
-
|
|
37843
|
-
|
|
37844
|
-
|
|
37845
|
-
});
|
|
38140
|
+
async function estimateMandateRegistrationFee(publicClient, governance, permissions) {
|
|
38141
|
+
const flatFeeWei = await readPermissionRegistrationFee(publicClient, governance);
|
|
38142
|
+
const perPermission = permissions.map((permission) => ({ permission, feeWei: flatFeeWei }));
|
|
38143
|
+
const totalWei = flatFeeWei * BigInt(permissions.length);
|
|
38144
|
+
return { totalWei, perPermission };
|
|
38145
|
+
}
|
|
38146
|
+
function describeMandateFee(estimate) {
|
|
38147
|
+
const count = estimate.perPermission.length;
|
|
38148
|
+
if (count === 0)
|
|
38149
|
+
return "Registration fee: 0 ETH (no new permissions to register)";
|
|
38150
|
+
const noun = count === 1 ? "permission" : "permissions";
|
|
38151
|
+
const perFeeWei = estimate.perPermission[0].feeWei;
|
|
38152
|
+
return `Registration fee: ${formatEther(estimate.totalWei)} ETH (${count} ${noun} \xD7 ${formatEther(perFeeWei)} ETH)`;
|
|
38153
|
+
}
|
|
38154
|
+
var RegistrationFeeError = class extends Error {
|
|
38155
|
+
/** Total fee required (wei). */
|
|
38156
|
+
requiredWei;
|
|
38157
|
+
/** Signer balance available (wei). */
|
|
38158
|
+
balanceWei;
|
|
38159
|
+
constructor(message, requiredWei, balanceWei) {
|
|
38160
|
+
super(message);
|
|
38161
|
+
this.name = "RegistrationFeeError";
|
|
38162
|
+
this.requiredWei = requiredWei;
|
|
38163
|
+
this.balanceWei = balanceWei;
|
|
38164
|
+
}
|
|
38165
|
+
};
|
|
38166
|
+
function assertFeeAffordable(balanceWei, totalFeeWei) {
|
|
38167
|
+
if (balanceWei < totalFeeWei) {
|
|
38168
|
+
throw new RegistrationFeeError(`Insufficient ETH for the ${formatEther(totalFeeWei)} ETH registration fee; signer balance is ${formatEther(balanceWei)} ETH.`, totalFeeWei, balanceWei);
|
|
37846
38169
|
}
|
|
37847
38170
|
}
|
|
37848
38171
|
|
|
@@ -37853,6 +38176,9 @@ var SAIL_INTELLIGENCE_DOCS_URL = "https://api.sail.money/docs";
|
|
|
37853
38176
|
// src/commands/account.ts
|
|
37854
38177
|
init_esm2();
|
|
37855
38178
|
|
|
38179
|
+
// src/lib/chain.ts
|
|
38180
|
+
init_esm2();
|
|
38181
|
+
|
|
37856
38182
|
// ../../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
|
|
37857
38183
|
var contracts = {
|
|
37858
38184
|
gasPriceOracle: { address: "0x420000000000000000000000000000000000000F" },
|
|
@@ -38124,6 +38450,35 @@ var baseSepoliaPreconf = /* @__PURE__ */ defineChain({
|
|
|
38124
38450
|
}
|
|
38125
38451
|
});
|
|
38126
38452
|
|
|
38453
|
+
// ../../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
|
|
38454
|
+
init_defineChain();
|
|
38455
|
+
var bsc = /* @__PURE__ */ defineChain({
|
|
38456
|
+
id: 56,
|
|
38457
|
+
name: "BNB Smart Chain",
|
|
38458
|
+
blockTime: 750,
|
|
38459
|
+
nativeCurrency: {
|
|
38460
|
+
decimals: 18,
|
|
38461
|
+
name: "BNB",
|
|
38462
|
+
symbol: "BNB"
|
|
38463
|
+
},
|
|
38464
|
+
rpcUrls: {
|
|
38465
|
+
default: { http: ["https://56.rpc.thirdweb.com"] }
|
|
38466
|
+
},
|
|
38467
|
+
blockExplorers: {
|
|
38468
|
+
default: {
|
|
38469
|
+
name: "BscScan",
|
|
38470
|
+
url: "https://bscscan.com",
|
|
38471
|
+
apiUrl: "https://api.bscscan.com/api"
|
|
38472
|
+
}
|
|
38473
|
+
},
|
|
38474
|
+
contracts: {
|
|
38475
|
+
multicall3: {
|
|
38476
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38477
|
+
blockCreated: 15921452
|
|
38478
|
+
}
|
|
38479
|
+
}
|
|
38480
|
+
});
|
|
38481
|
+
|
|
38127
38482
|
// ../../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
|
|
38128
38483
|
init_defineChain();
|
|
38129
38484
|
var mainnet = /* @__PURE__ */ defineChain({
|
|
@@ -38155,6 +38510,56 @@ var mainnet = /* @__PURE__ */ defineChain({
|
|
|
38155
38510
|
}
|
|
38156
38511
|
});
|
|
38157
38512
|
|
|
38513
|
+
// ../../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
|
|
38514
|
+
init_defineChain();
|
|
38515
|
+
var sourceId3 = 1;
|
|
38516
|
+
var optimism = /* @__PURE__ */ defineChain({
|
|
38517
|
+
...chainConfig,
|
|
38518
|
+
id: 10,
|
|
38519
|
+
name: "OP Mainnet",
|
|
38520
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38521
|
+
rpcUrls: {
|
|
38522
|
+
default: {
|
|
38523
|
+
http: ["https://mainnet.optimism.io"]
|
|
38524
|
+
}
|
|
38525
|
+
},
|
|
38526
|
+
blockExplorers: {
|
|
38527
|
+
default: {
|
|
38528
|
+
name: "Optimism Explorer",
|
|
38529
|
+
url: "https://optimistic.etherscan.io",
|
|
38530
|
+
apiUrl: "https://api-optimistic.etherscan.io/api"
|
|
38531
|
+
}
|
|
38532
|
+
},
|
|
38533
|
+
contracts: {
|
|
38534
|
+
...chainConfig.contracts,
|
|
38535
|
+
disputeGameFactory: {
|
|
38536
|
+
[sourceId3]: {
|
|
38537
|
+
address: "0xe5965Ab5962eDc7477C8520243A95517CD252fA9"
|
|
38538
|
+
}
|
|
38539
|
+
},
|
|
38540
|
+
l2OutputOracle: {
|
|
38541
|
+
[sourceId3]: {
|
|
38542
|
+
address: "0xdfe97868233d1aa22e815a266982f2cf17685a27"
|
|
38543
|
+
}
|
|
38544
|
+
},
|
|
38545
|
+
multicall3: {
|
|
38546
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38547
|
+
blockCreated: 4286263
|
|
38548
|
+
},
|
|
38549
|
+
portal: {
|
|
38550
|
+
[sourceId3]: {
|
|
38551
|
+
address: "0xbEb5Fc579115071764c7423A4f12eDde41f106Ed"
|
|
38552
|
+
}
|
|
38553
|
+
},
|
|
38554
|
+
l1StandardBridge: {
|
|
38555
|
+
[sourceId3]: {
|
|
38556
|
+
address: "0x99C9fc46f92E8a1c0deC1b1747d010903E884bE1"
|
|
38557
|
+
}
|
|
38558
|
+
}
|
|
38559
|
+
},
|
|
38560
|
+
sourceId: sourceId3
|
|
38561
|
+
});
|
|
38562
|
+
|
|
38158
38563
|
// ../../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
|
|
38159
38564
|
init_defineChain();
|
|
38160
38565
|
var sepolia = /* @__PURE__ */ defineChain({
|
|
@@ -38188,7 +38593,7 @@ var sepolia = /* @__PURE__ */ defineChain({
|
|
|
38188
38593
|
|
|
38189
38594
|
// ../../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
|
|
38190
38595
|
init_defineChain();
|
|
38191
|
-
var
|
|
38596
|
+
var sourceId4 = 1;
|
|
38192
38597
|
var unichain = /* @__PURE__ */ defineChain({
|
|
38193
38598
|
...chainConfig,
|
|
38194
38599
|
id: 130,
|
|
@@ -38214,22 +38619,77 @@ var unichain = /* @__PURE__ */ defineChain({
|
|
|
38214
38619
|
blockCreated: 0
|
|
38215
38620
|
},
|
|
38216
38621
|
disputeGameFactory: {
|
|
38217
|
-
[
|
|
38622
|
+
[sourceId4]: {
|
|
38218
38623
|
address: "0x2F12d621a16e2d3285929C9996f478508951dFe4"
|
|
38219
38624
|
}
|
|
38220
38625
|
},
|
|
38221
38626
|
portal: {
|
|
38222
|
-
[
|
|
38627
|
+
[sourceId4]: {
|
|
38223
38628
|
address: "0x0bd48f6B86a26D3a217d0Fa6FfE2B491B956A7a2"
|
|
38224
38629
|
}
|
|
38225
38630
|
},
|
|
38226
38631
|
l1StandardBridge: {
|
|
38227
|
-
[
|
|
38632
|
+
[sourceId4]: {
|
|
38228
38633
|
address: "0x81014F44b0a345033bB2b3B21C7a1A308B35fEeA"
|
|
38229
38634
|
}
|
|
38230
38635
|
}
|
|
38231
38636
|
},
|
|
38232
|
-
sourceId:
|
|
38637
|
+
sourceId: sourceId4
|
|
38638
|
+
});
|
|
38639
|
+
|
|
38640
|
+
// ../../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
|
|
38641
|
+
init_defineChain();
|
|
38642
|
+
var sourceId5 = 1;
|
|
38643
|
+
var worldchain = /* @__PURE__ */ defineChain({
|
|
38644
|
+
...chainConfig,
|
|
38645
|
+
id: 480,
|
|
38646
|
+
name: "World Chain",
|
|
38647
|
+
network: "worldchain",
|
|
38648
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38649
|
+
rpcUrls: {
|
|
38650
|
+
default: { http: ["https://worldchain-mainnet.g.alchemy.com/public"] }
|
|
38651
|
+
},
|
|
38652
|
+
blockExplorers: {
|
|
38653
|
+
default: {
|
|
38654
|
+
name: "Worldscan",
|
|
38655
|
+
url: "https://worldscan.org",
|
|
38656
|
+
apiUrl: "https://api.worldscan.org/api"
|
|
38657
|
+
},
|
|
38658
|
+
blockscout: {
|
|
38659
|
+
name: "Blockscout",
|
|
38660
|
+
url: "https://worldchain-mainnet.explorer.alchemy.com",
|
|
38661
|
+
apiUrl: "https://worldchain-mainnet.explorer.alchemy.com/api"
|
|
38662
|
+
}
|
|
38663
|
+
},
|
|
38664
|
+
contracts: {
|
|
38665
|
+
...chainConfig.contracts,
|
|
38666
|
+
multicall3: {
|
|
38667
|
+
address: "0xca11bde05977b3631167028862be2a173976ca11",
|
|
38668
|
+
blockCreated: 0
|
|
38669
|
+
},
|
|
38670
|
+
disputeGameFactory: {
|
|
38671
|
+
[sourceId5]: {
|
|
38672
|
+
address: "0x069c4c579671f8c120b1327a73217D01Ea2EC5ea"
|
|
38673
|
+
}
|
|
38674
|
+
},
|
|
38675
|
+
l2OutputOracle: {
|
|
38676
|
+
[sourceId5]: {
|
|
38677
|
+
address: "0x19A6d1E9034596196295CF148509796978343c5D"
|
|
38678
|
+
}
|
|
38679
|
+
},
|
|
38680
|
+
portal: {
|
|
38681
|
+
[sourceId5]: {
|
|
38682
|
+
address: "0xd5ec14a83B7d95BE1E2Ac12523e2dEE12Cbeea6C"
|
|
38683
|
+
}
|
|
38684
|
+
},
|
|
38685
|
+
l1StandardBridge: {
|
|
38686
|
+
[sourceId5]: {
|
|
38687
|
+
address: "0x470458C91978D2d929704489Ad730DC3E3001113"
|
|
38688
|
+
}
|
|
38689
|
+
}
|
|
38690
|
+
},
|
|
38691
|
+
testnet: false,
|
|
38692
|
+
sourceId: sourceId5
|
|
38233
38693
|
});
|
|
38234
38694
|
|
|
38235
38695
|
// src/lib/io.ts
|
|
@@ -38353,14 +38813,14 @@ function getRl() {
|
|
|
38353
38813
|
function ask(query) {
|
|
38354
38814
|
getRl();
|
|
38355
38815
|
process.stdout.write(query);
|
|
38356
|
-
return new Promise((
|
|
38816
|
+
return new Promise((resolve4) => {
|
|
38357
38817
|
const buffered = lineQueue.shift();
|
|
38358
38818
|
if (buffered !== void 0) {
|
|
38359
|
-
|
|
38819
|
+
resolve4(buffered);
|
|
38360
38820
|
} else if (inputClosed) {
|
|
38361
|
-
|
|
38821
|
+
resolve4("");
|
|
38362
38822
|
} else {
|
|
38363
|
-
waiters.push(
|
|
38823
|
+
waiters.push(resolve4);
|
|
38364
38824
|
}
|
|
38365
38825
|
});
|
|
38366
38826
|
}
|
|
@@ -38392,11 +38852,28 @@ async function promptHidden(question) {
|
|
|
38392
38852
|
}
|
|
38393
38853
|
|
|
38394
38854
|
// src/lib/chain.ts
|
|
38855
|
+
var hyperevm = defineChain({
|
|
38856
|
+
id: 999,
|
|
38857
|
+
name: "HyperEVM",
|
|
38858
|
+
nativeCurrency: { name: "HYPE", symbol: "HYPE", decimals: 18 },
|
|
38859
|
+
rpcUrls: { default: { http: ["https://rpc.hyperliquid.xyz/evm"] } }
|
|
38860
|
+
});
|
|
38861
|
+
var megaeth = defineChain({
|
|
38862
|
+
id: 4326,
|
|
38863
|
+
name: "MegaETH",
|
|
38864
|
+
nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 },
|
|
38865
|
+
rpcUrls: { default: { http: ["https://carrot.megaeth.com/rpc"] } }
|
|
38866
|
+
});
|
|
38395
38867
|
var CHAINS = {
|
|
38396
38868
|
1: mainnet,
|
|
38397
38869
|
8453: base,
|
|
38398
38870
|
42161: arbitrum,
|
|
38871
|
+
10: optimism,
|
|
38399
38872
|
130: unichain,
|
|
38873
|
+
56: bsc,
|
|
38874
|
+
480: worldchain,
|
|
38875
|
+
999: hyperevm,
|
|
38876
|
+
4326: megaeth,
|
|
38400
38877
|
84532: baseSepolia,
|
|
38401
38878
|
11155111: sepolia
|
|
38402
38879
|
};
|
|
@@ -38404,7 +38881,7 @@ function getChainById(chainId) {
|
|
|
38404
38881
|
const chain2 = CHAINS[chainId];
|
|
38405
38882
|
if (!chain2) {
|
|
38406
38883
|
throw new Error(
|
|
38407
|
-
`Unsupported chainId: ${chainId}. Supported: 1 (Ethereum), 8453 (Base), 42161 (Arbitrum), 130 (Unichain), 84532 (Base Sepolia), 11155111 (Eth Sepolia)`
|
|
38884
|
+
`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)`
|
|
38408
38885
|
);
|
|
38409
38886
|
}
|
|
38410
38887
|
return chain2;
|
|
@@ -38534,11 +39011,11 @@ function isProcessAlive(pid) {
|
|
|
38534
39011
|
}
|
|
38535
39012
|
}
|
|
38536
39013
|
function findFreePort(from14) {
|
|
38537
|
-
return new Promise((
|
|
39014
|
+
return new Promise((resolve4, reject) => {
|
|
38538
39015
|
const server = import_node_net.default.createServer();
|
|
38539
39016
|
server.unref();
|
|
38540
|
-
server.on("error", () => findFreePort(from14 + 1).then(
|
|
38541
|
-
server.listen(from14, "127.0.0.1", () => server.close(() =>
|
|
39017
|
+
server.on("error", () => findFreePort(from14 + 1).then(resolve4, reject));
|
|
39018
|
+
server.listen(from14, "127.0.0.1", () => server.close(() => resolve4(from14)));
|
|
38542
39019
|
});
|
|
38543
39020
|
}
|
|
38544
39021
|
|
|
@@ -39152,8 +39629,9 @@ var SigningServer = class {
|
|
|
39152
39629
|
}
|
|
39153
39630
|
}
|
|
39154
39631
|
if (!(0, import_node_fs6.existsSync)(this.runtimeDir)) (0, import_node_fs6.mkdirSync)(this.runtimeDir, { recursive: true });
|
|
39632
|
+
const serverStatePath = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
39155
39633
|
(0, import_node_fs6.writeFileSync)(
|
|
39156
|
-
|
|
39634
|
+
serverStatePath,
|
|
39157
39635
|
JSON.stringify(
|
|
39158
39636
|
{
|
|
39159
39637
|
url: this._url,
|
|
@@ -39165,8 +39643,10 @@ var SigningServer = class {
|
|
|
39165
39643
|
},
|
|
39166
39644
|
null,
|
|
39167
39645
|
2
|
|
39168
|
-
)
|
|
39646
|
+
),
|
|
39647
|
+
{ mode: 384 }
|
|
39169
39648
|
);
|
|
39649
|
+
(0, import_node_fs6.chmodSync)(serverStatePath, 384);
|
|
39170
39650
|
}
|
|
39171
39651
|
removeRuntimeState() {
|
|
39172
39652
|
const path11 = (0, import_node_path4.join)(this.runtimeDir, SERVER_STATE_FILE);
|
|
@@ -39295,7 +39775,7 @@ async function createSigningChannel(projectRoot = process.cwd()) {
|
|
|
39295
39775
|
}
|
|
39296
39776
|
|
|
39297
39777
|
// src/commands/account.ts
|
|
39298
|
-
var SAIL_MAINNET_CHAINS = [1, 8453, 42161, 130];
|
|
39778
|
+
var SAIL_MAINNET_CHAINS = [1, 8453, 42161, 10, 130, 56, 480, 999, 4326];
|
|
39299
39779
|
async function fetchProxyCreationCode(preferredChainId) {
|
|
39300
39780
|
const rpcUrl = getRpcUrl(preferredChainId) ?? void 0;
|
|
39301
39781
|
const publicClient = createPublicClient({
|
|
@@ -40065,15 +40545,36 @@ var IPERMISSION_ABI = [
|
|
|
40065
40545
|
{ name: "selector", type: "bytes4" },
|
|
40066
40546
|
{ name: "value", type: "uint256" },
|
|
40067
40547
|
{ name: "blockTimestamp", type: "uint256" },
|
|
40068
|
-
{ name: "blockNumber", type: "uint256" }
|
|
40548
|
+
{ name: "blockNumber", type: "uint256" },
|
|
40549
|
+
{ name: "configEpoch", type: "uint256" }
|
|
40069
40550
|
]
|
|
40070
40551
|
}
|
|
40071
40552
|
],
|
|
40072
40553
|
outputs: [{ type: "bool" }]
|
|
40073
40554
|
}
|
|
40074
40555
|
];
|
|
40556
|
+
var REGISTRATION_EPOCH_ABI2 = [
|
|
40557
|
+
{
|
|
40558
|
+
type: "function",
|
|
40559
|
+
name: "registrationEpoch",
|
|
40560
|
+
stateMutability: "view",
|
|
40561
|
+
inputs: [
|
|
40562
|
+
{ name: "account", type: "address" },
|
|
40563
|
+
{ name: "permission", type: "address" }
|
|
40564
|
+
],
|
|
40565
|
+
outputs: [{ type: "uint256" }]
|
|
40566
|
+
}
|
|
40567
|
+
];
|
|
40568
|
+
async function readRegistrationEpoch(publicClient, kernel, account2, permission) {
|
|
40569
|
+
return await publicClient.readContract({
|
|
40570
|
+
address: kernel,
|
|
40571
|
+
abi: REGISTRATION_EPOCH_ABI2,
|
|
40572
|
+
functionName: "registrationEpoch",
|
|
40573
|
+
args: [account2, permission]
|
|
40574
|
+
});
|
|
40575
|
+
}
|
|
40075
40576
|
function buildPermissionContext(params) {
|
|
40076
|
-
const { account: account2, manager, call: call2, blockInfo } = params;
|
|
40577
|
+
const { account: account2, manager, call: call2, blockInfo, configEpoch } = params;
|
|
40077
40578
|
const selector = call2.data.length >= 10 ? call2.data.slice(0, 10) : "0x00000000";
|
|
40078
40579
|
return {
|
|
40079
40580
|
account: account2,
|
|
@@ -40084,12 +40585,23 @@ function buildPermissionContext(params) {
|
|
|
40084
40585
|
selector,
|
|
40085
40586
|
value: call2.value,
|
|
40086
40587
|
blockTimestamp: blockInfo.timestamp,
|
|
40087
|
-
blockNumber: blockInfo.number
|
|
40588
|
+
blockNumber: blockInfo.number,
|
|
40589
|
+
configEpoch
|
|
40088
40590
|
};
|
|
40089
40591
|
}
|
|
40090
40592
|
async function probePermissionForCall(params) {
|
|
40091
|
-
const { publicClient, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40092
|
-
|
|
40593
|
+
const { publicClient, kernel, permission, account: account2, manager, call: call2, blockInfo } = params;
|
|
40594
|
+
let configEpoch;
|
|
40595
|
+
try {
|
|
40596
|
+
configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40597
|
+
} catch (err) {
|
|
40598
|
+
return {
|
|
40599
|
+
accepted: false,
|
|
40600
|
+
reverted: true,
|
|
40601
|
+
error: `could not read registrationEpoch from kernel ${kernel} (${err.message.split("\n")[0]})`
|
|
40602
|
+
};
|
|
40603
|
+
}
|
|
40604
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40093
40605
|
try {
|
|
40094
40606
|
const accepted = await publicClient.readContract({
|
|
40095
40607
|
address: permission,
|
|
@@ -40103,10 +40615,11 @@ async function probePermissionForCall(params) {
|
|
|
40103
40615
|
}
|
|
40104
40616
|
}
|
|
40105
40617
|
async function resolvePermissionForCall(params) {
|
|
40106
|
-
const { publicClient, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40107
|
-
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo });
|
|
40618
|
+
const { publicClient, kernel, account: account2, manager, call: call2, registeredPermissions, blockInfo } = params;
|
|
40108
40619
|
for (const permission of registeredPermissions) {
|
|
40109
40620
|
try {
|
|
40621
|
+
const configEpoch = await readRegistrationEpoch(publicClient, kernel, account2, permission);
|
|
40622
|
+
const ctx = buildPermissionContext({ account: account2, manager, call: call2, blockInfo, configEpoch });
|
|
40110
40623
|
const accepted = await publicClient.readContract({
|
|
40111
40624
|
address: permission,
|
|
40112
40625
|
abi: IPERMISSION_ABI,
|
|
@@ -40176,7 +40689,10 @@ async function probePassThrough(pc, permission, account2) {
|
|
|
40176
40689
|
selector: PROBE_SELECTOR,
|
|
40177
40690
|
value: 0n,
|
|
40178
40691
|
blockTimestamp: 0n,
|
|
40179
|
-
blockNumber: 0n
|
|
40692
|
+
blockNumber: 0n,
|
|
40693
|
+
// Pass-through probes only run on conjunctive kernels, which predate
|
|
40694
|
+
// registrationEpoch — there is no live epoch to read, so probe with 0.
|
|
40695
|
+
configEpoch: 0n
|
|
40180
40696
|
}
|
|
40181
40697
|
]
|
|
40182
40698
|
});
|
|
@@ -40352,7 +40868,7 @@ async function doctor(options = {}) {
|
|
|
40352
40868
|
console.log(`Account: ${safe}`);
|
|
40353
40869
|
if (stored?.saltNonce != null) {
|
|
40354
40870
|
const saltNonce = BigInt(stored.saltNonce);
|
|
40355
|
-
const MAINNET_CHAINS = [1, 8453, 42161, 130];
|
|
40871
|
+
const MAINNET_CHAINS = [1, 8453, 42161, 10, 130, 56, 480, 999, 4326];
|
|
40356
40872
|
try {
|
|
40357
40873
|
const proxyCreationCode = await pc.readContract({
|
|
40358
40874
|
address: SAFE_V141.proxyFactory,
|
|
@@ -40472,6 +40988,10 @@ struct Context {
|
|
|
40472
40988
|
uint256 value; // native ETH forwarded (wei)
|
|
40473
40989
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40474
40990
|
uint256 blockNumber; // block.number at dispatch
|
|
40991
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch;
|
|
40992
|
+
// configurable permissions fail closed on a mismatch with the
|
|
40993
|
+
// epoch stamped at configure() time. Custom permissions that
|
|
40994
|
+
// take no post-deploy configuration can ignore it.
|
|
40475
40995
|
}
|
|
40476
40996
|
|
|
40477
40997
|
/// @title IPermission
|
|
@@ -40507,6 +41027,8 @@ struct BatchContext {
|
|
|
40507
41027
|
bytes32 batchHash; // keccak256(abi.encode(calls)) \u2014 stable id for the exact sequence
|
|
40508
41028
|
uint256 blockTimestamp; // block.timestamp at dispatch
|
|
40509
41029
|
uint256 blockNumber; // block.number at dispatch
|
|
41030
|
+
uint256 configEpoch; // kernel registrationEpoch(account, permission) at dispatch \u2014
|
|
41031
|
+
// same fail-closed freshness check as Context.configEpoch
|
|
40510
41032
|
}
|
|
40511
41033
|
|
|
40512
41034
|
/// @title IBatchPermission
|
|
@@ -40672,19 +41194,16 @@ AI coding agents should read the project's \`AGENTS.md\` and this folder's \`con
|
|
|
40672
41194
|
before changing strategy code or running commands that touch funds.
|
|
40673
41195
|
`;
|
|
40674
41196
|
var CANONICAL_PKG = "@sail.money/sailor";
|
|
40675
|
-
|
|
40676
|
-
|
|
41197
|
+
function cliVersion() {
|
|
41198
|
+
const manifest = import_node_path8.default.join(packageRoot(), "package.json");
|
|
41199
|
+
let version4;
|
|
40677
41200
|
try {
|
|
40678
|
-
|
|
40679
|
-
|
|
40680
|
-
);
|
|
40681
|
-
return {
|
|
40682
|
-
name: pkg.name ?? CANONICAL_PKG,
|
|
40683
|
-
version: pkg.version ?? "0.0.0"
|
|
40684
|
-
};
|
|
40685
|
-
} catch {
|
|
40686
|
-
return { name: CANONICAL_PKG, version: "0.0.0" };
|
|
41201
|
+
version4 = JSON.parse(import_node_fs10.default.readFileSync(manifest, "utf-8")).version;
|
|
41202
|
+
} catch (err) {
|
|
41203
|
+
throw new Error(`Cannot read CLI package manifest at ${manifest}: ${err.message}`);
|
|
40687
41204
|
}
|
|
41205
|
+
if (!version4) throw new Error(`CLI package manifest at ${manifest} has no version`);
|
|
41206
|
+
return version4;
|
|
40688
41207
|
}
|
|
40689
41208
|
function scaffoldProjectWorkspace(dest, name, options) {
|
|
40690
41209
|
const chainId = options.chain ? (() => {
|
|
@@ -40811,30 +41330,12 @@ Pass --force to scaffold into it anyway (existing files with the same name are o
|
|
|
40811
41330
|
}
|
|
40812
41331
|
})() : null;
|
|
40813
41332
|
copyDirSync(templateSrc, dest);
|
|
40814
|
-
if (options.skills === false) {
|
|
40815
|
-
import_node_fs10.default.rmSync(import_node_path8.default.join(dest, ".agents", "skills"), { recursive: true, force: true });
|
|
40816
|
-
}
|
|
40817
|
-
const pkgRoot = packageRoot();
|
|
40818
|
-
const examplesPermSrc = import_node_path8.default.join(pkgRoot, "examples", "permissions");
|
|
40819
|
-
if (import_node_fs10.default.existsSync(examplesPermSrc)) {
|
|
40820
|
-
copyDirSync(examplesPermSrc, import_node_path8.default.join(dest, "examples", "permissions"));
|
|
40821
|
-
}
|
|
40822
|
-
const customMandateSrc = import_node_path8.default.join(pkgRoot, "examples", "custom-mandate");
|
|
40823
|
-
if (import_node_fs10.default.existsSync(customMandateSrc)) {
|
|
40824
|
-
copyDirSync(customMandateSrc, import_node_path8.default.join(dest, "examples", "custom-mandate"));
|
|
40825
|
-
}
|
|
40826
|
-
const permModelSrc = import_node_path8.default.join(pkgRoot, "docs", "PERMISSION_MODEL.md");
|
|
40827
|
-
if (import_node_fs10.default.existsSync(permModelSrc)) {
|
|
40828
|
-
import_node_fs10.default.mkdirSync(import_node_path8.default.join(dest, "docs"), { recursive: true });
|
|
40829
|
-
writeIfMissing2(import_node_path8.default.join(dest, "docs", "PERMISSION_MODEL.md"), import_node_fs10.default.readFileSync(permModelSrc, "utf-8"));
|
|
40830
|
-
}
|
|
40831
41333
|
const pkgPath = import_node_path8.default.join(dest, "package.json");
|
|
40832
41334
|
if (import_node_fs10.default.existsSync(pkgPath)) {
|
|
40833
41335
|
const pkg = JSON.parse(import_node_fs10.default.readFileSync(pkgPath, "utf-8"));
|
|
40834
41336
|
pkg.name = name;
|
|
40835
41337
|
const devDeps = pkg.devDependencies ?? {};
|
|
40836
|
-
|
|
40837
|
-
devDeps[CANONICAL_PKG] = cliName === DEV_PKG ? `npm:${DEV_PKG}@^${cliVer}` : `^${cliVer}`;
|
|
41338
|
+
devDeps[CANONICAL_PKG] = `^${cliVersion()}`;
|
|
40838
41339
|
pkg.devDependencies = devDeps;
|
|
40839
41340
|
import_node_fs10.default.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
40840
41341
|
`);
|
|
@@ -40922,7 +41423,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40922
41423
|
console.log("Next:");
|
|
40923
41424
|
console.log(" sailor ui start");
|
|
40924
41425
|
console.log(" Connect your wallet and deploy your SMA in the browser.\n");
|
|
40925
|
-
console.log('Or open this folder in your AI coding
|
|
41426
|
+
console.log('Or open this folder in your AI coding agent and say: "continue"');
|
|
40926
41427
|
return;
|
|
40927
41428
|
}
|
|
40928
41429
|
if (state.kind === "C") {
|
|
@@ -40939,7 +41440,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40939
41440
|
console.log(" forge build");
|
|
40940
41441
|
console.log(` sailor mandate deploy --contract <Name> --attach --sma ${state.sma}
|
|
40941
41442
|
`);
|
|
40942
|
-
console.log('Or open this folder in your AI coding
|
|
41443
|
+
console.log('Or open this folder in your AI coding agent and say: "continue"');
|
|
40943
41444
|
return;
|
|
40944
41445
|
}
|
|
40945
41446
|
if (state.kind === "D") {
|
|
@@ -40948,7 +41449,7 @@ function printWelcome(dest, name, inPlace, _hasRpc, freshInit = false) {
|
|
|
40948
41449
|
console.log(`SMA: ${state.sma} on ${state.chain}`);
|
|
40949
41450
|
console.log(`Permissions: ${state.permissionCount} registered
|
|
40950
41451
|
`);
|
|
40951
|
-
console.log('Open this folder in your AI coding
|
|
41452
|
+
console.log('Open this folder in your AI coding agent and say: "continue"');
|
|
40952
41453
|
return;
|
|
40953
41454
|
}
|
|
40954
41455
|
if (!inPlace) console.log(`
|
|
@@ -41094,13 +41595,13 @@ Added (new in template):`);
|
|
|
41094
41595
|
var import_node_fs12 = __toESM(require("node:fs"), 1);
|
|
41095
41596
|
var import_node_path10 = __toESM(require("node:path"), 1);
|
|
41096
41597
|
function readStdin() {
|
|
41097
|
-
return new Promise((
|
|
41598
|
+
return new Promise((resolve4, reject) => {
|
|
41098
41599
|
let data = "";
|
|
41099
41600
|
process.stdin.setEncoding("utf8");
|
|
41100
41601
|
process.stdin.on("data", (c) => {
|
|
41101
41602
|
data += c;
|
|
41102
41603
|
});
|
|
41103
|
-
process.stdin.on("end", () =>
|
|
41604
|
+
process.stdin.on("end", () => resolve4(data));
|
|
41104
41605
|
process.stdin.on("error", reject);
|
|
41105
41606
|
});
|
|
41106
41607
|
}
|
|
@@ -41408,6 +41909,22 @@ var MandateStore = class {
|
|
|
41408
41909
|
this.write(data);
|
|
41409
41910
|
return mandate2;
|
|
41410
41911
|
}
|
|
41912
|
+
/**
|
|
41913
|
+
* Track a permission only if no record at its address exists yet, returning the
|
|
41914
|
+
* record either way. Used by `mandate attach` for addresses that were never
|
|
41915
|
+
* deployed from this project — e.g. a shared permission singleton the operator
|
|
41916
|
+
* attaches by address. Without a store record, `recordAttachment` is a no-op and
|
|
41917
|
+
* the permission stays invisible to `mandate prepare`/`sign`. Unlike `add`, this
|
|
41918
|
+
* never overwrites an existing record (so richer deploy-time metadata such as
|
|
41919
|
+
* `sourcePath` is preserved). For attach-only records, `txHash`/`deployedAt`
|
|
41920
|
+
* reflect the registration/first-tracked moment, not an on-chain deployment.
|
|
41921
|
+
*/
|
|
41922
|
+
ensureTracked(mandate2) {
|
|
41923
|
+
const existing = this.read().mandates.find(
|
|
41924
|
+
(m) => m.address.toLowerCase() === mandate2.address.toLowerCase()
|
|
41925
|
+
);
|
|
41926
|
+
return existing ?? this.add(mandate2);
|
|
41927
|
+
}
|
|
41411
41928
|
/** Update mutable metadata fields on a tracked mandate (name, sourcePath, artifactPath). */
|
|
41412
41929
|
update(addressOrName, patch) {
|
|
41413
41930
|
const data = this.read();
|
|
@@ -41441,6 +41958,21 @@ var MandateStore = class {
|
|
|
41441
41958
|
|
|
41442
41959
|
// src/commands/onboard.ts
|
|
41443
41960
|
init_esm2();
|
|
41961
|
+
|
|
41962
|
+
// src/lib/registration-fee.ts
|
|
41963
|
+
function registrationGate(args) {
|
|
41964
|
+
const { estimate, agentBalanceWei } = args;
|
|
41965
|
+
if (agentBalanceWei !== void 0) {
|
|
41966
|
+
assertFeeAffordable(agentBalanceWei, estimate.totalWei);
|
|
41967
|
+
}
|
|
41968
|
+
return {
|
|
41969
|
+
totalFeeWei: estimate.totalWei,
|
|
41970
|
+
permissionCount: estimate.perPermission.length,
|
|
41971
|
+
disclosure: describeMandateFee(estimate)
|
|
41972
|
+
};
|
|
41973
|
+
}
|
|
41974
|
+
|
|
41975
|
+
// src/commands/onboard.ts
|
|
41444
41976
|
async function onboard(options) {
|
|
41445
41977
|
if (!ProjectContext.exists()) {
|
|
41446
41978
|
emit(options.json, () => console.log('No Sailor project found. Run "sailor init" first.'), {
|
|
@@ -41819,6 +42351,17 @@ async function attachMandate(project, channel, publicClient, agentSigner, smaAdd
|
|
|
41819
42351
|
hasDeadline: registerPermissionHasDeadline,
|
|
41820
42352
|
deadline: registrationDeadline
|
|
41821
42353
|
});
|
|
42354
|
+
const feeEstimate = await estimateMandateRegistrationFee(
|
|
42355
|
+
publicClient,
|
|
42356
|
+
project.contracts.governance,
|
|
42357
|
+
[templateAddress]
|
|
42358
|
+
);
|
|
42359
|
+
const fee = feeEstimate.totalWei;
|
|
42360
|
+
const agentBalanceWei = await publicClient.getBalance({
|
|
42361
|
+
address: agentSigner.viemAccount.address
|
|
42362
|
+
});
|
|
42363
|
+
const gate = registrationGate({ estimate: feeEstimate, agentBalanceWei });
|
|
42364
|
+
say(() => console.log(gate.disclosure));
|
|
41822
42365
|
say(() => console.log(`
|
|
41823
42366
|
Pushing signing request for "${template.label}" permission\u2026`));
|
|
41824
42367
|
say(
|
|
@@ -41841,6 +42384,13 @@ Pushing signing request for "${template.label}" permission\u2026`));
|
|
|
41841
42384
|
{ label: "Mandate signer", value: permissionSigner }
|
|
41842
42385
|
],
|
|
41843
42386
|
explanation: permExplanation,
|
|
42387
|
+
// Disclose the fee in the signing card so the owner sees what the agent
|
|
42388
|
+
// will pay before signing. Only included when non-zero or when there is a
|
|
42389
|
+
// fee to disclose (zero-fee chains pass 0 ETH, still informative).
|
|
42390
|
+
registrationFee: {
|
|
42391
|
+
totalEth: formatEther(fee),
|
|
42392
|
+
permissionCount: 1
|
|
42393
|
+
},
|
|
41844
42394
|
typedData
|
|
41845
42395
|
});
|
|
41846
42396
|
if (response.status === "rejected") {
|
|
@@ -41867,12 +42417,6 @@ Connect the owner wallet (mandate signer) in the browser \u2014 the agent wallet
|
|
|
41867
42417
|
} catch (err) {
|
|
41868
42418
|
if (err.message.startsWith("Security:")) throw err;
|
|
41869
42419
|
}
|
|
41870
|
-
say(() => console.log("Estimating permission fee\u2026"));
|
|
41871
|
-
const fee = await estimatePermissionFee(
|
|
41872
|
-
publicClient,
|
|
41873
|
-
project.contracts.governance,
|
|
41874
|
-
templateAddress
|
|
41875
|
-
);
|
|
41876
42420
|
say(() => console.log(`Submitting mandate registration (agent pays gas; fee ${fee} wei)\u2026`));
|
|
41877
42421
|
const walletClient = createWalletClient({
|
|
41878
42422
|
account: agentSigner.viemAccount,
|
|
@@ -41922,7 +42466,10 @@ Connect the owner wallet (mandate signer) in the browser \u2014 the agent wallet
|
|
|
41922
42466
|
name: template.label,
|
|
41923
42467
|
sma: smaAddress,
|
|
41924
42468
|
txHash,
|
|
41925
|
-
chainId: project.chainId
|
|
42469
|
+
chainId: project.chainId,
|
|
42470
|
+
// Registration fee actually paid by the agent for this permission.
|
|
42471
|
+
fee: fee.toString(),
|
|
42472
|
+
feeEth: formatEther(fee)
|
|
41926
42473
|
});
|
|
41927
42474
|
return txHash;
|
|
41928
42475
|
}
|
|
@@ -42024,6 +42571,14 @@ function publicClientFor(project) {
|
|
|
42024
42571
|
transport: http(getRpcUrl(project.chainId))
|
|
42025
42572
|
}).extend(publicActions);
|
|
42026
42573
|
}
|
|
42574
|
+
function knownTemplateLabel(chainId, address) {
|
|
42575
|
+
try {
|
|
42576
|
+
const known = getSailDeployment(chainId).knownTemplates ?? [];
|
|
42577
|
+
return known.find((t) => t.address.toLowerCase() === address.toLowerCase())?.label;
|
|
42578
|
+
} catch {
|
|
42579
|
+
return void 0;
|
|
42580
|
+
}
|
|
42581
|
+
}
|
|
42027
42582
|
async function mandateDeploy(options) {
|
|
42028
42583
|
const project = requireProject();
|
|
42029
42584
|
const channel = await createSigningChannel(process.cwd());
|
|
@@ -42339,6 +42894,7 @@ ${spec.label} clone (${options.template})`);
|
|
|
42339
42894
|
hasDeadline: registerPermissionHasDeadline,
|
|
42340
42895
|
deadline
|
|
42341
42896
|
});
|
|
42897
|
+
const fee = await readPermissionRegistrationFee(publicClient, project.contracts.governance);
|
|
42342
42898
|
const label = options.label ?? `${spec.label} (${options.template})`;
|
|
42343
42899
|
say(
|
|
42344
42900
|
() => console.log(
|
|
@@ -42358,6 +42914,10 @@ ${spec.label} clone (${options.template})`);
|
|
|
42358
42914
|
{ label: "Mandate signer", value: permissionSigner },
|
|
42359
42915
|
...spec.describe(initParams)
|
|
42360
42916
|
],
|
|
42917
|
+
registrationFee: {
|
|
42918
|
+
totalEth: formatEther(fee),
|
|
42919
|
+
permissionCount: 1
|
|
42920
|
+
},
|
|
42361
42921
|
typedData
|
|
42362
42922
|
});
|
|
42363
42923
|
if (response.status === "rejected") {
|
|
@@ -42384,7 +42944,6 @@ Connect the owner wallet (mandate signer) in the browser \u2014 the agent wallet
|
|
|
42384
42944
|
} catch (err) {
|
|
42385
42945
|
if (err.message.startsWith("Security:")) throw err;
|
|
42386
42946
|
}
|
|
42387
|
-
const fee = await estimatePermissionFee(publicClient, project.contracts.governance, clone);
|
|
42388
42947
|
if (!registerPermissionHasDeadline || deadline === void 0) {
|
|
42389
42948
|
throw new Error(
|
|
42390
42949
|
"deploy-clone requires a selective kernel (RegisterPermission with deadline). This chain's kernel does not match."
|
|
@@ -42437,7 +42996,10 @@ Connect the owner wallet (mandate signer) in the browser \u2014 the agent wallet
|
|
|
42437
42996
|
name: storedClone.name,
|
|
42438
42997
|
sma,
|
|
42439
42998
|
txHash,
|
|
42440
|
-
chainId: project.chainId
|
|
42999
|
+
chainId: project.chainId,
|
|
43000
|
+
// Registration fee actually paid by the agent for this permission.
|
|
43001
|
+
fee: fee.toString(),
|
|
43002
|
+
feeEth: formatEther(fee)
|
|
42441
43003
|
});
|
|
42442
43004
|
emit(json, () => {
|
|
42443
43005
|
}, {
|
|
@@ -42486,7 +43048,14 @@ async function runAttach(project, channel, options) {
|
|
|
42486
43048
|
label,
|
|
42487
43049
|
json
|
|
42488
43050
|
);
|
|
42489
|
-
|
|
43051
|
+
store.ensureTracked({
|
|
43052
|
+
name: label,
|
|
43053
|
+
address: mandateAddress,
|
|
43054
|
+
txHash,
|
|
43055
|
+
chainId: project.chainId,
|
|
43056
|
+
deployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43057
|
+
});
|
|
43058
|
+
store.recordAttachment(mandateAddress, { sma, txHash });
|
|
42490
43059
|
emit(json, () => {
|
|
42491
43060
|
}, {
|
|
42492
43061
|
status: "ok",
|
|
@@ -42500,7 +43069,14 @@ async function runAttachBatch(project, channel, options, sma, store) {
|
|
|
42500
43069
|
announceSigningUrl(json);
|
|
42501
43070
|
const txHash = await attachBatchToSma(project, channel, publicClient, sma, permissions, json);
|
|
42502
43071
|
for (const permission of permissions) {
|
|
42503
|
-
|
|
43072
|
+
store.ensureTracked({
|
|
43073
|
+
name: knownTemplateLabel(project.chainId, permission) ?? permission,
|
|
43074
|
+
address: permission,
|
|
43075
|
+
txHash,
|
|
43076
|
+
chainId: project.chainId,
|
|
43077
|
+
deployedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43078
|
+
});
|
|
43079
|
+
store.recordAttachment(permission, { sma, txHash });
|
|
42504
43080
|
}
|
|
42505
43081
|
emit(json, () => {
|
|
42506
43082
|
}, {
|
|
@@ -42756,6 +43332,8 @@ Attaching ${permissions.length} permissions in one signature \u2014 the mandate
|
|
|
42756
43332
|
explanation: (rec ? explainPermission(rec.name, rec.sourcePath) : null) ?? void 0
|
|
42757
43333
|
};
|
|
42758
43334
|
});
|
|
43335
|
+
const flatFee = await readPermissionRegistrationFee(publicClient, project.contracts.governance);
|
|
43336
|
+
const fee = flatFee * BigInt(permissions.length);
|
|
42759
43337
|
const response = await channel.requestSignature({
|
|
42760
43338
|
type: "typed-data",
|
|
42761
43339
|
kind: "register-permission",
|
|
@@ -42768,6 +43346,11 @@ Attaching ${permissions.length} permissions in one signature \u2014 the mandate
|
|
|
42768
43346
|
{ label: "Mandate signer", value: permissionSigner }
|
|
42769
43347
|
],
|
|
42770
43348
|
permissions: permExplanations,
|
|
43349
|
+
registrationFee: {
|
|
43350
|
+
totalEth: formatEther(fee),
|
|
43351
|
+
permissionCount: permissions.length,
|
|
43352
|
+
...permissions.length > 1 ? { perPermissionEth: formatEther(flatFee) } : {}
|
|
43353
|
+
},
|
|
42771
43354
|
typedData
|
|
42772
43355
|
});
|
|
42773
43356
|
if (response.status === "rejected") {
|
|
@@ -42776,10 +43359,6 @@ Attaching ${permissions.length} permissions in one signature \u2014 the mandate
|
|
|
42776
43359
|
if (response.status !== "signature") {
|
|
42777
43360
|
throw new Error(`Expected an EIP-712 signature response, got: ${response.status}`);
|
|
42778
43361
|
}
|
|
42779
|
-
let fee = 0n;
|
|
42780
|
-
for (const permission of permissions) {
|
|
42781
|
-
fee += await estimatePermissionFee(publicClient, project.contracts.governance, permission);
|
|
42782
|
-
}
|
|
42783
43362
|
const chain2 = getChainById(project.chainId);
|
|
42784
43363
|
const walletClient = createWalletClient({
|
|
42785
43364
|
account: agentSigner.viemAccount,
|
|
@@ -42812,7 +43391,10 @@ Attaching ${permissions.length} permissions in one signature \u2014 the mandate
|
|
|
42812
43391
|
permission,
|
|
42813
43392
|
sma,
|
|
42814
43393
|
txHash,
|
|
42815
|
-
chainId: project.chainId
|
|
43394
|
+
chainId: project.chainId,
|
|
43395
|
+
// Each permission in the batch is charged the same flat fee.
|
|
43396
|
+
fee: flatFee.toString(),
|
|
43397
|
+
feeEth: formatEther(flatFee)
|
|
42816
43398
|
});
|
|
42817
43399
|
say(() => {
|
|
42818
43400
|
if (!present) {
|
|
@@ -43024,6 +43606,35 @@ function runForgeBuild() {
|
|
|
43024
43606
|
|
|
43025
43607
|
// src/commands/mandate.ts
|
|
43026
43608
|
init_esm2();
|
|
43609
|
+
function chargeablePermissions(tracked) {
|
|
43610
|
+
return tracked.filter((p) => !p.revokedOnChain && !p.registeredOnSma);
|
|
43611
|
+
}
|
|
43612
|
+
async function liveMandateFee(chainId, permissionAddresses) {
|
|
43613
|
+
if (permissionAddresses.length === 0) return { totalWei: 0n, perPermission: [] };
|
|
43614
|
+
try {
|
|
43615
|
+
const deployment = getSailDeployment(chainId);
|
|
43616
|
+
const rpcUrl = getRpcUrl(chainId) ?? getChainById(chainId).rpcUrls.default.http[0];
|
|
43617
|
+
const pc = createPublicClient({ chain: getChainById(chainId), transport: http(rpcUrl) });
|
|
43618
|
+
return await estimateMandateRegistrationFee(
|
|
43619
|
+
pc,
|
|
43620
|
+
deployment.governance,
|
|
43621
|
+
permissionAddresses
|
|
43622
|
+
);
|
|
43623
|
+
} catch {
|
|
43624
|
+
return null;
|
|
43625
|
+
}
|
|
43626
|
+
}
|
|
43627
|
+
function draftFeeFromEstimate(estimate) {
|
|
43628
|
+
const perFeeWei = estimate.perPermission[0]?.feeWei ?? 0n;
|
|
43629
|
+
return {
|
|
43630
|
+
perPermissionWei: perFeeWei.toString(),
|
|
43631
|
+
perPermissionEth: formatEther(perFeeWei),
|
|
43632
|
+
totalWei: estimate.totalWei.toString(),
|
|
43633
|
+
totalEth: formatEther(estimate.totalWei),
|
|
43634
|
+
permissionCount: estimate.perPermission.length,
|
|
43635
|
+
disclosure: describeMandateFee(estimate)
|
|
43636
|
+
};
|
|
43637
|
+
}
|
|
43027
43638
|
function resolveActiveChain(account2) {
|
|
43028
43639
|
try {
|
|
43029
43640
|
const project = new ProjectContext();
|
|
@@ -43061,14 +43672,37 @@ async function trackedPermissionsFor(account2, chainId, kernel) {
|
|
|
43061
43672
|
};
|
|
43062
43673
|
});
|
|
43063
43674
|
const onChain = kernel ? await fetchOnChainPermissions(account2.safe, chainId, kernel) : null;
|
|
43064
|
-
if (onChain
|
|
43065
|
-
|
|
43066
|
-
|
|
43067
|
-
|
|
43068
|
-
|
|
43675
|
+
if (onChain === null) return local;
|
|
43676
|
+
return mergeOnChainPermissions(local, onChain, knownTemplateLabeler(chainId));
|
|
43677
|
+
}
|
|
43678
|
+
function mergeOnChainPermissions(local, onChain, labelFor = () => void 0) {
|
|
43679
|
+
for (const p of local) {
|
|
43680
|
+
if (p.registeredOnSma && !onChain.has(p.address.toLowerCase())) {
|
|
43681
|
+
p.revokedOnChain = true;
|
|
43682
|
+
}
|
|
43683
|
+
}
|
|
43684
|
+
const localAddrs = new Set(local.map((p) => p.address.toLowerCase()));
|
|
43685
|
+
const extra = [];
|
|
43686
|
+
for (const addr of onChain) {
|
|
43687
|
+
if (!localAddrs.has(addr)) {
|
|
43688
|
+
extra.push({
|
|
43689
|
+
address: addr,
|
|
43690
|
+
label: labelFor(addr) ?? `permission ${addr.slice(0, 10)}\u2026`,
|
|
43691
|
+
registeredOnSma: true
|
|
43692
|
+
});
|
|
43693
|
+
}
|
|
43694
|
+
}
|
|
43695
|
+
return [...local, ...extra];
|
|
43696
|
+
}
|
|
43697
|
+
function knownTemplateLabeler(chainId) {
|
|
43698
|
+
const map = /* @__PURE__ */ new Map();
|
|
43699
|
+
try {
|
|
43700
|
+
for (const t of getSailDeployment(chainId).knownTemplates ?? []) {
|
|
43701
|
+
map.set(t.address.toLowerCase(), t.label);
|
|
43069
43702
|
}
|
|
43703
|
+
} catch {
|
|
43070
43704
|
}
|
|
43071
|
-
return
|
|
43705
|
+
return (addr) => map.get(addr.toLowerCase());
|
|
43072
43706
|
}
|
|
43073
43707
|
function printNoPermissionsGuidance() {
|
|
43074
43708
|
console.log(
|
|
@@ -43096,19 +43730,28 @@ ${permissions.length} permission(s) tracked for SMA ${account2.safe}:
|
|
|
43096
43730
|
console.log(` ${status2}`);
|
|
43097
43731
|
}
|
|
43098
43732
|
const store = new MandateStore();
|
|
43733
|
+
const chargeable = chargeablePermissions(permissions);
|
|
43734
|
+
const draftPermissions = chargeable.map((p) => {
|
|
43735
|
+
const mandate2 = store.find(p.address);
|
|
43736
|
+
const explanation = explainPermission(p.label, mandate2?.sourcePath) ?? void 0;
|
|
43737
|
+
return { address: p.address, label: p.label, explanation };
|
|
43738
|
+
});
|
|
43739
|
+
let registrationFee;
|
|
43740
|
+
const unregisteredAddresses = chargeable.map((p) => p.address);
|
|
43741
|
+
if (unregisteredAddresses.length > 0) {
|
|
43742
|
+
const estimate = await liveMandateFee(chainId, unregisteredAddresses);
|
|
43743
|
+
if (estimate !== null) registrationFee = draftFeeFromEstimate(estimate);
|
|
43744
|
+
}
|
|
43099
43745
|
const draft = {
|
|
43100
43746
|
account: account2.safe,
|
|
43101
43747
|
chainId,
|
|
43102
|
-
|
|
43103
|
-
|
|
43104
|
-
|
|
43105
|
-
const mandate2 = store.find(p.address);
|
|
43106
|
-
const explanation = explainPermission(p.label, mandate2?.sourcePath) ?? void 0;
|
|
43107
|
-
return { address: p.address, label: p.label, explanation };
|
|
43108
|
-
}),
|
|
43109
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
43748
|
+
permissions: draftPermissions,
|
|
43749
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
43750
|
+
...registrationFee ? { registrationFee } : {}
|
|
43110
43751
|
};
|
|
43111
43752
|
writeJsonFile(sailPath("mandate-draft.json"), draft);
|
|
43753
|
+
if (registrationFee) console.log(`
|
|
43754
|
+
${registrationFee.disclosure}`);
|
|
43112
43755
|
console.log("\nDraft written to .sail/mandate-draft.json for the UI to display.");
|
|
43113
43756
|
}
|
|
43114
43757
|
async function mandateSign(opts = {}) {
|
|
@@ -43135,6 +43778,15 @@ Permissions tracked for SMA ${account2.safe}:
|
|
|
43135
43778
|
"\nNote: `sailor mandate sign` reviews and confirms the permissions attached to your SMA.\nOn-chain registration happens via `sailor mandate attach` (or `sailor mandate deploy --attach`)."
|
|
43136
43779
|
);
|
|
43137
43780
|
const activePermissions = permissions.filter((p) => !p.revokedOnChain);
|
|
43781
|
+
const unregistered = chargeablePermissions(permissions);
|
|
43782
|
+
if (unregistered.length > 0) {
|
|
43783
|
+
const estimate = await liveMandateFee(chainId, unregistered.map((p) => p.address));
|
|
43784
|
+
if (estimate !== null) {
|
|
43785
|
+
console.log(`
|
|
43786
|
+
${describeMandateFee(estimate)}`);
|
|
43787
|
+
console.log(" Paid by the agent wallet on registration, per permission.");
|
|
43788
|
+
}
|
|
43789
|
+
}
|
|
43138
43790
|
const proceed = opts.yes || await confirm(
|
|
43139
43791
|
`Confirm these ${activePermissions.length} permission(s) are authorized for your SMA?`
|
|
43140
43792
|
);
|
|
@@ -43142,7 +43794,6 @@ Permissions tracked for SMA ${account2.safe}:
|
|
|
43142
43794
|
console.log("No permissions confirmed.");
|
|
43143
43795
|
return;
|
|
43144
43796
|
}
|
|
43145
|
-
const unregistered = activePermissions.filter((p) => !p.registeredOnSma);
|
|
43146
43797
|
if (unregistered.length === 0) {
|
|
43147
43798
|
console.log(`
|
|
43148
43799
|
\u2713 Confirmed ${activePermissions.length} permission(s) for ${account2.safe}.`);
|
|
@@ -43173,8 +43824,451 @@ ${unregistered.length} permission(s) are not yet registered on this SMA. Initiat
|
|
|
43173
43824
|
\u2713 Saved to .sail/mandate.json \u2014 agent is ready to run.`);
|
|
43174
43825
|
}
|
|
43175
43826
|
|
|
43176
|
-
// src/commands/mandate-
|
|
43827
|
+
// src/commands/mandate-configure.ts
|
|
43177
43828
|
var import_node_fs15 = require("node:fs");
|
|
43829
|
+
var import_node_path13 = require("node:path");
|
|
43830
|
+
|
|
43831
|
+
// ../sdk/dist/templates/boundedSwap.js
|
|
43832
|
+
init_esm2();
|
|
43833
|
+
var ABI = [
|
|
43834
|
+
{ name: "routers", type: "address[]" },
|
|
43835
|
+
{ name: "tokensIn", type: "address[]" },
|
|
43836
|
+
{ name: "tokensOut", type: "address[]" },
|
|
43837
|
+
{ name: "maxAmountPerTx", type: "uint256" },
|
|
43838
|
+
{ name: "maxSlippageBps", type: "uint256" },
|
|
43839
|
+
{ name: "priceOracle", type: "address" },
|
|
43840
|
+
{ name: "maxPriceAgeSec", type: "uint256" }
|
|
43841
|
+
];
|
|
43842
|
+
var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
43843
|
+
var boundedSwapTemplate = {
|
|
43844
|
+
name: "SharedBoundedSwapPermission",
|
|
43845
|
+
address: "0x0000000000000000000000000000000000000000",
|
|
43846
|
+
encoder: {
|
|
43847
|
+
encode(params) {
|
|
43848
|
+
return encodeAbiParameters(ABI, [
|
|
43849
|
+
params.routers,
|
|
43850
|
+
params.tokensIn,
|
|
43851
|
+
params.tokensOut,
|
|
43852
|
+
params.maxAmountPerTx,
|
|
43853
|
+
BigInt(params.maxSlippageBps),
|
|
43854
|
+
params.priceOracle,
|
|
43855
|
+
BigInt(params.maxPriceAgeSec)
|
|
43856
|
+
]);
|
|
43857
|
+
},
|
|
43858
|
+
decode(data) {
|
|
43859
|
+
const decoded = decodeAbiParameters(ABI, data);
|
|
43860
|
+
return {
|
|
43861
|
+
routers: [...decoded[0]],
|
|
43862
|
+
tokensIn: [...decoded[1]],
|
|
43863
|
+
tokensOut: [...decoded[2]],
|
|
43864
|
+
maxAmountPerTx: decoded[3],
|
|
43865
|
+
maxSlippageBps: Number(decoded[4]),
|
|
43866
|
+
priceOracle: decoded[5],
|
|
43867
|
+
maxPriceAgeSec: Number(decoded[6])
|
|
43868
|
+
};
|
|
43869
|
+
}
|
|
43870
|
+
},
|
|
43871
|
+
explainer: {
|
|
43872
|
+
explain(params) {
|
|
43873
|
+
const warnings = [];
|
|
43874
|
+
if (params.maxSlippageBps > 100) {
|
|
43875
|
+
warnings.push(`High slippage tolerance: ${params.maxSlippageBps / 100}%`);
|
|
43876
|
+
}
|
|
43877
|
+
if (params.priceOracle === ZERO_ADDRESS) {
|
|
43878
|
+
warnings.push("No price oracle configured \u2014 swaps are not checked against a reference price");
|
|
43879
|
+
}
|
|
43880
|
+
return {
|
|
43881
|
+
templateName: "SharedBoundedSwapPermission",
|
|
43882
|
+
humanReadable: [
|
|
43883
|
+
`Maximum input per swap: ${params.maxAmountPerTx.toString()} (input-token base units)`,
|
|
43884
|
+
`Maximum slippage: ${params.maxSlippageBps / 100}%`,
|
|
43885
|
+
`Allowed routers: ${params.routers.join(", ")}`,
|
|
43886
|
+
`Allowed input tokens: ${params.tokensIn.join(", ")}`,
|
|
43887
|
+
`Allowed output tokens: ${params.tokensOut.join(", ")}`,
|
|
43888
|
+
params.priceOracle === ZERO_ADDRESS ? "Price oracle: none" : `Price oracle: ${params.priceOracle} (max age ${params.maxPriceAgeSec}s)`
|
|
43889
|
+
],
|
|
43890
|
+
warnings
|
|
43891
|
+
};
|
|
43892
|
+
}
|
|
43893
|
+
}
|
|
43894
|
+
};
|
|
43895
|
+
|
|
43896
|
+
// src/commands/mandate-configure.ts
|
|
43897
|
+
init_esm2();
|
|
43898
|
+
var TEMPLATE_REGISTRY = {
|
|
43899
|
+
SwapPermission: {
|
|
43900
|
+
label: "Bounded Swap (Uniswap V3)",
|
|
43901
|
+
bigintFields: ["maxAmountPerTx"],
|
|
43902
|
+
encode: (raw) => boundedSwapTemplate.encoder.encode(coerceSwapParams(raw)),
|
|
43903
|
+
decode: (blob) => {
|
|
43904
|
+
const p = boundedSwapTemplate.encoder.decode(blob);
|
|
43905
|
+
return {
|
|
43906
|
+
routers: p.routers,
|
|
43907
|
+
tokensIn: p.tokensIn,
|
|
43908
|
+
tokensOut: p.tokensOut,
|
|
43909
|
+
maxAmountPerTx: p.maxAmountPerTx.toString(),
|
|
43910
|
+
maxSlippageBps: p.maxSlippageBps,
|
|
43911
|
+
priceOracle: p.priceOracle,
|
|
43912
|
+
maxPriceAgeSec: p.maxPriceAgeSec
|
|
43913
|
+
};
|
|
43914
|
+
}
|
|
43915
|
+
}
|
|
43916
|
+
};
|
|
43917
|
+
function asAddressArray(v, field) {
|
|
43918
|
+
if (!Array.isArray(v)) throw new Error(`${field}: expected an array of addresses`);
|
|
43919
|
+
return v.map((x, i) => {
|
|
43920
|
+
if (typeof x !== "string" || !isAddress(x, { strict: false })) {
|
|
43921
|
+
throw new Error(`${field}[${i}]: invalid address "${String(x)}"`);
|
|
43922
|
+
}
|
|
43923
|
+
return getAddress(x);
|
|
43924
|
+
});
|
|
43925
|
+
}
|
|
43926
|
+
function asAddress(v, field) {
|
|
43927
|
+
if (typeof v !== "string" || !isAddress(v, { strict: false })) {
|
|
43928
|
+
throw new Error(`${field}: invalid address "${String(v)}"`);
|
|
43929
|
+
}
|
|
43930
|
+
return getAddress(v);
|
|
43931
|
+
}
|
|
43932
|
+
function asUint(v, field) {
|
|
43933
|
+
if (v === void 0 || v === null) throw new Error(`${field}: missing`);
|
|
43934
|
+
try {
|
|
43935
|
+
return BigInt(typeof v === "string" || typeof v === "number" ? v : String(v));
|
|
43936
|
+
} catch {
|
|
43937
|
+
throw new Error(`${field}: expected an integer, got "${String(v)}"`);
|
|
43938
|
+
}
|
|
43939
|
+
}
|
|
43940
|
+
function asInt(v, field) {
|
|
43941
|
+
const n = asUint(v, field);
|
|
43942
|
+
return Number(n);
|
|
43943
|
+
}
|
|
43944
|
+
function coerceSwapParams(raw) {
|
|
43945
|
+
return {
|
|
43946
|
+
routers: asAddressArray(raw.routers, "routers"),
|
|
43947
|
+
tokensIn: asAddressArray(raw.tokensIn, "tokensIn"),
|
|
43948
|
+
tokensOut: asAddressArray(raw.tokensOut, "tokensOut"),
|
|
43949
|
+
maxAmountPerTx: asUint(raw.maxAmountPerTx, "maxAmountPerTx"),
|
|
43950
|
+
maxSlippageBps: asInt(raw.maxSlippageBps, "maxSlippageBps"),
|
|
43951
|
+
priceOracle: asAddress(raw.priceOracle, "priceOracle"),
|
|
43952
|
+
maxPriceAgeSec: asInt(raw.maxPriceAgeSec, "maxPriceAgeSec")
|
|
43953
|
+
};
|
|
43954
|
+
}
|
|
43955
|
+
function requireProject2() {
|
|
43956
|
+
if (!ProjectContext.exists()) {
|
|
43957
|
+
console.log('No Sailor project found. Run "sailor init" first.');
|
|
43958
|
+
process.exit(1);
|
|
43959
|
+
}
|
|
43960
|
+
return new ProjectContext();
|
|
43961
|
+
}
|
|
43962
|
+
function fail2(err, json = false) {
|
|
43963
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
43964
|
+
emit(json, () => console.error(`
|
|
43965
|
+
Mandate configure failed: ${msg}`), {
|
|
43966
|
+
status: "error",
|
|
43967
|
+
error: msg
|
|
43968
|
+
});
|
|
43969
|
+
process.exit(1);
|
|
43970
|
+
}
|
|
43971
|
+
function publicClientFor2(project) {
|
|
43972
|
+
return createPublicClient({
|
|
43973
|
+
chain: getChainById(project.chainId),
|
|
43974
|
+
transport: http(getRpcUrl(project.chainId))
|
|
43975
|
+
}).extend(publicActions);
|
|
43976
|
+
}
|
|
43977
|
+
function announceSigningUrl2(json) {
|
|
43978
|
+
const url = signingPageUrl(projectPort(process.cwd()));
|
|
43979
|
+
if (json) {
|
|
43980
|
+
process.stdout.write(`${JSON.stringify({ status: "waiting_for_signature", url })}
|
|
43981
|
+
`);
|
|
43982
|
+
} else {
|
|
43983
|
+
console.log(`
|
|
43984
|
+
\u2192 Open the Sailor dashboard to approve signing requests:
|
|
43985
|
+
${url}
|
|
43986
|
+
`);
|
|
43987
|
+
}
|
|
43988
|
+
}
|
|
43989
|
+
function resolveBlob(options) {
|
|
43990
|
+
const hasParams = options.params !== void 0;
|
|
43991
|
+
const hasArgsFile = options.argsFile !== void 0;
|
|
43992
|
+
if (hasParams && hasArgsFile) {
|
|
43993
|
+
throw new Error("Provide EITHER --params <hex> OR --args-file <path>, not both.");
|
|
43994
|
+
}
|
|
43995
|
+
if (!hasParams && !hasArgsFile) {
|
|
43996
|
+
throw new Error(
|
|
43997
|
+
"Provide the config blob as --params <0x-hex>, or as --args-file <path> paired with --template <Name>."
|
|
43998
|
+
);
|
|
43999
|
+
}
|
|
44000
|
+
if (hasParams) {
|
|
44001
|
+
const raw2 = options.params.trim();
|
|
44002
|
+
if (!isHex(raw2) || raw2.length <= 2) {
|
|
44003
|
+
throw new Error(`--params must be 0x-prefixed hex; got "${options.params}".`);
|
|
44004
|
+
}
|
|
44005
|
+
return { blob: raw2, via: "params" };
|
|
44006
|
+
}
|
|
44007
|
+
const templateName = options.template;
|
|
44008
|
+
if (!templateName) {
|
|
44009
|
+
throw new Error("--args-file requires --template <Name> (e.g. SwapPermission).");
|
|
44010
|
+
}
|
|
44011
|
+
const entry = TEMPLATE_REGISTRY[templateName];
|
|
44012
|
+
if (!entry) {
|
|
44013
|
+
throw new Error(
|
|
44014
|
+
`Unknown --template "${templateName}". Known: ${Object.keys(TEMPLATE_REGISTRY).join(", ")}. Pass a pre-encoded blob with --params for any other template.`
|
|
44015
|
+
);
|
|
44016
|
+
}
|
|
44017
|
+
const argsFilePath = (0, import_node_path13.resolve)(options.argsFile);
|
|
44018
|
+
let raw;
|
|
44019
|
+
try {
|
|
44020
|
+
raw = (0, import_node_fs15.readFileSync)(argsFilePath, "utf8").trim();
|
|
44021
|
+
} catch {
|
|
44022
|
+
throw new Error(`Cannot read --args-file: ${argsFilePath}`);
|
|
44023
|
+
}
|
|
44024
|
+
let parsed;
|
|
44025
|
+
try {
|
|
44026
|
+
parsed = JSON.parse(raw);
|
|
44027
|
+
} catch (err) {
|
|
44028
|
+
throw new Error(`--args-file is not valid JSON: ${err.message}`);
|
|
44029
|
+
}
|
|
44030
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
44031
|
+
throw new Error("--args-file must contain a JSON object of template params.");
|
|
44032
|
+
}
|
|
44033
|
+
const blob = entry.encode(parsed);
|
|
44034
|
+
return { blob, via: `template:${templateName}` };
|
|
44035
|
+
}
|
|
44036
|
+
async function mandateConfigure(options) {
|
|
44037
|
+
const project = requireProject2();
|
|
44038
|
+
const channel = await createSigningChannel(process.cwd());
|
|
44039
|
+
try {
|
|
44040
|
+
await channel.start();
|
|
44041
|
+
await runConfigure(project, channel, options);
|
|
44042
|
+
} catch (err) {
|
|
44043
|
+
fail2(err, options.json);
|
|
44044
|
+
} finally {
|
|
44045
|
+
channel.stop();
|
|
44046
|
+
}
|
|
44047
|
+
}
|
|
44048
|
+
async function runConfigure(project, channel, options) {
|
|
44049
|
+
const json = !!options.json;
|
|
44050
|
+
const say = (fn) => {
|
|
44051
|
+
if (!json) fn();
|
|
44052
|
+
};
|
|
44053
|
+
if (!isAddress(options.sma, { strict: false })) {
|
|
44054
|
+
throw new Error(`Invalid --sma address: ${options.sma}`);
|
|
44055
|
+
}
|
|
44056
|
+
if (!isAddress(options.address, { strict: false })) {
|
|
44057
|
+
throw new Error(
|
|
44058
|
+
`--address must be a deployed shared-template singleton address: ${options.address}`
|
|
44059
|
+
);
|
|
44060
|
+
}
|
|
44061
|
+
const sma = getAddress(options.sma);
|
|
44062
|
+
const singleton = getAddress(options.address);
|
|
44063
|
+
const { blob, via } = resolveBlob(options);
|
|
44064
|
+
const publicClient = publicClientFor2(project);
|
|
44065
|
+
const registered = await publicClient.readContract({
|
|
44066
|
+
address: project.contracts.kernel,
|
|
44067
|
+
abi: SailKernelAbi,
|
|
44068
|
+
functionName: "registered",
|
|
44069
|
+
args: [sma]
|
|
44070
|
+
});
|
|
44071
|
+
if (!registered) {
|
|
44072
|
+
throw new Error(`SMA ${sma} is not registered with SailKernel; cannot configure a permission for it.`);
|
|
44073
|
+
}
|
|
44074
|
+
const kernelConfig = await publicClient.readContract({
|
|
44075
|
+
address: project.contracts.kernel,
|
|
44076
|
+
abi: SailKernelAbi,
|
|
44077
|
+
functionName: "configs",
|
|
44078
|
+
args: [sma]
|
|
44079
|
+
});
|
|
44080
|
+
const permissionSigner = kernelConfig[0];
|
|
44081
|
+
if (!permissionSigner || permissionSigner === getAddress("0x0000000000000000000000000000000000000000")) {
|
|
44082
|
+
throw new Error(`SMA ${sma} has no on-chain permissionSigner; cannot configure.`);
|
|
44083
|
+
}
|
|
44084
|
+
const alreadyConfigured = await publicClient.readContract({
|
|
44085
|
+
address: singleton,
|
|
44086
|
+
abi: ConfigurablePermissionAbi,
|
|
44087
|
+
functionName: "isConfigured",
|
|
44088
|
+
args: [sma]
|
|
44089
|
+
});
|
|
44090
|
+
if (alreadyConfigured && !options.force) {
|
|
44091
|
+
say(
|
|
44092
|
+
() => console.log(
|
|
44093
|
+
`
|
|
44094
|
+
\u2713 ${singleton} is already configured for ${sma} (isConfigured == true).
|
|
44095
|
+
Re-run with --force to overwrite the current bounds.`
|
|
44096
|
+
)
|
|
44097
|
+
);
|
|
44098
|
+
emit(
|
|
44099
|
+
json,
|
|
44100
|
+
() => {
|
|
44101
|
+
},
|
|
44102
|
+
{ status: "ok", alreadyConfigured: true, singleton, sma, chainId: project.chainId }
|
|
44103
|
+
);
|
|
44104
|
+
return;
|
|
44105
|
+
}
|
|
44106
|
+
const nonce = await publicClient.readContract({
|
|
44107
|
+
address: singleton,
|
|
44108
|
+
abi: ConfigurablePermissionAbi,
|
|
44109
|
+
functionName: "configNonces",
|
|
44110
|
+
args: [sma]
|
|
44111
|
+
});
|
|
44112
|
+
say(() => {
|
|
44113
|
+
console.log(`
|
|
44114
|
+
configure ${singleton}`);
|
|
44115
|
+
console.log(` SMA: ${sma}`);
|
|
44116
|
+
console.log(` permissionSigner: ${permissionSigner} (must sign in the browser \u2014 owner tx)`);
|
|
44117
|
+
console.log(` current nonce: ${nonce}`);
|
|
44118
|
+
console.log(` already set: ${alreadyConfigured ? "yes (--force will overwrite)" : "no"}`);
|
|
44119
|
+
console.log(` config blob: ${blob} (via ${via}, ${Math.floor((blob.length - 2) / 2)} bytes)`);
|
|
44120
|
+
});
|
|
44121
|
+
const configureDirectData = encodeFunctionData({
|
|
44122
|
+
abi: ConfigurablePermissionAbi,
|
|
44123
|
+
functionName: "configureDirect",
|
|
44124
|
+
args: [sma, blob]
|
|
44125
|
+
});
|
|
44126
|
+
say(() => console.log(`
|
|
44127
|
+
Pre-flight (eth_call of configureDirect, no gas)\u2026`));
|
|
44128
|
+
try {
|
|
44129
|
+
await publicClient.simulateContract({
|
|
44130
|
+
address: singleton,
|
|
44131
|
+
abi: ConfigurablePermissionAbi,
|
|
44132
|
+
functionName: "configureDirect",
|
|
44133
|
+
args: [sma, blob],
|
|
44134
|
+
account: permissionSigner
|
|
44135
|
+
});
|
|
44136
|
+
} catch (err) {
|
|
44137
|
+
const ce = getContractError(err, {
|
|
44138
|
+
abi: ConfigurablePermissionAbi,
|
|
44139
|
+
address: singleton,
|
|
44140
|
+
args: [sma, blob],
|
|
44141
|
+
functionName: "configureDirect"
|
|
44142
|
+
});
|
|
44143
|
+
const reason = ce?.message ?? err?.message ?? String(err);
|
|
44144
|
+
throw new Error(
|
|
44145
|
+
`Pre-flight reverted \u2014 the config blob is invalid for ${singleton} on ${sma}.
|
|
44146
|
+
Revert: ${reason}
|
|
44147
|
+
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.`
|
|
44148
|
+
);
|
|
44149
|
+
}
|
|
44150
|
+
say(() => console.log("\u2713 pre-flight passed (configureDirect would succeed)."));
|
|
44151
|
+
let decoded;
|
|
44152
|
+
if (options.template && TEMPLATE_REGISTRY[options.template]) {
|
|
44153
|
+
try {
|
|
44154
|
+
decoded = TEMPLATE_REGISTRY[options.template].decode(blob);
|
|
44155
|
+
say(() => {
|
|
44156
|
+
console.log("\nDecoded bounds (what the singleton will store):");
|
|
44157
|
+
for (const [k, v] of Object.entries(decoded)) {
|
|
44158
|
+
const display = Array.isArray(v) ? v.join(", ") : String(v);
|
|
44159
|
+
console.log(` ${k}: ${display}`);
|
|
44160
|
+
}
|
|
44161
|
+
});
|
|
44162
|
+
} catch {
|
|
44163
|
+
}
|
|
44164
|
+
}
|
|
44165
|
+
if (options.simulateOnly) {
|
|
44166
|
+
emit(
|
|
44167
|
+
json,
|
|
44168
|
+
() => {
|
|
44169
|
+
console.log("\n--simulate-only: stopping after pre-flight (no signing, no gas).");
|
|
44170
|
+
},
|
|
44171
|
+
{
|
|
44172
|
+
status: "ok",
|
|
44173
|
+
simulateOnly: true,
|
|
44174
|
+
singleton,
|
|
44175
|
+
sma,
|
|
44176
|
+
permissionSigner,
|
|
44177
|
+
nonce: nonce.toString(),
|
|
44178
|
+
alreadyConfigured,
|
|
44179
|
+
blob,
|
|
44180
|
+
blobBytes: Math.floor((blob.length - 2) / 2),
|
|
44181
|
+
decoded,
|
|
44182
|
+
chainId: project.chainId
|
|
44183
|
+
}
|
|
44184
|
+
);
|
|
44185
|
+
return;
|
|
44186
|
+
}
|
|
44187
|
+
const label = options.label ?? (options.template ?? "shared-template");
|
|
44188
|
+
announceSigningUrl2(json);
|
|
44189
|
+
say(
|
|
44190
|
+
() => console.log(
|
|
44191
|
+
`Pushing configure request \u2014 the mandate signer (${permissionSigner}) must approve in the browser\u2026`
|
|
44192
|
+
)
|
|
44193
|
+
);
|
|
44194
|
+
const response = await channel.requestSignature({
|
|
44195
|
+
type: "transaction",
|
|
44196
|
+
kind: "arbitrary-tx",
|
|
44197
|
+
title: `Configure "${label}"`,
|
|
44198
|
+
description: `Write per-account bounds on the shared permission ${singleton}.
|
|
44199
|
+
You (the mandate signer) send the transaction \u2014 configureDirect requires msg.sender to be the permissionSigner.`,
|
|
44200
|
+
chainId: project.chainId,
|
|
44201
|
+
to: singleton,
|
|
44202
|
+
data: configureDirectData,
|
|
44203
|
+
details: [
|
|
44204
|
+
{ label: "SMA", value: sma },
|
|
44205
|
+
{ label: "Singleton", value: singleton },
|
|
44206
|
+
{ label: "Template", value: options.template ?? "(raw blob)" },
|
|
44207
|
+
{ label: "Mandate signer", value: permissionSigner },
|
|
44208
|
+
{ label: "Config blob (bytes)", value: String(Math.floor((blob.length - 2) / 2)) },
|
|
44209
|
+
...decoded ? Object.entries(decoded).map(([k, v]) => ({
|
|
44210
|
+
label: k,
|
|
44211
|
+
value: Array.isArray(v) ? v.join(", ") : String(v)
|
|
44212
|
+
})) : []
|
|
44213
|
+
]
|
|
44214
|
+
});
|
|
44215
|
+
if (response.status === "rejected") {
|
|
44216
|
+
throw new Error(`User rejected configure: ${response.reason ?? "no reason given"}`);
|
|
44217
|
+
}
|
|
44218
|
+
if (response.status !== "signed") {
|
|
44219
|
+
throw new Error(`Expected a signed transaction, got: ${response.status}`);
|
|
44220
|
+
}
|
|
44221
|
+
say(() => console.log("Waiting for confirmation\u2026"));
|
|
44222
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash: response.txHash });
|
|
44223
|
+
if (receipt.status !== "success") {
|
|
44224
|
+
throw new Error(`configureDirect transaction failed (tx ${response.txHash})`);
|
|
44225
|
+
}
|
|
44226
|
+
const configuredNow = await publicClient.readContract({
|
|
44227
|
+
address: singleton,
|
|
44228
|
+
abi: ConfigurablePermissionAbi,
|
|
44229
|
+
functionName: "isConfigured",
|
|
44230
|
+
args: [sma]
|
|
44231
|
+
});
|
|
44232
|
+
if (!configuredNow) {
|
|
44233
|
+
throw new Error(
|
|
44234
|
+
`Tx ${response.txHash} mined, but isConfigured(${sma}) is still false. Verify on-chain.`
|
|
44235
|
+
);
|
|
44236
|
+
}
|
|
44237
|
+
say(() => console.log("\u2713", `Configured ${singleton} for ${sma} (isConfigured == true).`));
|
|
44238
|
+
appendActivity({
|
|
44239
|
+
ts: nowIso(),
|
|
44240
|
+
actor: "owner",
|
|
44241
|
+
type: "permission_configured",
|
|
44242
|
+
permission: singleton,
|
|
44243
|
+
name: label,
|
|
44244
|
+
sma,
|
|
44245
|
+
txHash: response.txHash,
|
|
44246
|
+
chainId: project.chainId
|
|
44247
|
+
});
|
|
44248
|
+
emit(
|
|
44249
|
+
json,
|
|
44250
|
+
() => {
|
|
44251
|
+
console.log(
|
|
44252
|
+
`
|
|
44253
|
+
Next: prove it accepts/rejects the right calls before dispatching:
|
|
44254
|
+
sailor mandate simulate --address ${singleton} --sma ${sma} --calls ./probe.json`
|
|
44255
|
+
);
|
|
44256
|
+
},
|
|
44257
|
+
{
|
|
44258
|
+
status: "ok",
|
|
44259
|
+
singleton,
|
|
44260
|
+
sma,
|
|
44261
|
+
template: options.template,
|
|
44262
|
+
permissionSigner,
|
|
44263
|
+
txHash: response.txHash,
|
|
44264
|
+
blob,
|
|
44265
|
+
chainId: project.chainId
|
|
44266
|
+
}
|
|
44267
|
+
);
|
|
44268
|
+
}
|
|
44269
|
+
|
|
44270
|
+
// src/commands/mandate-simulate.ts
|
|
44271
|
+
var import_node_fs16 = require("node:fs");
|
|
43178
44272
|
init_esm2();
|
|
43179
44273
|
function parseExpect(raw, where) {
|
|
43180
44274
|
if (raw === void 0) return void 0;
|
|
@@ -43190,7 +44284,7 @@ function resolveSampleCalls(options) {
|
|
|
43190
44284
|
if (options.calls) {
|
|
43191
44285
|
let raw;
|
|
43192
44286
|
try {
|
|
43193
|
-
raw = JSON.parse((0,
|
|
44287
|
+
raw = JSON.parse((0, import_node_fs16.readFileSync)(options.calls, "utf8"));
|
|
43194
44288
|
} catch (err) {
|
|
43195
44289
|
throw new Error(`Could not read --calls file "${options.calls}": ${err.message}`);
|
|
43196
44290
|
}
|
|
@@ -43294,6 +44388,7 @@ async function mandateSimulate(options) {
|
|
|
43294
44388
|
const [probe, codeCheck] = await Promise.all([
|
|
43295
44389
|
probePermissionForCall({
|
|
43296
44390
|
publicClient: pc,
|
|
44391
|
+
kernel: project.contracts.kernel,
|
|
43297
44392
|
permission,
|
|
43298
44393
|
account: account2,
|
|
43299
44394
|
manager,
|
|
@@ -43406,7 +44501,7 @@ async function mandateSimulate(options) {
|
|
|
43406
44501
|
}
|
|
43407
44502
|
|
|
43408
44503
|
// src/commands/rotate-signer.ts
|
|
43409
|
-
var
|
|
44504
|
+
var import_node_fs17 = require("node:fs");
|
|
43410
44505
|
init_esm2();
|
|
43411
44506
|
var PENDING_REATTACH_FILE = ["state", "pending-reattach.json"];
|
|
43412
44507
|
async function rotateSigner(options) {
|
|
@@ -43684,10 +44779,8 @@ Re-approving ${permissions.length} mandate(s) \u2014 the mandate signer (${permi
|
|
|
43684
44779
|
if (response.status !== "signature") {
|
|
43685
44780
|
throw new Error(`Expected an EIP-712 signature response, got: ${response.status}`);
|
|
43686
44781
|
}
|
|
43687
|
-
|
|
43688
|
-
|
|
43689
|
-
fee += await estimatePermissionFee(publicClient, project.contracts.governance, permission);
|
|
43690
|
-
}
|
|
44782
|
+
const flatFee = await readPermissionRegistrationFee(publicClient, project.contracts.governance);
|
|
44783
|
+
const fee = flatFee * BigInt(permissions.length);
|
|
43691
44784
|
const agentSigner = await loadManagerSigner();
|
|
43692
44785
|
const chain2 = getChainById(project.chainId);
|
|
43693
44786
|
const walletClient = createWalletClient({
|
|
@@ -43794,7 +44887,7 @@ ensure the agent that signs dispatches holds this key.`
|
|
|
43794
44887
|
const keystore = await keyring.exportKeystore(password);
|
|
43795
44888
|
writeJsonFile(target, keystore, 384);
|
|
43796
44889
|
const perManagerPath = managerKeystorePath(keyring.address);
|
|
43797
|
-
(0,
|
|
44890
|
+
(0, import_node_fs17.mkdirSync)(sailPath("keys", "managers"), { recursive: true });
|
|
43798
44891
|
writeJsonFile(perManagerPath, keystore, 384);
|
|
43799
44892
|
say(
|
|
43800
44893
|
() => console.log(
|
|
@@ -43806,7 +44899,7 @@ ensure the agent that signs dispatches holds this key.`
|
|
|
43806
44899
|
function promoteManagerKeystore(newManager, say) {
|
|
43807
44900
|
const stored = readJsonFile(managerKeystorePath(newManager));
|
|
43808
44901
|
if (!stored) return;
|
|
43809
|
-
(0,
|
|
44902
|
+
(0, import_node_fs17.mkdirSync)(sailPath("keys", "managers"), { recursive: true });
|
|
43810
44903
|
const activeTarget = keyPath("manager");
|
|
43811
44904
|
const displaced = readJsonFile(activeTarget);
|
|
43812
44905
|
if (displaced?.address) {
|
|
@@ -43858,7 +44951,7 @@ function writePending(pending) {
|
|
|
43858
44951
|
}
|
|
43859
44952
|
function clearPending() {
|
|
43860
44953
|
try {
|
|
43861
|
-
(0,
|
|
44954
|
+
(0, import_node_fs17.rmSync)(sailPath(...PENDING_REATTACH_FILE), { force: true });
|
|
43862
44955
|
} catch {
|
|
43863
44956
|
}
|
|
43864
44957
|
}
|
|
@@ -43957,12 +45050,12 @@ function ownerShow(options) {
|
|
|
43957
45050
|
}
|
|
43958
45051
|
|
|
43959
45052
|
// src/commands/run.ts
|
|
43960
|
-
var
|
|
43961
|
-
var
|
|
45053
|
+
var import_node_fs18 = __toESM(require("node:fs"), 1);
|
|
45054
|
+
var import_node_path14 = __toESM(require("node:path"), 1);
|
|
43962
45055
|
var import_node_url = require("node:url");
|
|
43963
45056
|
init_esm2();
|
|
43964
45057
|
var DEFAULT_INTERVAL_SEC = 60;
|
|
43965
|
-
var sleep2 = (ms) => new Promise((
|
|
45058
|
+
var sleep2 = (ms) => new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
43966
45059
|
var ERC20_READ_ABI = [
|
|
43967
45060
|
{
|
|
43968
45061
|
type: "function",
|
|
@@ -43992,7 +45085,7 @@ var ERC20_READ_ABI = [
|
|
|
43992
45085
|
function loadAgentData(filePath) {
|
|
43993
45086
|
if (!filePath) return {};
|
|
43994
45087
|
try {
|
|
43995
|
-
const parsed = JSON.parse(
|
|
45088
|
+
const parsed = JSON.parse(import_node_fs18.default.readFileSync(filePath, "utf-8"));
|
|
43996
45089
|
return parsed && typeof parsed === "object" ? parsed : {};
|
|
43997
45090
|
} catch {
|
|
43998
45091
|
return {};
|
|
@@ -44001,8 +45094,8 @@ function loadAgentData(filePath) {
|
|
|
44001
45094
|
async function loadAgent() {
|
|
44002
45095
|
const candidates = ["src/agent.ts", "src/agent.js", "dist/agent.js", "dist/src/agent.js"];
|
|
44003
45096
|
for (const rel of candidates) {
|
|
44004
|
-
const abs =
|
|
44005
|
-
if (!
|
|
45097
|
+
const abs = import_node_path14.default.join(process.cwd(), rel);
|
|
45098
|
+
if (!import_node_fs18.default.existsSync(abs)) continue;
|
|
44006
45099
|
let mod2;
|
|
44007
45100
|
if (abs.endsWith(".ts")) {
|
|
44008
45101
|
const { tsImport } = await import("tsx/esm/api");
|
|
@@ -44255,6 +45348,8 @@ Configure the chain in the SDK chain registry or set KERNEL_ADDRESS in .sail/.en
|
|
|
44255
45348
|
} else {
|
|
44256
45349
|
permission = await resolvePermissionForCall({
|
|
44257
45350
|
publicClient,
|
|
45351
|
+
kernel,
|
|
45352
|
+
// narrowed: runCommand validates kernel before runTick runs
|
|
44258
45353
|
account: accountAddr,
|
|
44259
45354
|
manager: agentManager.address,
|
|
44260
45355
|
call: firstCall,
|
|
@@ -44297,7 +45392,7 @@ Configure the chain in the SDK chain registry or set KERNEL_ADDRESS in .sail/.en
|
|
|
44297
45392
|
if (isConjunctive && result.txHash) {
|
|
44298
45393
|
try {
|
|
44299
45394
|
await publicClient.waitForTransactionReceipt({ hash: result.txHash, timeout: 3e4 });
|
|
44300
|
-
await new Promise((
|
|
45395
|
+
await new Promise((resolve4) => setTimeout(resolve4, 500));
|
|
44301
45396
|
} catch {
|
|
44302
45397
|
}
|
|
44303
45398
|
}
|
|
@@ -44430,7 +45525,7 @@ async function scan(options) {
|
|
|
44430
45525
|
args: [address]
|
|
44431
45526
|
})
|
|
44432
45527
|
]);
|
|
44433
|
-
const [permissionSigner, manager, , sessionActive] = config;
|
|
45528
|
+
const [permissionSigner, manager, , , sessionActive] = config;
|
|
44434
45529
|
smas.push({ address, registered: true, manager, permissionSigner, sessionActive, mandates });
|
|
44435
45530
|
} catch (err) {
|
|
44436
45531
|
smas.push({
|
|
@@ -44478,9 +45573,9 @@ async function scan(options) {
|
|
|
44478
45573
|
|
|
44479
45574
|
// src/commands/service.ts
|
|
44480
45575
|
var import_node_child_process2 = require("node:child_process");
|
|
44481
|
-
var
|
|
45576
|
+
var import_node_fs19 = __toESM(require("node:fs"), 1);
|
|
44482
45577
|
var import_node_os = __toESM(require("node:os"), 1);
|
|
44483
|
-
var
|
|
45578
|
+
var import_node_path15 = __toESM(require("node:path"), 1);
|
|
44484
45579
|
function sanitizeName(raw) {
|
|
44485
45580
|
const s = raw.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
44486
45581
|
return s || "agent";
|
|
@@ -44599,21 +45694,21 @@ function buildWindowsTaskXml(cfg) {
|
|
|
44599
45694
|
`;
|
|
44600
45695
|
}
|
|
44601
45696
|
function isTccProtected(projectDir, home = import_node_os.default.homedir()) {
|
|
44602
|
-
const rel =
|
|
44603
|
-
if (rel.startsWith("..") ||
|
|
44604
|
-
const top = rel.split(
|
|
45697
|
+
const rel = import_node_path15.default.relative(home, import_node_path15.default.resolve(projectDir));
|
|
45698
|
+
if (rel.startsWith("..") || import_node_path15.default.isAbsolute(rel)) return false;
|
|
45699
|
+
const top = rel.split(import_node_path15.default.sep)[0];
|
|
44605
45700
|
return ["Desktop", "Documents", "Downloads"].includes(top ?? "");
|
|
44606
45701
|
}
|
|
44607
45702
|
function resolveCliEntry() {
|
|
44608
45703
|
try {
|
|
44609
|
-
return
|
|
45704
|
+
return import_node_fs19.default.realpathSync(process.argv[1]);
|
|
44610
45705
|
} catch {
|
|
44611
|
-
return
|
|
45706
|
+
return import_node_path15.default.resolve(process.argv[1]);
|
|
44612
45707
|
}
|
|
44613
45708
|
}
|
|
44614
45709
|
function resolveProjectDir(explicit) {
|
|
44615
|
-
const dir =
|
|
44616
|
-
if (!
|
|
45710
|
+
const dir = import_node_path15.default.resolve(explicit ?? process.cwd());
|
|
45711
|
+
if (!import_node_fs19.default.existsSync(import_node_path15.default.join(dir, ".sail"))) {
|
|
44617
45712
|
throw new Error(
|
|
44618
45713
|
`No .sail/ found in ${dir}.
|
|
44619
45714
|
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.)`
|
|
@@ -44625,7 +45720,7 @@ function passphraseReadiness(projectDir) {
|
|
|
44625
45720
|
const account2 = (() => {
|
|
44626
45721
|
try {
|
|
44627
45722
|
return JSON.parse(
|
|
44628
|
-
|
|
45723
|
+
import_node_fs19.default.readFileSync(import_node_path15.default.join(projectDir, ".sail", "account.json"), "utf-8")
|
|
44629
45724
|
);
|
|
44630
45725
|
} catch {
|
|
44631
45726
|
return null;
|
|
@@ -44641,28 +45736,28 @@ function passphraseReadiness(projectDir) {
|
|
|
44641
45736
|
} finally {
|
|
44642
45737
|
process.chdir(prevCwd);
|
|
44643
45738
|
}
|
|
44644
|
-
const env = parseEnvFile(
|
|
45739
|
+
const env = parseEnvFile(import_node_path15.default.join(projectDir, ".sail", ".env.local"));
|
|
44645
45740
|
const passphraseInEnvFile = Boolean(env.SAIL_PASSPHRASE);
|
|
44646
45741
|
return { keystorePresent, passphraseInEnvFile, ready: keystorePresent && passphraseInEnvFile };
|
|
44647
45742
|
}
|
|
44648
45743
|
function buildConfig(opts) {
|
|
44649
45744
|
const projectDir = resolveProjectDir(opts.project);
|
|
44650
45745
|
return {
|
|
44651
|
-
projectName: sanitizeName(
|
|
45746
|
+
projectName: sanitizeName(import_node_path15.default.basename(projectDir)),
|
|
44652
45747
|
projectDir,
|
|
44653
45748
|
nodePath: process.execPath,
|
|
44654
45749
|
cliEntry: resolveCliEntry(),
|
|
44655
|
-
logPath:
|
|
45750
|
+
logPath: import_node_path15.default.join(projectDir, ".sail", "agent.log"),
|
|
44656
45751
|
interval: opts.interval != null ? Number(opts.interval) : void 0,
|
|
44657
45752
|
chain: opts.chain != null ? Number(opts.chain) : void 0,
|
|
44658
45753
|
restartSec: 30
|
|
44659
45754
|
};
|
|
44660
45755
|
}
|
|
44661
45756
|
function plistPath(projectName) {
|
|
44662
|
-
return
|
|
45757
|
+
return import_node_path15.default.join(import_node_os.default.homedir(), "Library", "LaunchAgents", `${launchdLabel(projectName)}.plist`);
|
|
44663
45758
|
}
|
|
44664
45759
|
function systemdPath(projectName) {
|
|
44665
|
-
return
|
|
45760
|
+
return import_node_path15.default.join(import_node_os.default.homedir(), ".config", "systemd", "user", systemdUnitName(projectName));
|
|
44666
45761
|
}
|
|
44667
45762
|
async function serviceInstall(opts = {}) {
|
|
44668
45763
|
const cfg = buildConfig(opts);
|
|
@@ -44686,12 +45781,12 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44686
45781
|
console.warn(`\u26A0 ${msg}
|
|
44687
45782
|
Proceeding because --force was given.`);
|
|
44688
45783
|
}
|
|
44689
|
-
|
|
45784
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(cfg.logPath), { recursive: true });
|
|
44690
45785
|
if (platform === "darwin") {
|
|
44691
45786
|
const plist = buildLaunchdPlist(cfg);
|
|
44692
45787
|
const dest = plistPath(cfg.projectName);
|
|
44693
|
-
|
|
44694
|
-
|
|
45788
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(dest), { recursive: true });
|
|
45789
|
+
import_node_fs19.default.writeFileSync(dest, plist);
|
|
44695
45790
|
const uid2 = process.getuid?.() ?? 0;
|
|
44696
45791
|
try {
|
|
44697
45792
|
try {
|
|
@@ -44710,8 +45805,8 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44710
45805
|
if (platform === "linux") {
|
|
44711
45806
|
const unit = buildSystemdUnit(cfg);
|
|
44712
45807
|
const dest = systemdPath(cfg.projectName);
|
|
44713
|
-
|
|
44714
|
-
|
|
45808
|
+
import_node_fs19.default.mkdirSync(import_node_path15.default.dirname(dest), { recursive: true });
|
|
45809
|
+
import_node_fs19.default.writeFileSync(dest, unit);
|
|
44715
45810
|
try {
|
|
44716
45811
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "daemon-reload"], { stdio: "inherit" });
|
|
44717
45812
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "enable", "--now", systemdUnitName(cfg.projectName)], {
|
|
@@ -44725,8 +45820,8 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44725
45820
|
}
|
|
44726
45821
|
if (platform === "win32") {
|
|
44727
45822
|
const xml = buildWindowsTaskXml(cfg);
|
|
44728
|
-
const dest =
|
|
44729
|
-
|
|
45823
|
+
const dest = import_node_path15.default.join(import_node_os.default.tmpdir(), `${windowsTaskName(cfg.projectName)}.xml`);
|
|
45824
|
+
import_node_fs19.default.writeFileSync(dest, xml, "utf-8");
|
|
44730
45825
|
try {
|
|
44731
45826
|
(0, import_node_child_process2.execFileSync)(
|
|
44732
45827
|
"schtasks",
|
|
@@ -44737,7 +45832,7 @@ Run "sailor keys generate" (and save the passphrase) or set it in .sail/.env.loc
|
|
|
44737
45832
|
throw new Error(`schtasks /Create failed: ${err.message}`);
|
|
44738
45833
|
} finally {
|
|
44739
45834
|
try {
|
|
44740
|
-
|
|
45835
|
+
import_node_fs19.default.rmSync(dest, { force: true });
|
|
44741
45836
|
} catch {
|
|
44742
45837
|
}
|
|
44743
45838
|
}
|
|
@@ -44763,14 +45858,14 @@ function okInstall(cfg, unit) {
|
|
|
44763
45858
|
);
|
|
44764
45859
|
}
|
|
44765
45860
|
async function serviceStatus(opts = {}) {
|
|
44766
|
-
const projectName = sanitizeName(
|
|
45861
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44767
45862
|
const platform = process.platform;
|
|
44768
45863
|
let installed = false;
|
|
44769
45864
|
let running = false;
|
|
44770
45865
|
let detail = "";
|
|
44771
45866
|
try {
|
|
44772
45867
|
if (platform === "darwin") {
|
|
44773
|
-
installed =
|
|
45868
|
+
installed = import_node_fs19.default.existsSync(plistPath(projectName));
|
|
44774
45869
|
const uid2 = process.getuid?.() ?? 0;
|
|
44775
45870
|
try {
|
|
44776
45871
|
detail = (0, import_node_child_process2.execFileSync)("launchctl", ["print", `gui/${uid2}/${launchdLabel(projectName)}`], {
|
|
@@ -44782,7 +45877,7 @@ async function serviceStatus(opts = {}) {
|
|
|
44782
45877
|
} catch {
|
|
44783
45878
|
}
|
|
44784
45879
|
} else if (platform === "linux") {
|
|
44785
|
-
installed =
|
|
45880
|
+
installed = import_node_fs19.default.existsSync(systemdPath(projectName));
|
|
44786
45881
|
try {
|
|
44787
45882
|
detail = (0, import_node_child_process2.execFileSync)("systemctl", ["--user", "is-active", systemdUnitName(projectName)], {
|
|
44788
45883
|
encoding: "utf-8",
|
|
@@ -44818,7 +45913,7 @@ async function serviceStatus(opts = {}) {
|
|
|
44818
45913
|
);
|
|
44819
45914
|
}
|
|
44820
45915
|
async function serviceStop(opts = {}) {
|
|
44821
|
-
const projectName = sanitizeName(
|
|
45916
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44822
45917
|
const platform = process.platform;
|
|
44823
45918
|
if (platform === "darwin") {
|
|
44824
45919
|
const uid2 = process.getuid?.() ?? 0;
|
|
@@ -44837,7 +45932,7 @@ async function serviceStop(opts = {}) {
|
|
|
44837
45932
|
});
|
|
44838
45933
|
}
|
|
44839
45934
|
async function serviceUninstall(opts = {}) {
|
|
44840
|
-
const projectName = sanitizeName(
|
|
45935
|
+
const projectName = sanitizeName(import_node_path15.default.basename(resolveProjectDir(opts.project)));
|
|
44841
45936
|
const platform = process.platform;
|
|
44842
45937
|
if (platform === "darwin") {
|
|
44843
45938
|
const uid2 = process.getuid?.() ?? 0;
|
|
@@ -44847,7 +45942,7 @@ async function serviceUninstall(opts = {}) {
|
|
|
44847
45942
|
});
|
|
44848
45943
|
} catch {
|
|
44849
45944
|
}
|
|
44850
|
-
|
|
45945
|
+
import_node_fs19.default.rmSync(plistPath(projectName), { force: true });
|
|
44851
45946
|
} else if (platform === "linux") {
|
|
44852
45947
|
try {
|
|
44853
45948
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "disable", "--now", systemdUnitName(projectName)], {
|
|
@@ -44855,7 +45950,7 @@ async function serviceUninstall(opts = {}) {
|
|
|
44855
45950
|
});
|
|
44856
45951
|
} catch {
|
|
44857
45952
|
}
|
|
44858
|
-
|
|
45953
|
+
import_node_fs19.default.rmSync(systemdPath(projectName), { force: true });
|
|
44859
45954
|
try {
|
|
44860
45955
|
(0, import_node_child_process2.execFileSync)("systemctl", ["--user", "daemon-reload"], { stdio: "ignore" });
|
|
44861
45956
|
} catch {
|
|
@@ -44873,21 +45968,21 @@ async function serviceUninstall(opts = {}) {
|
|
|
44873
45968
|
}
|
|
44874
45969
|
async function serviceLogs(opts = {}) {
|
|
44875
45970
|
const projectDir = resolveProjectDir(opts.project);
|
|
44876
|
-
const logPath =
|
|
44877
|
-
if (!
|
|
45971
|
+
const logPath = import_node_path15.default.join(projectDir, ".sail", "agent.log");
|
|
45972
|
+
if (!import_node_fs19.default.existsSync(logPath)) {
|
|
44878
45973
|
console.log(`No log yet at ${logPath}. The service writes here once it runs.`);
|
|
44879
45974
|
return;
|
|
44880
45975
|
}
|
|
44881
45976
|
if (opts.follow) {
|
|
44882
45977
|
if (process.platform === "win32") {
|
|
44883
|
-
console.log(
|
|
45978
|
+
console.log(import_node_fs19.default.readFileSync(logPath, "utf-8"));
|
|
44884
45979
|
console.log("(follow mode is not supported on Windows here \u2014 re-run to refresh)");
|
|
44885
45980
|
return;
|
|
44886
45981
|
}
|
|
44887
45982
|
(0, import_node_child_process2.execFileSync)("tail", ["-f", logPath], { stdio: "inherit" });
|
|
44888
45983
|
return;
|
|
44889
45984
|
}
|
|
44890
|
-
const lines =
|
|
45985
|
+
const lines = import_node_fs19.default.readFileSync(logPath, "utf-8").split("\n");
|
|
44891
45986
|
console.log(lines.slice(-200).join("\n"));
|
|
44892
45987
|
}
|
|
44893
45988
|
|
|
@@ -45043,14 +46138,14 @@ async function sessionResume(opts = {}) {
|
|
|
45043
46138
|
}
|
|
45044
46139
|
|
|
45045
46140
|
// src/commands/station.ts
|
|
45046
|
-
var
|
|
45047
|
-
var
|
|
45048
|
-
var RUNTIME_SERVER_FILE2 = (0,
|
|
46141
|
+
var import_node_fs20 = require("node:fs");
|
|
46142
|
+
var import_node_path16 = require("node:path");
|
|
46143
|
+
var RUNTIME_SERVER_FILE2 = (0, import_node_path16.join)(".sail", "runtime", "server.json");
|
|
45049
46144
|
function readState(projectRoot) {
|
|
45050
|
-
const file = (0,
|
|
45051
|
-
if (!(0,
|
|
46145
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
46146
|
+
if (!(0, import_node_fs20.existsSync)(file)) return null;
|
|
45052
46147
|
try {
|
|
45053
|
-
return JSON.parse((0,
|
|
46148
|
+
return JSON.parse((0, import_node_fs20.readFileSync)(file, "utf8"));
|
|
45054
46149
|
} catch {
|
|
45055
46150
|
return null;
|
|
45056
46151
|
}
|
|
@@ -45122,9 +46217,9 @@ async function stationStop(options) {
|
|
|
45122
46217
|
}
|
|
45123
46218
|
const daemon = await discoverDaemon(projectRoot);
|
|
45124
46219
|
if (!daemon) {
|
|
45125
|
-
const file = (0,
|
|
46220
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
45126
46221
|
try {
|
|
45127
|
-
if ((0,
|
|
46222
|
+
if ((0, import_node_fs20.existsSync)(file)) (0, import_node_fs20.rmSync)(file);
|
|
45128
46223
|
} catch {
|
|
45129
46224
|
}
|
|
45130
46225
|
emit(options.json, () => console.log("Station process not found; cleared stale state."), {
|
|
@@ -45140,9 +46235,9 @@ async function stationStop(options) {
|
|
|
45140
46235
|
pid: state.pid
|
|
45141
46236
|
});
|
|
45142
46237
|
} catch {
|
|
45143
|
-
const file = (0,
|
|
46238
|
+
const file = (0, import_node_path16.join)(projectRoot, RUNTIME_SERVER_FILE2);
|
|
45144
46239
|
try {
|
|
45145
|
-
if ((0,
|
|
46240
|
+
if ((0, import_node_fs20.existsSync)(file)) (0, import_node_fs20.rmSync)(file);
|
|
45146
46241
|
} catch {
|
|
45147
46242
|
}
|
|
45148
46243
|
emit(options.json, () => console.log("Station process not found; cleared stale state."), {
|
|
@@ -45204,9 +46299,9 @@ async function status() {
|
|
|
45204
46299
|
|
|
45205
46300
|
// src/commands/ui.ts
|
|
45206
46301
|
var import_node_child_process5 = require("node:child_process");
|
|
45207
|
-
var
|
|
46302
|
+
var import_node_fs21 = __toESM(require("node:fs"), 1);
|
|
45208
46303
|
var import_node_net2 = __toESM(require("node:net"), 1);
|
|
45209
|
-
var
|
|
46304
|
+
var import_node_path17 = __toESM(require("node:path"), 1);
|
|
45210
46305
|
|
|
45211
46306
|
// src/lib/tailscale.ts
|
|
45212
46307
|
var import_node_child_process4 = require("node:child_process");
|
|
@@ -45252,12 +46347,12 @@ function tailscaleServeDown() {
|
|
|
45252
46347
|
}
|
|
45253
46348
|
|
|
45254
46349
|
// src/commands/ui.ts
|
|
45255
|
-
var UI_STATE_FILE =
|
|
46350
|
+
var UI_STATE_FILE = import_node_path17.default.join(".sail", "runtime", "ui.json");
|
|
45256
46351
|
function readState2(projectRoot) {
|
|
45257
|
-
const file =
|
|
45258
|
-
if (!
|
|
46352
|
+
const file = import_node_path17.default.join(projectRoot, UI_STATE_FILE);
|
|
46353
|
+
if (!import_node_fs21.default.existsSync(file)) return null;
|
|
45259
46354
|
try {
|
|
45260
|
-
return JSON.parse(
|
|
46355
|
+
return JSON.parse(import_node_fs21.default.readFileSync(file, "utf-8"));
|
|
45261
46356
|
} catch {
|
|
45262
46357
|
return null;
|
|
45263
46358
|
}
|
|
@@ -45265,7 +46360,7 @@ function readState2(projectRoot) {
|
|
|
45265
46360
|
function installedCliVersion() {
|
|
45266
46361
|
try {
|
|
45267
46362
|
const pkg = JSON.parse(
|
|
45268
|
-
|
|
46363
|
+
import_node_fs21.default.readFileSync(import_node_path17.default.join(packageRoot(), "package.json"), "utf-8")
|
|
45269
46364
|
);
|
|
45270
46365
|
return pkg.version ?? null;
|
|
45271
46366
|
} catch {
|
|
@@ -45292,16 +46387,16 @@ async function warnIfVersionSkew(port) {
|
|
|
45292
46387
|
}
|
|
45293
46388
|
function waitForPort(port, timeoutMs) {
|
|
45294
46389
|
const deadline = Date.now() + timeoutMs;
|
|
45295
|
-
return new Promise((
|
|
46390
|
+
return new Promise((resolve4) => {
|
|
45296
46391
|
const attempt = () => {
|
|
45297
46392
|
const socket = import_node_net2.default.connect(port, "127.0.0.1");
|
|
45298
46393
|
socket.once("connect", () => {
|
|
45299
46394
|
socket.destroy();
|
|
45300
|
-
|
|
46395
|
+
resolve4(true);
|
|
45301
46396
|
});
|
|
45302
46397
|
socket.once("error", () => {
|
|
45303
46398
|
socket.destroy();
|
|
45304
|
-
if (Date.now() > deadline)
|
|
46399
|
+
if (Date.now() > deadline) resolve4(false);
|
|
45305
46400
|
else setTimeout(attempt, 150);
|
|
45306
46401
|
});
|
|
45307
46402
|
};
|
|
@@ -45310,16 +46405,16 @@ function waitForPort(port, timeoutMs) {
|
|
|
45310
46405
|
}
|
|
45311
46406
|
async function uiCommand(opts = {}) {
|
|
45312
46407
|
const distDir = cliDistDir();
|
|
45313
|
-
const uiDistDir =
|
|
45314
|
-
const serverBundle =
|
|
46408
|
+
const uiDistDir = import_node_path17.default.join(packageRoot(), "packages", "ui", "dist");
|
|
46409
|
+
const serverBundle = import_node_path17.default.resolve(distDir, "server.cjs");
|
|
45315
46410
|
const projectRoot = process.cwd();
|
|
45316
|
-
const sailDir2 =
|
|
46411
|
+
const sailDir2 = import_node_path17.default.join(projectRoot, ".sail");
|
|
45317
46412
|
const envPort = Number(process.env.PORT);
|
|
45318
46413
|
const port = await findFreePort(Number.isInteger(envPort) && envPort > 0 && envPort <= 65535 ? envPort : projectPort(projectRoot));
|
|
45319
|
-
if (!
|
|
46414
|
+
if (!import_node_fs21.default.existsSync(serverBundle)) {
|
|
45320
46415
|
throw new Error(`Server bundle not found at ${serverBundle}. Re-run the sailor build.`);
|
|
45321
46416
|
}
|
|
45322
|
-
if (!
|
|
46417
|
+
if (!import_node_fs21.default.existsSync(import_node_path17.default.join(uiDistDir, "index.html"))) {
|
|
45323
46418
|
throw new Error(`UI dist not found at ${uiDistDir}. Re-run the sailor build.`);
|
|
45324
46419
|
}
|
|
45325
46420
|
let tailnetUrl = null;
|
|
@@ -45349,10 +46444,10 @@ async function uiCommand(opts = {}) {
|
|
|
45349
46444
|
await warnIfVersionSkew(existing.port);
|
|
45350
46445
|
return;
|
|
45351
46446
|
}
|
|
45352
|
-
const runtimeDir =
|
|
45353
|
-
|
|
45354
|
-
const logFile =
|
|
45355
|
-
const logFd =
|
|
46447
|
+
const runtimeDir = import_node_path17.default.join(projectRoot, ".sail", "runtime");
|
|
46448
|
+
import_node_fs21.default.mkdirSync(runtimeDir, { recursive: true });
|
|
46449
|
+
const logFile = import_node_path17.default.join(runtimeDir, "ui.log");
|
|
46450
|
+
const logFd = import_node_fs21.default.openSync(logFile, "a");
|
|
45356
46451
|
const corsOrigins = [process.env.SAILOR_CORS_ORIGINS, tailnetUrl].filter(Boolean).join(",");
|
|
45357
46452
|
const child = (0, import_node_child_process5.spawn)(process.execPath, [serverBundle], {
|
|
45358
46453
|
detached: true,
|
|
@@ -45367,7 +46462,7 @@ async function uiCommand(opts = {}) {
|
|
|
45367
46462
|
}
|
|
45368
46463
|
});
|
|
45369
46464
|
child.unref();
|
|
45370
|
-
|
|
46465
|
+
import_node_fs21.default.closeSync(logFd);
|
|
45371
46466
|
const READY_TIMEOUT_MS = 1e4;
|
|
45372
46467
|
const deadline = Date.now() + READY_TIMEOUT_MS;
|
|
45373
46468
|
let ready = false;
|
|
@@ -45381,14 +46476,14 @@ async function uiCommand(opts = {}) {
|
|
|
45381
46476
|
if (!ready) {
|
|
45382
46477
|
let tail = "";
|
|
45383
46478
|
try {
|
|
45384
|
-
tail =
|
|
46479
|
+
tail = import_node_fs21.default.readFileSync(logFile, "utf-8").split("\n").filter(Boolean).slice(-15).join("\n");
|
|
45385
46480
|
} catch {
|
|
45386
46481
|
}
|
|
45387
46482
|
throw new Error(
|
|
45388
46483
|
`Sailor UI failed to start within ${READY_TIMEOUT_MS / 1e3}s on port ${port}.` + (tail ? `
|
|
45389
46484
|
|
|
45390
46485
|
Server output:
|
|
45391
|
-
${tail}` : ` See ${
|
|
46486
|
+
${tail}` : ` See ${import_node_path17.default.relative(projectRoot, logFile)}.`)
|
|
45392
46487
|
);
|
|
45393
46488
|
}
|
|
45394
46489
|
let exposed = false;
|
|
@@ -45403,8 +46498,8 @@ ${tail}` : ` See ${import_node_path16.default.relative(projectRoot, logFile)}.`)
|
|
|
45403
46498
|
);
|
|
45404
46499
|
}
|
|
45405
46500
|
}
|
|
45406
|
-
|
|
45407
|
-
|
|
46501
|
+
import_node_fs21.default.writeFileSync(
|
|
46502
|
+
import_node_path17.default.join(projectRoot, UI_STATE_FILE),
|
|
45408
46503
|
JSON.stringify({ pid: child.pid, port, startedAt: (/* @__PURE__ */ new Date()).toISOString(), exposed }, null, 2)
|
|
45409
46504
|
);
|
|
45410
46505
|
console.log(`Sailor UI started at http://localhost:${port} (pid ${child.pid})`);
|
|
@@ -45417,7 +46512,7 @@ async function uiStatus() {
|
|
|
45417
46512
|
console.log(`\u25CF running http://localhost:${state.port} (pid ${state.pid})`);
|
|
45418
46513
|
await warnIfVersionSkew(state.port);
|
|
45419
46514
|
} else {
|
|
45420
|
-
if (state)
|
|
46515
|
+
if (state) import_node_fs21.default.rmSync(import_node_path17.default.join(process.cwd(), UI_STATE_FILE), { force: true });
|
|
45421
46516
|
console.log("\u25CB Sailor UI is not running");
|
|
45422
46517
|
}
|
|
45423
46518
|
}
|
|
@@ -45429,7 +46524,7 @@ function uiStop() {
|
|
|
45429
46524
|
return;
|
|
45430
46525
|
}
|
|
45431
46526
|
if (!isProcessAlive(state.pid)) {
|
|
45432
|
-
|
|
46527
|
+
import_node_fs21.default.rmSync(import_node_path17.default.join(projectRoot, UI_STATE_FILE), { force: true });
|
|
45433
46528
|
console.log("Sailor UI is not running (stale state file removed).");
|
|
45434
46529
|
return;
|
|
45435
46530
|
}
|
|
@@ -45438,21 +46533,21 @@ function uiStop() {
|
|
|
45438
46533
|
tailscaleServeDown();
|
|
45439
46534
|
console.log("Tailnet exposure removed.");
|
|
45440
46535
|
}
|
|
45441
|
-
|
|
46536
|
+
import_node_fs21.default.rmSync(import_node_path17.default.join(projectRoot, UI_STATE_FILE), { force: true });
|
|
45442
46537
|
console.log(`Stopped Sailor UI (pid ${state.pid}).`);
|
|
45443
46538
|
}
|
|
45444
46539
|
|
|
45445
46540
|
// src/index.ts
|
|
45446
|
-
function
|
|
46541
|
+
function cliVersion2() {
|
|
45447
46542
|
try {
|
|
45448
|
-
const pkg = JSON.parse((0,
|
|
46543
|
+
const pkg = JSON.parse((0, import_node_fs22.readFileSync)((0, import_node_path18.join)(packageRoot(), "package.json"), "utf-8"));
|
|
45449
46544
|
return pkg.version ?? "0.0.0";
|
|
45450
46545
|
} catch {
|
|
45451
46546
|
return "0.0.0";
|
|
45452
46547
|
}
|
|
45453
46548
|
}
|
|
45454
46549
|
var program2 = new Command();
|
|
45455
|
-
program2.name("sailor").description("Operator toolkit for Sail Protocol").version(
|
|
46550
|
+
program2.name("sailor").description("Operator toolkit for Sail Protocol").version(cliVersion2());
|
|
45456
46551
|
function action(fn) {
|
|
45457
46552
|
return async () => {
|
|
45458
46553
|
try {
|
|
@@ -45477,7 +46572,7 @@ function actionWith(fn) {
|
|
|
45477
46572
|
closePrompts();
|
|
45478
46573
|
};
|
|
45479
46574
|
}
|
|
45480
|
-
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)").
|
|
46575
|
+
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(
|
|
45481
46576
|
async (name, opts) => {
|
|
45482
46577
|
try {
|
|
45483
46578
|
await initCommand(name, opts);
|
|
@@ -45516,6 +46611,9 @@ mandate.command("attach").description("Register one or more already-deployed per
|
|
|
45516
46611
|
"--address <mandateOrName>",
|
|
45517
46612
|
"Permission address or locally-tracked name; or a comma-separated list of addresses to register together in one signature"
|
|
45518
46613
|
).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));
|
|
46614
|
+
mandate.command("configure").description(
|
|
46615
|
+
"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."
|
|
46616
|
+
).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));
|
|
45519
46617
|
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));
|
|
45520
46618
|
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));
|
|
45521
46619
|
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));
|