@dev.sail.money/sailor 1.3.0-98 → 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 +7 -7
- package/LICENSE +1 -1
- package/README.md +64 -472
- package/package.json +11 -6
- package/packages/cli/README.md +1 -1
- package/packages/cli/dist/index.cjs +1469 -463
- package/packages/cli/dist/server.cjs +19796 -21737
- package/packages/sdk/README.md +1 -1
- package/packages/sdk/dist/abis/ConfigurablePermission.d.ts +130 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.d.ts.map +1 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.js +79 -0
- package/packages/sdk/dist/abis/ConfigurablePermission.js.map +1 -0
- package/packages/sdk/dist/abis/SailKernel.d.ts +42 -0
- package/packages/sdk/dist/abis/SailKernel.d.ts.map +1 -1
- package/packages/sdk/dist/abis/SailKernel.js +34 -0
- package/packages/sdk/dist/abis/SailKernel.js.map +1 -1
- package/packages/sdk/dist/abis/index.d.ts +1 -0
- package/packages/sdk/dist/abis/index.d.ts.map +1 -1
- package/packages/sdk/dist/abis/index.js +1 -0
- package/packages/sdk/dist/abis/index.js.map +1 -1
- package/packages/sdk/dist/chains.d.ts +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 +2 -1
- package/packages/sdk/dist/fees.d.ts.map +1 -1
- package/packages/sdk/dist/fees.js +2 -1
- package/packages/sdk/dist/fees.js.map +1 -1
- package/packages/sdk/dist/index.d.ts +3 -2
- package/packages/sdk/dist/index.d.ts.map +1 -1
- package/packages/sdk/dist/index.js +3 -2
- package/packages/sdk/dist/index.js.map +1 -1
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/packages/sdk/dist/safe.d.ts +49 -0
- package/packages/sdk/dist/safe.d.ts.map +1 -1
- package/packages/sdk/dist/safe.js +74 -0
- package/packages/sdk/dist/safe.js.map +1 -1
- package/packages/sdk/package.json +6 -2
- package/packages/ui/dist/assets/{add-BX5reKtK.js → add-CBbu2pe_.js} +2 -2
- package/packages/ui/dist/assets/{all-wallets-IZ3PlVF-.js → all-wallets-C1oy4NUu.js} +2 -2
- package/packages/ui/dist/assets/{app-store-ARgRdMdF.js → app-store-DKqyf0Zv.js} +1 -1
- package/packages/ui/dist/assets/{apple-VCaqsI9w.js → apple-DyoIbCFy.js} +2 -2
- package/packages/ui/dist/assets/{arrow-bottom-circle-h5vFiZ2I.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-6c28yOM9.js → bank-B41nlslf.js} +2 -2
- package/packages/ui/dist/assets/{basic-CJnbTfSd.js → basic-CWqOb7CV.js} +177 -177
- package/packages/ui/dist/assets/{browser-CDKlxM3D.js → browser-DDKdqoZ9.js} +2 -2
- package/packages/ui/dist/assets/{card-DQdED02q.js → card-BgOmTajq.js} +2 -2
- package/packages/ui/dist/assets/ccip-CtJUKWRd.js +1 -0
- package/packages/ui/dist/assets/{checkmark-JoRNVoFV.js → checkmark-CGqQipH4.js} +2 -2
- package/packages/ui/dist/assets/{checkmark-bold-B6bGHVIs.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-D-fiJ9qJ.js → chrome-store-BsyI-4PI.js} +2 -2
- package/packages/ui/dist/assets/{clock-xCPkzwjj.js → clock-Dct9oQ3M.js} +2 -2
- package/packages/ui/dist/assets/{close-BkqmPpWG.js → close-BvSCnI2y.js} +2 -2
- package/packages/ui/dist/assets/{coinPlaceholder-PIvN9oq_.js → coinPlaceholder-p7RiWkon.js} +2 -2
- package/packages/ui/dist/assets/{compass-CW5kWcxW.js → compass-BUeeZqX4.js} +2 -2
- package/packages/ui/dist/assets/{copy-DUZlAQJJ.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-BUAMB0G1.js → cursor-transparent-BZp3-JmA.js} +2 -2
- package/packages/ui/dist/assets/{desktop-BxdlwV8P.js → desktop-BIui_Lzb.js} +2 -2
- package/packages/ui/dist/assets/{disconnect-GelNh3mn.js → disconnect-B3Bxdchp.js} +2 -2
- package/packages/ui/dist/assets/{discord-N0jnxkzC.js → discord-VWI0yDyx.js} +2 -2
- package/packages/ui/dist/assets/{etherscan-B41u7wF4.js → etherscan-BpBvUT9i.js} +2 -2
- package/packages/ui/dist/assets/events-DQ172AOg.js +1 -0
- package/packages/ui/dist/assets/{exclamation-triangle-BWJC56FC.js → exclamation-triangle-o1TJHIUw.js} +2 -2
- package/packages/ui/dist/assets/{extension-G6I6oogw.js → extension-4RaLvbh5.js} +2 -2
- package/packages/ui/dist/assets/external-link-BHIwjDgj.js +8 -0
- package/packages/ui/dist/assets/{facebook-47twy32b.js → facebook-Bes5g-wN.js} +2 -2
- package/packages/ui/dist/assets/{farcaster-DYqnqCqs.js → farcaster-CiJ-352m.js} +2 -2
- package/packages/ui/dist/assets/{filters-dF6xeJnE.js → filters-DMOteumb.js} +2 -2
- package/packages/ui/dist/assets/{github-DbW4Ihz2.js → github-D2nDec9X.js} +2 -2
- package/packages/ui/dist/assets/{google-TKm7G8LF.js → google-lZZlQZPQ.js} +2 -2
- package/packages/ui/dist/assets/{help-circle-CY3qTmsG.js → help-circle-D4cSSziR.js} +1 -1
- package/packages/ui/dist/assets/{id-JpHW4q14.js → id-BmhXZq5P.js} +2 -2
- package/packages/ui/dist/assets/{image-Dip2fG98.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-q0mGElxZ.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-B1enFsqh.js → info-77RSvIMg.js} +2 -2
- package/packages/ui/dist/assets/{info-circle-D4j3FISs.js → info-circle-CWsII-NN.js} +2 -2
- package/packages/ui/dist/assets/{lightbulb-DZbKr-vS.js → lightbulb-BZXzm7XE.js} +2 -2
- package/packages/ui/dist/assets/{mail-D-TO_uVQ.js → mail-DMG1YqB0.js} +2 -2
- package/packages/ui/dist/assets/metamask-sdk-K1x_iqcc.js +542 -0
- package/packages/ui/dist/assets/{mobile-Bkmwzav2.js → mobile-DuJfOBSk.js} +2 -2
- package/packages/ui/dist/assets/{more-D1_I_jiB.js → more-Cs9ySK2F.js} +2 -2
- package/packages/ui/dist/assets/{network-placeholder-DUaFjoXh.js → network-placeholder-CMDPmB1E.js} +2 -2
- package/packages/ui/dist/assets/{nftPlaceholder-Cc0iUryh.js → nftPlaceholder-Cj0f9y2u.js} +2 -2
- package/packages/ui/dist/assets/{off-BvX71sse.js → off-9zSSsm-e.js} +2 -2
- package/packages/ui/dist/assets/{play-store-XzLbtbTd.js → play-store-CPwIb8Gj.js} +2 -2
- package/packages/ui/dist/assets/{plus-B77_RmYR.js → plus-BOHQri8o.js} +2 -2
- package/packages/ui/dist/assets/{qr-code-BNeIhB1d.js → qr-code-DqhbK276.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-B9sX-yty.js → recycle-horizontal-BpGM56Qz.js} +2 -2
- package/packages/ui/dist/assets/{refresh-BWRygnjm.js → refresh-BPzZlhTP.js} +2 -2
- package/packages/ui/dist/assets/{reown-logo-DCAEsGFm.js → reown-logo-OCkI0xzo.js} +2 -2
- package/packages/ui/dist/assets/{search-ZXIqrawS.js → search-B1JEJvwq.js} +2 -2
- package/packages/ui/dist/assets/{secp256k1-Doz05h4g.js → secp256k1-BqUeV9Cb.js} +1 -1
- package/packages/ui/dist/assets/{send-BQcO0jNC.js → send-JNsDlNoq.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontal-4yZEzz2K.js → swapHorizontal-C3Z1FImK.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalBold-DxBKu3sl.js → swapHorizontalBold-Cmdy2iAn.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalMedium-DAQYJ2JK.js → swapHorizontalMedium-DFX57Nn9.js} +2 -2
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-CUlZzFJ6.js → swapHorizontalRoundedBold-baB389c8.js} +2 -2
- package/packages/ui/dist/assets/{swapVertical-CjWHAaDM.js → swapVertical-DmAYGfK1.js} +2 -2
- package/packages/ui/dist/assets/{telegram-JBeabiJP.js → telegram-BHbYE-nI.js} +2 -2
- package/packages/ui/dist/assets/{three-dots-D3R8OjSx.js → three-dots-BwRWl6qJ.js} +2 -2
- package/packages/ui/dist/assets/{twitch-1f9z7xVO.js → twitch-Drx0q6B6.js} +2 -2
- package/packages/ui/dist/assets/{twitterIcon-BW7n2xnp.js → twitterIcon-AuJ2KQ6p.js} +2 -2
- package/packages/ui/dist/assets/{verify-Cs5owI38.js → verify-Dkrd3q7o.js} +2 -2
- package/packages/ui/dist/assets/{verify-filled-Ci5sx5qS.js → verify-filled-B9e3-nz-.js} +2 -2
- package/packages/ui/dist/assets/{w3m-modal-DnWtss8u.js → w3m-modal-DtkEjQA7.js} +1 -1
- package/packages/ui/dist/assets/{wallet-MaGNqaW-.js → wallet-CqYzSiBd.js} +2 -2
- package/packages/ui/dist/assets/{wallet-placeholder-kTOy12_L.js → wallet-placeholder-B05kTN_K.js} +2 -2
- package/packages/ui/dist/assets/{walletconnect-CyuP92jg.js → walletconnect-BwoPXLaS.js} +3 -3
- package/packages/ui/dist/assets/{warning-circle-BImUCdpG.js → warning-circle-DK9Ai8rT.js} +2 -2
- package/packages/ui/dist/assets/{x-II45JHpV.js → x-BNdh5DVW.js} +2 -2
- package/packages/ui/dist/index.html +2 -2
- package/templates/default/.agents/skills/sail-mandates/SKILL.md +1 -1
- package/templates/default/.agents/skills/sail-mandates/references/approvals.md +3 -3
- package/templates/default/.agents/skills/sail-mandates/references/examples-index.md +3 -3
- package/templates/default/.agents/skills/sail-onboarding/SKILL.md +34 -33
- package/templates/default/.agents/skills/sail-servers/SKILL.md +1 -0
- package/templates/default/.agents/skills/sail-swap-quote/SKILL.md +76 -0
- package/templates/default/.agents/skills/sail-template-approve-batch/SKILL.md +98 -0
- package/templates/default/.agents/skills/sail-template-borrow/SKILL.md +68 -0
- package/templates/default/.agents/skills/sail-template-deposit/SKILL.md +61 -0
- package/templates/default/.agents/skills/sail-template-swap/SKILL.md +207 -0
- package/templates/default/.agents/skills/sail-template-swap-no-oracle/SKILL.md +100 -0
- package/templates/default/.agents/skills/sail-template-transfer/SKILL.md +52 -0
- package/templates/default/.agents/skills/sail-template-withdraw/SKILL.md +50 -0
- package/templates/default/.agents/skills/sail-templates/SKILL.md +142 -0
- package/templates/default/.agents/skills/sail-templates/catalog.mjs +200 -0
- package/templates/default/.agents/skills/sail-templates/deployed.json +133 -0
- package/templates/default/.agents/skills/sail-templates/oracles/IOracle.sol +13 -0
- package/templates/default/.agents/skills/sail-templates/oracles/UniV3TwapOracle.sol +114 -0
- package/templates/default/.agents/skills/sail-templates/oracles/libs/FullMath.sol +62 -0
- package/templates/default/.agents/skills/sail-templates/oracles/libs/TickMath.sol +44 -0
- package/templates/default/.agents/skills/sail-templates/references/config-schemas.md +139 -0
- package/templates/default/.agents/skills/sail-templates/references/reuse-flow.md +139 -0
- package/templates/default/.agents/skills/sail-token-resolve/SKILL.md +174 -0
- package/templates/default/.env.example +9 -0
- package/templates/default/AGENTS.md +107 -13
- package/templates/default/docs/PERMISSION_MODEL.md +2 -2
- package/{examples → templates/default/examples}/custom-mandate/.sail/contracts/interfaces/IPermission.sol +4 -0
- package/{examples → templates/default/examples}/custom-mandate/README.md +4 -1
- package/{examples → templates/default/examples}/permissions/interfaces/IBatchPermission.sol +2 -0
- package/{examples → templates/default/examples}/permissions/interfaces/IPermission.sol +4 -0
- package/templates/default/scripts/quote-swap.mjs +211 -0
- package/templates/default/scripts/resolve-token.mjs +992 -0
- package/templates/default/scripts/shared-template-addr.mjs +110 -0
- package/templates/default/test/BoundedCallPermission.t.sol +2 -1
- package/docs/PERMISSION_MODEL.md +0 -93
- package/examples/README.md +0 -24
- package/examples/lifi-permissions/LifiBoundedApprovePermissionCloneable.sol +0 -84
- package/examples/lifi-permissions/LifiDiamondSwapPermissionCloneable.sol +0 -97
- package/examples/lifi-permissions/README.md +0 -53
- package/packages/ui/dist/assets/arrow-bottom-Cwptw8fW.js +0 -8
- package/packages/ui/dist/assets/arrow-left-bM1TRcV9.js +0 -8
- package/packages/ui/dist/assets/arrow-right-BYd_N4Jr.js +0 -8
- package/packages/ui/dist/assets/arrow-top-CLUnwVE2.js +0 -8
- package/packages/ui/dist/assets/ccip-BL7RIPfY.js +0 -1
- package/packages/ui/dist/assets/chevron-bottom-BMCelIEu.js +0 -8
- package/packages/ui/dist/assets/chevron-left-ryPLhHCc.js +0 -8
- package/packages/ui/dist/assets/chevron-right-CdDNRv7f.js +0 -8
- package/packages/ui/dist/assets/chevron-top-BxWIjjGk.js +0 -8
- package/packages/ui/dist/assets/core-von2c1sc.js +0 -907
- package/packages/ui/dist/assets/cursor-BzRVY7BD.js +0 -3
- package/packages/ui/dist/assets/events-C9icG2YB.js +0 -1
- package/packages/ui/dist/assets/external-link-BPaGQf4a.js +0 -8
- package/packages/ui/dist/assets/fallback-BTfJeGjh.js +0 -1
- package/packages/ui/dist/assets/index-BGJ_8fMk.js +0 -1
- package/packages/ui/dist/assets/index-Bq3PAopp.js +0 -16
- package/packages/ui/dist/assets/index-C4_cA5XW.js +0 -1
- package/packages/ui/dist/assets/index-CaDN0gL4.js +0 -1
- package/packages/ui/dist/assets/index-DLElIcBr.js +0 -1789
- package/packages/ui/dist/assets/index-lhNfD4jA.css +0 -1
- package/packages/ui/dist/assets/index.es-BaCKS_tW.js +0 -26
- package/packages/ui/dist/assets/metamask-sdk-DljW3QD1.js +0 -542
- package/packages/ui/dist/assets/native-CJ5et6AR.js +0 -1
- package/packages/ui/dist/assets/parseSignature-BAS-wKoj.js +0 -1
- package/scripts/check-docs.mjs +0 -309
- package/scripts/check-init.mjs +0 -123
- package/scripts/check-update.mjs +0 -177
- package/scripts/clean.mjs +0 -17
- package/scripts/pack.mjs +0 -21
- package/templates/default/.agents/skills/sail-overview/SKILL.md +0 -100
- package/templates/default/.agents/skills/sail-sailor/SKILL.md +0 -190
- package/templates/default/.agents/skills/sail-setup/SKILL.md +0 -38
- package/templates/default/.gitlab-ci.yml +0 -58
- /package/{examples → templates/default/examples}/custom-mandate/foundry.toml +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/BoundedCallPermission.sol +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/README.md +0 -0
- /package/{examples → templates/default/examples}/custom-mandate/mandates/SailCalldata.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedApproveAndCallBatch.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedBorrow_AaveV3_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedLimitless_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedPerp_GMXv2_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedStake_Venice_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSupply_AaveV3_Arbitrum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwapNative_UniswapV3_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV3_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedSwap_UniswapV4_Unichain.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedTransfer_ERC20_Ethereum.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/BoundedVault_ERC4626_Base.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/README.md +0 -0
- /package/{examples → templates/default/examples}/permissions/SailCalldata.sol +0 -0
- /package/{examples → templates/default/examples}/permissions/foundry.toml +0 -0
package/README.md
CHANGED
|
@@ -1,85 +1,42 @@
|
|
|
1
1
|
# Sailor
|
|
2
2
|
|
|
3
|
-
> The
|
|
4
|
-
|
|
5
|
-
Sailor is the off-chain operator layer for [Sail Protocol](https://github.com/sail-money/SailProtocol): the tooling an operator uses to create a Separately Managed Account, register a mandate, and run a strategy agent against it. It wraps SailKernel dispatch, MandateFactory registration, and EIP-712 mandate signing behind a TypeScript SDK, a CLI, and a local dashboard. It does not deploy the protocol or author permission templates — those live in Sail Protocol. It targets already-deployed SailKernel instances and gives operators the tooling to drive them.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## What's inside
|
|
10
|
-
|
|
11
|
-
| Package | Name | Role |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| `packages/sdk` | `@sail.money/sdk` / `@sail.money/sailor/sdk` | TypeScript library: SailorClient, EIP-712 helpers, ABIs, deployment registry, chain registry |
|
|
14
|
-
| `packages/cli` | `@sail.money/sailor` | CLI for account setup, mandate signing, and agent execution |
|
|
15
|
-
| `packages/ui` | `sailor-ui` | Local dashboard (per-project port; see Dashboard below) |
|
|
16
|
-
| `templates/default` | — | The agent starter `sailor init` scaffolds: slim `AGENTS.md` + on-demand skills under `.agents/skills/` |
|
|
17
|
-
| `examples/permissions` | — | Worked permission contracts by protocol and chain (reference, unaudited) |
|
|
18
|
-
| `examples/custom-mandate` | — | Solidity reference: IPermission authoring scaffold |
|
|
19
|
-
| `examples/lifi-permissions` | — | Solidity reference: LiFi clone permission contracts (source of the clone implementations) |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## Protocol model
|
|
24
|
-
|
|
25
|
-
```mermaid
|
|
26
|
-
flowchart TD
|
|
27
|
-
Owner["**Owner**<br/>holds the Safe · signs the mandate"]
|
|
28
|
-
Manager["**Manager**<br/>agent · signs dispatches"]
|
|
29
|
-
SMA["**SMA**<br/>Safe · holds assets · executes"]
|
|
30
|
-
Mandate["**Mandate**<br/>set of permission contracts"]
|
|
31
|
-
Kernel["**Sail Kernel**<br/>evaluates permission · trusted core<br/>dispatches to Safe on success"]
|
|
32
|
-
|
|
33
|
-
Owner -- "01 deploys & owns" --> SMA
|
|
34
|
-
Owner -- "02 signs mandate (EIP-712)" --> Mandate
|
|
35
|
-
Owner -- "03 appoints · instant revocation" --> Manager
|
|
36
|
-
Manager -- "04 signs dispatch (EIP-712)" --> Kernel
|
|
37
|
-
Mandate -- "05 defines bounds" --> Kernel
|
|
38
|
-
Kernel -- "06 ✓ executes · ✗ outside mandate: reverts" --> SMA
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
Sailor is the operator tooling that drives the Manager/dispatch and mandate-registration flows (steps 02–05).
|
|
42
|
-
|
|
43
|
-
---
|
|
3
|
+
> The open-source toolkit — TypeScript SDK, CLI, and local dashboard — for operating agent-managed Separately Managed Accounts on [Sail Protocol](https://github.com/sail-money/protocol).
|
|
44
4
|
|
|
45
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@sail.money/sailor)
|
|
6
|
+
[](./LICENSE)
|
|
46
7
|
|
|
47
|
-
|
|
8
|
+
## What you can build
|
|
48
9
|
|
|
49
|
-
|
|
50
|
-
|---|---|---|
|
|
51
|
-
| **Owner** | Holds the Safe. Custody anchor. Always self-custodial. | The LP (Safe owner) |
|
|
52
|
-
| **Permission Signer** | Authorizes the mandate. Signs registration and revocation via EIP-712. | Same as Owner, or a separate signing key |
|
|
53
|
-
| **Manager** | Executes dispatches within mandate bounds. Signs each dispatch. | The agent wallet — encrypted in `.sail/keys/manager.json` |
|
|
10
|
+
Autonomous AI agents that transact digital assets, for any use case:
|
|
54
11
|
|
|
55
|
-
|
|
12
|
+
- **Trading** — spot, perps, DCA, rebalancing
|
|
13
|
+
- **Yield** — lending, borrowing, liquidity providing, looping
|
|
14
|
+
- **Prediction markets** — bounded bets on outcome venues
|
|
15
|
+
- **Payments & treasury** — transfers, scheduled moves, operational flows
|
|
56
16
|
|
|
57
|
-
|
|
17
|
+
Every agent operates inside a **mandate** — a set of onchain permissions the protocol enforces on each transaction. The agent can't exceed it; you can revoke it in one transaction.
|
|
58
18
|
|
|
59
|
-
|
|
19
|
+
Sailor takes you end to end: deploy your SMA, build your strategy, sign its mandate, and **run the agent on your own machine**.
|
|
60
20
|
|
|
61
|
-
|
|
62
|
-
2. **Author your permissions** — describe what the agent may do. Permission contracts encode the bounds: tokens, amounts, venues, call targets. Author them in the scaffolded Foundry workspace.
|
|
63
|
-
3. **Simulate, deploy, and sign your mandate** — `sailor mandate simulate` probes a permission off-chain before authorizing it. `sailor mandate deploy --attach` deploys and registers it on-chain. `sailor mandate sign` builds and signs the registration payload against live on-chain state.
|
|
64
|
-
4. **Run** — `sailor run` executes the agent loop. Three execution hosts compose: run it locally on a schedule, install it as a local OS service (`sailor service install` — launchd/systemd/Task Scheduler) that restarts on crash, or let the GitHub Actions cron workflow the scaffold provides run it. `sailor trigger github` fires that workflow on demand.
|
|
65
|
-
5. **Operate** — `sailor doctor` checks kernel health and gas balances; `sailor chains` lists supported chains and deployment addresses; `sailor session pause` instantly revokes dispatch rights without touching Safe custody. After a CLI upgrade, `sailor update` resyncs agent tooling files (skills, `AGENTS.md`, `Dockerfile`) without touching user code or runtime state.
|
|
21
|
+
The full trust model — what the contracts enforce versus what stays off-chain — is in the [Sail Protocol repo](https://github.com/sail-money/protocol) and the [whitepaper](https://github.com/sail-money/protocol/blob/main/docs/whitepaper/Sail_Protocol_Whitepaper.pdf).
|
|
66
22
|
|
|
67
|
-
|
|
23
|
+
## What's in the box
|
|
68
24
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
25
|
+
| Piece | What it does |
|
|
26
|
+
|---|---|
|
|
27
|
+
| **SDK** (`@sail.money/sailor/sdk`) | `SailorClient`, encrypted keyring, EIP-712 signing, dispatch submission, deployment + chain registries, template encoders |
|
|
28
|
+
| **CLI** (`sailor`) | Everything from `sailor init` to `sailor run`: keys, SMA deployment, mandate lifecycle, agent loop, doctor, session control |
|
|
29
|
+
| **Dashboard** (`sailor ui`) | Local web UI for onboarding, balances, mandate health, activity, and owner signing |
|
|
30
|
+
| **Skills** | Seventeen curated procedures under `.agents/skills/` that equip the agent across the whole workflow — project setup and diagnostics, mandate authoring and template configuration, market data and transactions, unattended automation |
|
|
72
31
|
|
|
73
|
-
|
|
32
|
+
**About the scaffold.** `sailor init` scaffolds your project from `templates/default/`, and the agent arrives already equipped: the skills cover setting up (onboarding, project state, the local servers), defining the mandate (one skill per shared template, plus the full custom-permission lifecycle), executing strategy (token resolution and liquidity mapping, live swap quotes, the dispatch model), and running unattended (automation options, notifications, custom dashboards). Alongside the skills ship the **worked example permissions** (`templates/default/examples/` → your project's `examples/`) the mandate skills teach from — protocol-specific bounding patterns (Uniswap, Aave, GMX, ERC-4626, and more) plus an `IPermission` authoring workspace. Shipped teaching material in every scaffold, not repo furniture.
|
|
74
33
|
|
|
75
34
|
## Installation
|
|
76
35
|
|
|
77
|
-
###
|
|
78
|
-
|
|
79
|
-
Create a folder, step into it, then install and init:
|
|
36
|
+
### npm
|
|
80
37
|
|
|
81
38
|
```bash
|
|
82
|
-
# bash / zsh
|
|
39
|
+
# bash / zsh (macOS, Linux)
|
|
83
40
|
mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init
|
|
84
41
|
```
|
|
85
42
|
|
|
@@ -88,454 +45,89 @@ mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init
|
|
|
88
45
|
mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init
|
|
89
46
|
```
|
|
90
47
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
> **npx shortcut** — skips the explicit install; npm downloads sailor on the fly:
|
|
94
|
-
> ```sh
|
|
95
|
-
> mkdir my-agent && cd my-agent && npx sailor init
|
|
96
|
-
> ```
|
|
97
|
-
|
|
98
|
-
### Global CLI (for direct sailor commands)
|
|
99
|
-
|
|
100
|
-
```sh
|
|
101
|
-
npm install -g @sail.money/sailor
|
|
102
|
-
sailor init my-agent
|
|
103
|
-
```
|
|
48
|
+
Requires Node.js **>= 18**. For a global CLI instead: `npm install -g @sail.money/sailor`.
|
|
104
49
|
|
|
105
50
|
### Docker (no Node.js required)
|
|
106
51
|
|
|
107
|
-
Run sailor from a pre-built image — useful when you don't want to install Node.js or want an isolated environment:
|
|
108
|
-
|
|
109
52
|
```bash
|
|
110
53
|
mkdir my-agent && cd my-agent
|
|
111
54
|
docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
|
|
112
55
|
docker exec agent sailor init
|
|
113
56
|
```
|
|
114
57
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
---
|
|
58
|
+
Project files live on your host via the volume mount; prefix `sailor` commands with `docker exec agent`. Full details: [docs/docker.md](./docs/docker.md).
|
|
118
59
|
|
|
119
60
|
## Quickstart
|
|
120
61
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
- Node.js 18+
|
|
124
|
-
- A wallet (MetaMask, Rabby, Phantom, and more)
|
|
125
|
-
- An RPC URL (e.g. Alchemy free tier)
|
|
126
|
-
- A supported chain: **Ethereum, Base, Arbitrum, Unichain, Base Sepolia, or Eth Sepolia** — verified deployments are bundled in `@sail.money/sailor`.
|
|
127
|
-
|
|
128
|
-
### Recommended — assistant-driven
|
|
62
|
+
The recommended path is agent-driven: open the scaffolded folder in Claude Code, Cursor, Codex, or any AI coding agent and say **"start"** — the scaffold's `AGENTS.md` and skills walk the agent through everything below. The direct-CLI version of the same journey:
|
|
129
63
|
|
|
130
64
|
```bash
|
|
131
|
-
|
|
132
|
-
mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init && npm install
|
|
133
|
-
```
|
|
65
|
+
npx sailor init my-agent && cd my-agent && npm install
|
|
134
66
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init ; npm install
|
|
138
|
-
```
|
|
67
|
+
# 1. Generate the agent's encrypted signing key (geth keystore v3 on disk)
|
|
68
|
+
sailor keys generate --type agent-wallet
|
|
139
69
|
|
|
140
|
-
|
|
70
|
+
# 2. Connect your wallet as owner, then deploy the SMA (a Safe) on-chain
|
|
71
|
+
sailor owner connect
|
|
72
|
+
sailor onboard --new-sma
|
|
141
73
|
|
|
142
|
-
|
|
74
|
+
# 3. Give the agent a mandate — register + configure a shared permission
|
|
75
|
+
# template (swap, transfer, deposit, ...). The skills flow drives this
|
|
76
|
+
# conversationally; directly, it is register then configure:
|
|
77
|
+
sailor mandate attach --address <templateAddress> --sma <yourSMA>
|
|
78
|
+
sailor mandate configure --address <templateAddress> --template SwapPermission --args-file swap-config.json
|
|
143
79
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
sailor chains # list supported chains and kernel addresses
|
|
147
|
-
sailor capabilities # what you can build on this chain — read-only, no gas
|
|
148
|
-
sailor doctor # kernel model + RPC reachability + gas balances
|
|
149
|
-
|
|
150
|
-
# SMA setup
|
|
151
|
-
sailor account predict # compute deterministic SMA address before deploying
|
|
152
|
-
sailor onboard --new-sma # deploy SMA and optionally attach a mandate
|
|
153
|
-
|
|
154
|
-
# Mandate lifecycle
|
|
155
|
-
sailor mandate simulate # probe a permission off-chain (no gas) before registering
|
|
156
|
-
sailor mandate sign # sign the mandate — reconciles against live on-chain state
|
|
157
|
-
sailor mandate deploy # deploy a Foundry-compiled permission contract
|
|
158
|
-
sailor mandate attach # register a deployed permission on an SMA (or a comma-separated list, in one signature)
|
|
159
|
-
|
|
160
|
-
# Agent operation
|
|
161
|
-
sailor run --once # single tick — confirm it works before automating
|
|
162
|
-
sailor run # start the agent (continuous)
|
|
163
|
-
sailor keys export-ci # copy encrypted agent wallet to ci-keystore.json for CI
|
|
164
|
-
|
|
165
|
-
# Unattended execution
|
|
166
|
-
sailor service install # run as a local OS daemon (launchd/systemd/Task Scheduler), restarts on crash
|
|
167
|
-
sailor service status # whether the service is installed and running
|
|
168
|
-
sailor service logs -f # follow the agent log (.sail/agent.log)
|
|
169
|
-
sailor trigger github # fire the agent's GitHub Actions workflow on demand
|
|
170
|
-
|
|
171
|
-
# Dashboard
|
|
172
|
-
sailor ui start # prints the per-project dashboard URL
|
|
173
|
-
sailor ui start --expose tailscale # also expose it on your tailnet over HTTPS (see Dashboard section)
|
|
174
|
-
|
|
175
|
-
# Maintenance
|
|
176
|
-
sailor update # re-sync skills, AGENTS.md, and tooling files after a CLI upgrade
|
|
80
|
+
# 4. Run the agent loop (or --once for a single tick)
|
|
81
|
+
sailor run --once
|
|
177
82
|
```
|
|
178
83
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
---
|
|
182
|
-
|
|
183
|
-
## Templates
|
|
184
|
-
|
|
185
|
-
`sailor init` scaffolds a new agent project from a template. By default it
|
|
186
|
-
writes into the **current directory**; pass a name to create a subdirectory.
|
|
84
|
+
**See an action get blocked.** The fail-closed guarantee is testable before anything is at risk — probe the mandate off-chain with `sailor mandate simulate` (an `eth_call`; spends no gas, signs nothing):
|
|
187
85
|
|
|
188
86
|
```bash
|
|
189
|
-
sailor
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
sailor init my-agent --template <name> # named subdirectory + specific template
|
|
87
|
+
sailor mandate simulate --address <templateAddress> \
|
|
88
|
+
--target <someContractOutsideYourMandate> \
|
|
89
|
+
--calldata 0xa9059cbb... --expect fail
|
|
193
90
|
```
|
|
194
91
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
| Template | Description |
|
|
198
|
-
|---|---|
|
|
199
|
-
| `default` | Neutral agent starter. Includes a blank agent loop, Foundry workspace for permission contracts, GitHub Actions cron job, and the operator guide (`AGENTS.md`). For a complete worked example see `examples/dca/`. **Default.** |
|
|
200
|
-
|
|
201
|
-
### What makes a valid template
|
|
202
|
-
|
|
203
|
-
A valid template is any directory under `templates/` that contains a
|
|
204
|
-
`package.json`. Solidity reference sources live under `examples/`
|
|
205
|
-
(`examples/permissions`, `examples/custom-mandate`, `examples/lifi-permissions`)
|
|
206
|
-
— they are not project scaffolds and never appear in the template list.
|
|
207
|
-
|
|
208
|
-
### Adding a template
|
|
209
|
-
|
|
210
|
-
1. Create a directory under `templates/<your-template-name>/`.
|
|
211
|
-
2. Add a `package.json` (the `name` field is patched to the project name on
|
|
212
|
-
init).
|
|
213
|
-
3. Add a `.sail/` workspace structure if the agent needs local state.
|
|
214
|
-
4. The template will appear automatically in `sailor init --template <name>`.
|
|
215
|
-
|
|
216
|
-
Template files are bundled into the published `sailor` npm package via the
|
|
217
|
-
`files` field in the root `package.json`.
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## Dashboard (`sailor ui`)
|
|
222
|
-
|
|
223
|
-
The Sailor dashboard is a local React app. It shows live account state, mandate
|
|
224
|
-
health, signer balances, and recent activity — all read from the project's
|
|
225
|
-
`.sail/` directory with no hosted backend.
|
|
226
|
-
|
|
227
|
-
Each project gets its own deterministic port in the 3333–3999 range (derived
|
|
228
|
-
from the project path, so several projects can run dashboards side by side).
|
|
229
|
-
Use the URL the command prints, or read it from `.sail/runtime/ui.json` —
|
|
230
|
-
do not assume port 3333.
|
|
231
|
-
|
|
232
|
-
### Commands
|
|
233
|
-
|
|
234
|
-
```bash
|
|
235
|
-
sailor ui # start the dashboard (same as sailor ui start)
|
|
236
|
-
sailor ui start # start the dashboard and print its URL
|
|
237
|
-
sailor ui stop # stop the running dashboard
|
|
238
|
-
sailor ui status # show whether the dashboard is running + URL + pid
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
### How it works
|
|
242
|
-
|
|
243
|
-
`sailor ui start` spawns a bundled Express server (`server.cjs`) that:
|
|
244
|
-
|
|
245
|
-
- Serves the pre-built React UI as static files on `/`
|
|
246
|
-
- Exposes a local API on `/api` that reads `.sail/` state from the current
|
|
247
|
-
working directory
|
|
248
|
-
|
|
249
|
-
The server PID is written to `.sail/runtime/ui.json` on start. `sailor ui stop`
|
|
250
|
-
reads that file, sends `SIGTERM` to the server process, and removes the file.
|
|
251
|
-
This means you can start the dashboard in one terminal and stop it from another.
|
|
252
|
-
|
|
253
|
-
### Running in the background
|
|
254
|
-
|
|
255
|
-
```bash
|
|
256
|
-
# macOS / Linux
|
|
257
|
-
sailor ui start &
|
|
258
|
-
sailor ui status # ● running http://localhost:<port> (pid 12345)
|
|
259
|
-
sailor ui stop # Stopped Sailor UI (pid 12345).
|
|
260
|
-
|
|
261
|
-
# Windows (PowerShell)
|
|
262
|
-
Start-Job { sailor ui start }
|
|
263
|
-
sailor ui status
|
|
264
|
-
sailor ui stop
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
### Remote access over your tailnet (HTTPS) — optional
|
|
268
|
-
|
|
269
|
-
The dashboard is local-only by default. To reach it from another device (e.g. a
|
|
270
|
-
remote operator box), expose it over your [Tailscale](https://tailscale.com)
|
|
271
|
-
tailnet on HTTPS:
|
|
272
|
-
|
|
273
|
-
```bash
|
|
274
|
-
sailor ui start --expose tailscale
|
|
275
|
-
# → Sailor UI started at http://localhost:<port>
|
|
276
|
-
# → Exposed on your tailnet at https://<node>.<tailnet>.ts.net/
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
It uses `tailscale serve` (tailnet-private), **never `funnel`** — only devices on
|
|
280
|
-
your tailnet can reach it, not the public internet. `sailor ui stop` tears the
|
|
281
|
-
tailnet proxy down along with the local server.
|
|
282
|
-
|
|
283
|
-
Requirements:
|
|
284
|
-
|
|
285
|
-
- `tailscale` installed and logged in (`tailscale up`).
|
|
286
|
-
- Tailscale **Serve** enabled for your tailnet, plus **HTTPS certificates**
|
|
287
|
-
(admin console → DNS → Enable HTTPS). If Serve is disabled, the command prints
|
|
288
|
-
the enable link instead of reporting success.
|
|
289
|
-
|
|
290
|
-
When exposed, the tailnet origin is added to the dashboard's CORS allowlist
|
|
291
|
-
automatically. To allow additional origins (e.g. a custom HTTPS host in front of
|
|
292
|
-
the station), set a comma-separated list — the local origin is always allowed:
|
|
293
|
-
|
|
294
|
-
```bash
|
|
295
|
-
SAILOR_CORS_ORIGINS=https://hermes.example.ts.net,https://another.host
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
---
|
|
299
|
-
|
|
300
|
-
## Agent-driven onboarding & custom mandates
|
|
301
|
-
|
|
302
|
-
On any of the six supported chains, an agent can drive the whole setup through
|
|
303
|
-
a browser **signing station**. The station is a local HTTP + WebSocket daemon
|
|
304
|
-
that bridges the CLI and the owner's wallet: the agent never holds the owner
|
|
305
|
-
key — it pushes signing requests, the owner approves them in the browser, and
|
|
306
|
-
the agent submits the transactions it's allowed to.
|
|
307
|
-
|
|
308
|
-
```bash
|
|
309
|
-
sailor keys generate # create the manager (agent) key
|
|
310
|
-
sailor station start & # signing daemon (serves the UI)
|
|
311
|
-
# owner opens the printed URL once and connects their wallet
|
|
312
|
-
sailor owner connect # detect & persist the owner
|
|
313
|
-
sailor scan # discover the owner's Safes + state
|
|
314
|
-
sailor onboard --new-sma # create an SMA + (optionally) attach a mandate
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
Agents author their own permission contracts and deploy them from the scaffolded
|
|
318
|
-
Foundry workspace (`mandates/`, with `@sail/interfaces/IPermission.sol` vendored
|
|
319
|
-
under `.sail/contracts/`):
|
|
320
|
-
|
|
321
|
-
```bash
|
|
322
|
-
forge build
|
|
323
|
-
sailor mandate deploy --contract MyMandate \
|
|
324
|
-
--args '["0xPermissionSigner", ["0xTarget"]]' \
|
|
325
|
-
--attach --sma 0xSafe
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
`deploy` emits a contract-creation signing request (the owner signs it in the
|
|
329
|
-
browser); the deployed address is read from the receipt and tracked in
|
|
330
|
-
`.sail/state/mandates.json`. `attach` reads the signer nonce, has the owner sign
|
|
331
|
-
a `RegisterPermission` EIP-712 message, then the agent submits
|
|
332
|
-
`kernel.registerPermission` with the exact registration fee. Every command takes
|
|
333
|
-
`--json` for headless agent use; set `SAIL_PASSPHRASE` to unlock the manager key
|
|
334
|
-
non-interactively.
|
|
335
|
-
|
|
336
|
-
`sailor mandate sign` reconciles against the live on-chain `getPermissions()` call
|
|
337
|
-
before building the mandate payload — permissions revoked on-chain are excluded even
|
|
338
|
-
if they remain in the local `.sail/state/mandates.json` (which is an append-only
|
|
339
|
-
historical record and is never modified by the reconciliation).
|
|
340
|
-
|
|
341
|
-
### GitHub Actions CI
|
|
342
|
-
|
|
343
|
-
The scaffolded `.github/workflows/agent-tick.yml` runs `sailor run --once` on a
|
|
344
|
-
cron schedule using `npm ci` (no pnpm required). Setup:
|
|
92
|
+
Each probed call prints a verdict — `PASS`, `FAIL`, or `REVERT` — which is the permission contract's real `evaluate()` decision, exactly what the kernel consults on a live dispatch. A call outside your mandate shows `FAIL` (and `--expect fail` exits non-zero on a mismatch, so you can wire it into CI). At runtime the same protection reads: `sailor run` skips any planned call no registered permission accepts — logged to the console (`skipped: no registered permission authorizes call to <target>`) and to `.sail/activity.jsonl` as `dispatch_denied` — and if a transaction ever reaches the kernel outside its bounds, the kernel reverts it. Deny by default, at every layer.
|
|
345
93
|
|
|
346
|
-
|
|
347
|
-
in the project root and allowlists it in `.gitignore`. The geth v3 keystore is
|
|
348
|
-
safe to commit; the raw private key is never exposed.
|
|
349
|
-
2. Commit `ci-keystore.json`, `.sail/account.json`, and `.sail/mandate.json`.
|
|
350
|
-
3. Add two repository secrets (Settings → Secrets → Actions):
|
|
351
|
-
- `SAIL_PASSPHRASE` — the passphrase that encrypts the agent wallet
|
|
352
|
-
- `RPC_URL` — your RPC endpoint
|
|
94
|
+
Longer walkthrough, including revocation: [docs/getting-started.md](./docs/getting-started.md).
|
|
353
95
|
|
|
354
|
-
|
|
355
|
-
`npx sailor run --once` with `SAIL_PASSPHRASE` set so the key is unlocked
|
|
356
|
-
non-interactively. No private key ever appears in the workflow file or in secrets.
|
|
96
|
+
## How the agent is guided (skills)
|
|
357
97
|
|
|
358
|
-
|
|
98
|
+
The scaffold follows the open [Agent Skills](https://agentskills.io) standard: a slim, always-loaded `AGENTS.md` carries the project map and hard invariants, while detailed procedures live in on-demand skills under `.agents/skills/` — onboarding, transactions, mandate authoring, shared-template configuration (one skill per template), automation, and more. Shared templates are registered and configured *through* the skills because the safe order of operations (register → configure → simulate → verify) is encoded there once, instead of re-derived by every agent. Skills are plain markdown; agents that don't scan skills follow the routing table in `AGENTS.md` to the same files. See [docs/templates-and-skills.md](./docs/templates-and-skills.md).
|
|
359
99
|
|
|
360
|
-
##
|
|
100
|
+
## Documentation
|
|
361
101
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
| Package | Contents |
|
|
102
|
+
| Doc | What's in it |
|
|
365
103
|
|---|---|
|
|
366
|
-
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
The SDK is also published separately as `@sail.money/sdk` for projects that consume it independently of the CLI.
|
|
375
|
-
|
|
376
|
-
### npm (`publish-npm.yml`)
|
|
377
|
-
|
|
378
|
-
Published to the public npm registry under the `@sail.money` scope.
|
|
379
|
-
|
|
380
|
-
| Trigger | Package | Version | dist-tag |
|
|
381
|
-
|---|---|---|---|
|
|
382
|
-
| Tag push (`v*`) | `@sail.money/sailor` | `1.2.0` | `latest` |
|
|
383
|
-
| Manual dispatch | `@dev.sail.money/sailor` | `1.2.0-42` | `dev` |
|
|
384
|
-
|
|
385
|
-
```bash
|
|
386
|
-
npm install @sail.money/sailor # latest stable (tag push)
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
For dev builds, the package name changes scope to `@dev.sail.money`. Use an alias so your import paths stay the same:
|
|
390
|
-
|
|
391
|
-
```bash
|
|
392
|
-
npm install "@sail.money/sailor@npm:@dev.sail.money/sailor@dev"
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
This installs the latest dev build and makes it available as `@sail.money/sailor` locally — `@sail.money/sailor/sdk` imports continue to work unchanged.
|
|
396
|
-
|
|
397
|
-
### GitHub Packages (`publish.yml`)
|
|
398
|
-
|
|
399
|
-
Published to GitHub Packages under the `@sail-money` scope for internal testing — no public npm registry required.
|
|
400
|
-
|
|
401
|
-
| Trigger | Package | dist-tag |
|
|
402
|
-
|---|---|---|
|
|
403
|
-
| Merge to `main` | `@sail-money/sailor` | `latest` |
|
|
404
|
-
| Manual dispatch | `@sail-money/sailor-dev` | `dev` |
|
|
405
|
-
|
|
406
|
-
Both builds require an alias since the package scope differs from `@sail.money`:
|
|
407
|
-
|
|
408
|
-
```bash
|
|
409
|
-
npm install "@sail.money/sailor@npm:@sail-money/sailor@latest" --registry https://npm.pkg.github.com
|
|
410
|
-
npm install "@sail.money/sailor@npm:@sail-money/sailor-dev@dev" --registry https://npm.pkg.github.com
|
|
411
|
-
```
|
|
412
|
-
|
|
413
|
-
Or pin in `package.json`:
|
|
414
|
-
|
|
415
|
-
```json
|
|
416
|
-
"dependencies": {
|
|
417
|
-
"@sail.money/sailor": "npm:@sail-money/sailor@latest"
|
|
418
|
-
}
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
```json
|
|
422
|
-
"dependencies": {
|
|
423
|
-
"@sail.money/sailor": "npm:@sail-money/sailor-dev@dev"
|
|
424
|
-
}
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
Either way, `@sail.money/sailor/sdk` imports work unchanged.
|
|
428
|
-
|
|
429
|
-
### Docker Hub (`publish-docker.yml`)
|
|
430
|
-
|
|
431
|
-
A pre-built image is published to Docker Hub so you can run the CLI without installing Node.js locally. The image uses Alpine Linux and includes `tsx` (required to compile TypeScript agent code at runtime).
|
|
432
|
-
|
|
433
|
-
| Trigger | Tag |
|
|
434
|
-
|---|---|
|
|
435
|
-
| Merge to `main` or manual dispatch | `sailmoney/sailor:dev` |
|
|
436
|
-
| Tag push (`v*`) | `sailmoney/sailor:<version>` + `sailmoney/sailor:latest` |
|
|
437
|
-
|
|
438
|
-
#### Starting the container
|
|
439
|
-
|
|
440
|
-
Run this from your project root. `-P` publishes all exposed ports to random available host ports; use a fixed `-p <host>:3334` if you want a stable UI port.
|
|
441
|
-
|
|
442
|
-
```bash
|
|
443
|
-
docker run -d --name agent -P -v "${PWD}:/workspace" sailmoney/sailor
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
- `-d` — detached, runs in the background
|
|
447
|
-
- `--name agent` — container name used in all `docker exec` calls
|
|
448
|
-
- `-P` — maps container ports (UI: 3334, station: 3141) to random host ports
|
|
449
|
-
- `-v "${PWD}:/workspace"` — mounts the current project into the container
|
|
450
|
-
|
|
451
|
-
#### Running sailor commands
|
|
452
|
-
|
|
453
|
-
All sailor commands run via `docker exec`:
|
|
454
|
-
|
|
455
|
-
```bash
|
|
456
|
-
docker exec agent sailor --version
|
|
457
|
-
docker exec agent sailor init
|
|
458
|
-
docker exec agent sailor ui start
|
|
459
|
-
docker exec agent sailor run --once
|
|
460
|
-
```
|
|
461
|
-
|
|
462
|
-
Project files are on your **local filesystem** — read and write them directly from local paths. Only `sailor` commands need the `docker exec` prefix; the volume mount makes files accessible to both sides.
|
|
463
|
-
|
|
464
|
-
#### Opening the dashboard
|
|
465
|
-
|
|
466
|
-
The UI always binds to port **3334 inside the container**, but the host-side port depends on how `-P` mapped it. Resolve it before opening the browser:
|
|
467
|
-
|
|
468
|
-
```bash
|
|
469
|
-
docker port agent 3334
|
|
470
|
-
# → 0.0.0.0:49201 (open http://localhost:49201 in the browser)
|
|
471
|
-
```
|
|
472
|
-
|
|
473
|
-
#### Stopping
|
|
474
|
-
|
|
475
|
-
```bash
|
|
476
|
-
docker stop agent # stop the container
|
|
477
|
-
docker start agent # restart it later (project files and state are on the host)
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
---
|
|
104
|
+
| [docs/getting-started.md](./docs/getting-started.md) | Long-form quickstart: install → first SMA → first mandate → first run → revocation |
|
|
105
|
+
| [docs/cli-reference.md](./docs/cli-reference.md) | The full `sailor` command surface, grouped by workflow |
|
|
106
|
+
| [docs/sdk-usage.md](./docs/sdk-usage.md) | `SailorClient` basics and every SDK subpath export, with examples |
|
|
107
|
+
| [docs/docker.md](./docs/docker.md) | Image, volumes, key handling, dashboard access, headless operation |
|
|
108
|
+
| [docs/templates-and-skills.md](./docs/templates-and-skills.md) | The shared-template catalog and how skills drive configuration and use |
|
|
109
|
+
| [docs/architecture.md](./docs/architecture.md) | The Sailor ↔ Sail Protocol boundary: what's onchain vs what this toolkit does |
|
|
481
110
|
|
|
482
111
|
## Security model
|
|
483
112
|
|
|
484
|
-
- The agent signs dispatches; the kernel evaluates the named permission on every call
|
|
485
|
-
- The Owner key controls the Safe and is never read by Sailor
|
|
486
|
-
- The manager key is encrypted on disk
|
|
487
|
-
- The session can be paused instantly
|
|
488
|
-
- All addresses
|
|
489
|
-
|
|
490
|
-
---
|
|
491
|
-
|
|
492
|
-
## State of the project
|
|
493
|
-
|
|
494
|
-
Sailor is functional and published as [`@sail.money/sailor`](https://www.npmjs.com/package/@sail.money/sailor) on npm (v1.2.0). The SDK, CLI, keystore, mandate flows, agent runner, and dashboard are implemented and have been exercised end to end.
|
|
495
|
-
|
|
496
|
-
The Sail Protocol trusted core is deployed on six chains — Ethereum, Base, Arbitrum, Unichain, Base Sepolia, and Eth Sepolia — via CREATE2, with every core contract at the same address on every chain. All six run the selective dispatch model with zero fees and are bootstrapped with a genesis allowlist so `createAccount` is usable immediately. These deployments are under an ongoing external audit by [Octane Security](https://octane.security) and are not final — do not use them with funds you are not prepared to lose.
|
|
497
|
-
|
|
498
|
-
Permission templates have not yet been deployed against the current kernel on any chain; `knownTemplates` and `standaloneTemplates` are empty for all six chains in `packages/sdk/src/deployments.ts` and will be populated as templates are deployed and verified against the new kernel.
|
|
113
|
+
- The agent signs dispatches; the **kernel evaluates the named permission on every call**. A permission returning false, reverting, or exceeding its gas cap is a denial — fail-closed.
|
|
114
|
+
- The **Owner key controls the Safe and is never read by Sailor**. Mandate registration requires a deliberate signature from the permission signer in the browser signing station.
|
|
115
|
+
- The **manager (agent) key is encrypted on disk** (geth keystore v3: scrypt + aes-128-ctr) and never transmitted.
|
|
116
|
+
- The session can be **paused instantly** (`sailor session pause` or the dashboard) — revoking dispatch rights without touching Safe custody.
|
|
117
|
+
- All addresses are EIP-55 normalized before any on-chain call or state write.
|
|
499
118
|
|
|
500
|
-
|
|
119
|
+
Vulnerability reports: see [SECURITY.md](./SECURITY.md) (off-chain toolkit) — smart-contract issues go to the [protocol's policy](https://github.com/sail-money/protocol/blob/main/SECURITY.md).
|
|
501
120
|
|
|
502
121
|
## Deployments
|
|
503
122
|
|
|
504
|
-
|
|
123
|
+
The SDK bundles verified deployments for **11 chains** — mainnets: Ethereum (1), Base (8453), Arbitrum (42161), Optimism (10), Unichain (130), BSC (56), World Chain (480), HyperEVM (999), MegaETH (4326); testnets: Base Sepolia (84532), Ethereum Sepolia (11155111). Every core contract sits at the same address on every chain via CREATE2 (SailKernel: `0x38b508756c976e876EFF05a29E731A4d348BA6ED`), and the seven shared permission templates (swap, swap-no-oracle, borrow, deposit, withdraw, transfer, approve-and-call-batch) are deployed and registered as `knownTemplates` on all of them. Query it yourself: `sailor chains` or `getSailDeployment(chainId)` from the SDK; the canonical record is the protocol repo's [deployments/addresses.md](https://github.com/sail-money/protocol/blob/main/deployments/addresses.md).
|
|
505
124
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
| Contract | Address |
|
|
509
|
-
|---|---|
|
|
510
|
-
| SailKernel | `0x02ABC18B65A328de2e749F56ba79ACF2718a6659` |
|
|
511
|
-
| SailGovernance | `0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC` |
|
|
512
|
-
| TimelockController | `0xE48Ba8DB6d748adafD13155c3590f62e58a77f56` |
|
|
513
|
-
| MandateFactory | `0x14EDd6c2a56EfC0d71E215ab13094B9AF90543d2` |
|
|
514
|
-
| StandardFeePolicy | `0xe7B5901b839cFFDEd9D4108A22712C8BfdA1D80D` |
|
|
515
|
-
| SafeModuleEnabler | `0x7897Cb53a4be4a2eaAf46D60573C4Fd83b33fE1F` |
|
|
516
|
-
| Treasury | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
|
|
517
|
-
|
|
518
|
-
These addresses are bundled in `@sail.money/sailor` and exposed via `getSailDeployment(chainId)` in the SDK. The Protocol repository is the canonical source of truth for deployment details — see [deployments/addresses.md](https://github.com/sail-money/Protocol/blob/main/deployments/addresses.md).
|
|
519
|
-
|
|
520
|
-
### Supported chains
|
|
521
|
-
|
|
522
|
-
| Chain | Chain ID |
|
|
523
|
-
|---|---|
|
|
524
|
-
| Ethereum | 1 |
|
|
525
|
-
| Base | 8453 |
|
|
526
|
-
| Arbitrum | 42161 |
|
|
527
|
-
| Unichain | 130 |
|
|
528
|
-
| Base Sepolia | 84532 |
|
|
529
|
-
| Eth Sepolia | 11155111 |
|
|
530
|
-
|
|
531
|
-
---
|
|
125
|
+
The Sail Protocol trusted core and its seven shared permission templates underwent an AI **security review** by [Octane](https://octane.security); the final analysis identified no critical- or high-severity findings, and the reports live in the protocol repo's [docs/security](https://github.com/sail-money/protocol/tree/main/docs/security). That review covers the protocol contracts — not this toolkit. A security review is not a guarantee of correctness; size your exposure accordingly.
|
|
532
126
|
|
|
533
127
|
## Contributing
|
|
534
128
|
|
|
535
|
-
Sailor
|
|
536
|
-
|
|
537
|
-
---
|
|
129
|
+
Sailor will be continuously enhanced through community participation and feedback — contributions, issue reports, and design discussions are actively welcomed. Start with [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
538
130
|
|
|
539
131
|
## License
|
|
540
132
|
|
|
541
|
-
MIT
|
|
133
|
+
[MIT](./LICENSE) © Agentic Finance Inc.
|