@dev.sail.money/sailor 0.0.2 → 1.0.0-38

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.
Files changed (199) hide show
  1. package/AGENTS.md +43 -15
  2. package/README.md +217 -126
  3. package/examples/permissions/BoundedApproveAndCallBatch.sol +179 -0
  4. package/examples/permissions/BoundedBet_Limitless_Base.sol +8 -7
  5. package/examples/permissions/BoundedBorrow_AaveV3_Arbitrum.sol +13 -13
  6. package/examples/permissions/BoundedPerp_GMXv2_Arbitrum.sol +50 -39
  7. package/examples/permissions/BoundedStake_Venice_Base.sol +85 -0
  8. package/examples/permissions/BoundedSupply_AaveV3_Arbitrum.sol +82 -0
  9. package/examples/permissions/BoundedSwap_UniswapV3_Base.sol +15 -12
  10. package/examples/permissions/BoundedSwap_UniswapV4_Unichain.sol +14 -8
  11. package/examples/permissions/BoundedTransfer_ERC20_Ethereum.sol +6 -6
  12. package/examples/permissions/BoundedVault_ERC4626_Base.sol +97 -0
  13. package/examples/permissions/README.md +29 -2
  14. package/examples/permissions/SailCalldata.sol +118 -0
  15. package/examples/permissions/interfaces/IBatchPermission.sol +38 -0
  16. package/package.json +17 -12
  17. package/packages/cli/dist/index.cjs +4164 -2508
  18. package/packages/cli/dist/server.cjs +897 -1566
  19. package/packages/sdk/dist/chains.d.ts +12 -0
  20. package/packages/sdk/dist/chains.d.ts.map +1 -0
  21. package/packages/sdk/dist/chains.js +94 -0
  22. package/packages/sdk/dist/chains.js.map +1 -0
  23. package/packages/sdk/dist/deployments.d.ts +14 -7
  24. package/packages/sdk/dist/deployments.d.ts.map +1 -1
  25. package/packages/sdk/dist/deployments.js +132 -141
  26. package/packages/sdk/dist/deployments.js.map +1 -1
  27. package/packages/sdk/dist/index.d.ts +3 -2
  28. package/packages/sdk/dist/index.d.ts.map +1 -1
  29. package/packages/sdk/dist/index.js +3 -2
  30. package/packages/sdk/dist/index.js.map +1 -1
  31. package/packages/sdk/dist/intelligence.d.ts +1 -1
  32. package/packages/sdk/dist/intelligence.js +1 -1
  33. package/packages/sdk/dist/lifi.d.ts +17 -0
  34. package/packages/sdk/dist/lifi.d.ts.map +1 -1
  35. package/packages/sdk/dist/lifi.js +24 -0
  36. package/packages/sdk/dist/lifi.js.map +1 -1
  37. package/packages/sdk/dist/safe.d.ts +83 -0
  38. package/packages/sdk/dist/safe.d.ts.map +1 -1
  39. package/packages/sdk/dist/safe.js +92 -1
  40. package/packages/sdk/dist/safe.js.map +1 -1
  41. package/packages/sdk/dist/templates/ammLiquidity.d.ts +24 -11
  42. package/packages/sdk/dist/templates/ammLiquidity.d.ts.map +1 -1
  43. package/packages/sdk/dist/templates/ammLiquidity.js +39 -31
  44. package/packages/sdk/dist/templates/ammLiquidity.js.map +1 -1
  45. package/packages/sdk/dist/templates/approveAndCallBatch.d.ts +24 -10
  46. package/packages/sdk/dist/templates/approveAndCallBatch.d.ts.map +1 -1
  47. package/packages/sdk/dist/templates/approveAndCallBatch.js +36 -23
  48. package/packages/sdk/dist/templates/approveAndCallBatch.js.map +1 -1
  49. package/packages/sdk/dist/templates/boundedBorrow.d.ts +19 -9
  50. package/packages/sdk/dist/templates/boundedBorrow.d.ts.map +1 -1
  51. package/packages/sdk/dist/templates/boundedBorrow.js +28 -19
  52. package/packages/sdk/dist/templates/boundedBorrow.js.map +1 -1
  53. package/packages/sdk/dist/templates/boundedSwap.d.ts +19 -9
  54. package/packages/sdk/dist/templates/boundedSwap.d.ts.map +1 -1
  55. package/packages/sdk/dist/templates/boundedSwap.js +30 -20
  56. package/packages/sdk/dist/templates/boundedSwap.js.map +1 -1
  57. package/packages/sdk/dist/templates/defiBundle.d.ts +35 -9
  58. package/packages/sdk/dist/templates/defiBundle.d.ts.map +1 -1
  59. package/packages/sdk/dist/templates/defiBundle.js +84 -22
  60. package/packages/sdk/dist/templates/defiBundle.js.map +1 -1
  61. package/packages/sdk/dist/templates/pendle.d.ts +23 -8
  62. package/packages/sdk/dist/templates/pendle.d.ts.map +1 -1
  63. package/packages/sdk/dist/templates/pendle.js +34 -14
  64. package/packages/sdk/dist/templates/pendle.js.map +1 -1
  65. package/packages/sdk/dist/templates/transferTarget.d.ts +11 -3
  66. package/packages/sdk/dist/templates/transferTarget.d.ts.map +1 -1
  67. package/packages/sdk/dist/templates/transferTarget.js +14 -7
  68. package/packages/sdk/dist/templates/transferTarget.js.map +1 -1
  69. package/packages/sdk/dist/types.d.ts +19 -1
  70. package/packages/sdk/dist/types.d.ts.map +1 -1
  71. package/packages/sdk/package.json +28 -0
  72. package/packages/ui/dist/assets/{add-DaJhwIBV.js → add-Dl1etsL9.js} +1 -1
  73. package/packages/ui/dist/assets/{all-wallets-BUxsqWXi.js → all-wallets-C0eHLOGG.js} +1 -1
  74. package/packages/ui/dist/assets/{app-store-DkltwTqE.js → app-store-B-VMDEZ3.js} +1 -1
  75. package/packages/ui/dist/assets/{apple-owVOeaIT.js → apple-DkDXzKns.js} +1 -1
  76. package/packages/ui/dist/assets/{arrow-bottom-D2mmNJve.js → arrow-bottom-DtPzuS76.js} +1 -1
  77. package/packages/ui/dist/assets/{arrow-bottom-circle-CbNYijx-.js → arrow-bottom-circle-D7odSAO8.js} +1 -1
  78. package/packages/ui/dist/assets/{arrow-left-DJB61s4C.js → arrow-left-zJV9tpx0.js} +1 -1
  79. package/packages/ui/dist/assets/{arrow-right-BBrsQ9R4.js → arrow-right-BOREfe7o.js} +1 -1
  80. package/packages/ui/dist/assets/{arrow-top-Cil6bOc8.js → arrow-top-CipQc3Af.js} +1 -1
  81. package/packages/ui/dist/assets/{bank-CbwEmRo3.js → bank-C5s7eoV5.js} +1 -1
  82. package/packages/ui/dist/assets/{basic-CLNfjw3m.js → basic-D2es4Vq8.js} +1 -1
  83. package/packages/ui/dist/assets/{browser-B5TtF4Pb.js → browser-DITQWDC9.js} +1 -1
  84. package/packages/ui/dist/assets/{card-CO7BVB-C.js → card-C3DDkaYK.js} +1 -1
  85. package/packages/ui/dist/assets/{ccip-2W7K3_J3.js → ccip-UBXL3JiN.js} +1 -1
  86. package/packages/ui/dist/assets/{checkmark-bold-D9xGHzPE.js → checkmark-bold-D8yW0_K_.js} +1 -1
  87. package/packages/ui/dist/assets/{checkmark-BEtSHq9m.js → checkmark-ngef3MAl.js} +1 -1
  88. package/packages/ui/dist/assets/{chevron-bottom-BDztht6i.js → chevron-bottom-C56BipDR.js} +1 -1
  89. package/packages/ui/dist/assets/{chevron-left-EV4GFNbc.js → chevron-left-BmIPtPl_.js} +1 -1
  90. package/packages/ui/dist/assets/{chevron-right-B4_bB9oR.js → chevron-right-BnySHQ8h.js} +1 -1
  91. package/packages/ui/dist/assets/{chevron-top-D54xPNzF.js → chevron-top-BDGZnNW3.js} +1 -1
  92. package/packages/ui/dist/assets/{chrome-store-DYUpAJJq.js → chrome-store-BYIqJZVF.js} +1 -1
  93. package/packages/ui/dist/assets/{clock-Ca1T1Soz.js → clock-Bl4mUHAM.js} +1 -1
  94. package/packages/ui/dist/assets/{close-BZqWjurK.js → close-B9rhEX6U.js} +1 -1
  95. package/packages/ui/dist/assets/{coinPlaceholder-e6fl2XDo.js → coinPlaceholder-1cO0FQsl.js} +1 -1
  96. package/packages/ui/dist/assets/{compass-DCLC7zIh.js → compass-7i-VuXu2.js} +1 -1
  97. package/packages/ui/dist/assets/{copy-Th2AaD-O.js → copy-OqqXix2J.js} +1 -1
  98. package/packages/ui/dist/assets/{core-Ckx_cyuH.js → core-tX9kIIDJ.js} +3 -3
  99. package/packages/ui/dist/assets/cursor-BoyeQ9fN.js +3 -0
  100. package/packages/ui/dist/assets/{cursor-transparent-BKHeABKB.js → cursor-transparent-5aoRH67u.js} +1 -1
  101. package/packages/ui/dist/assets/{desktop-CBjY8t6F.js → desktop-BaPXK9R6.js} +1 -1
  102. package/packages/ui/dist/assets/{disconnect-DbSs2cli.js → disconnect-LlK5K1CF.js} +1 -1
  103. package/packages/ui/dist/assets/{discord-ZlLOAUkM.js → discord-BdcQNWY_.js} +1 -1
  104. package/packages/ui/dist/assets/{etherscan-CKUrqWYN.js → etherscan-Bb-WxpO1.js} +1 -1
  105. package/packages/ui/dist/assets/{events-CiKP71cK.js → events-DjdZr6no.js} +1 -1
  106. package/packages/ui/dist/assets/{exclamation-triangle-DA1QzFiO.js → exclamation-triangle-COx4VtPV.js} +1 -1
  107. package/packages/ui/dist/assets/{extension-BVJkmvpJ.js → extension-DF63DTWO.js} +1 -1
  108. package/packages/ui/dist/assets/{external-link-D_bsR7B2.js → external-link-DyghCkQu.js} +1 -1
  109. package/packages/ui/dist/assets/{facebook-CmFmhojx.js → facebook-Dcg4bZMR.js} +1 -1
  110. package/packages/ui/dist/assets/{fallback-Ofl6uSnB.js → fallback-DJIr_fH3.js} +1 -1
  111. package/packages/ui/dist/assets/{farcaster-Co-M3Ss8.js → farcaster-BkmV5HjO.js} +1 -1
  112. package/packages/ui/dist/assets/{filters-B1WwNaFU.js → filters-DLHj1T_P.js} +1 -1
  113. package/packages/ui/dist/assets/{github-CP4fP6gn.js → github-BFDCgKrF.js} +1 -1
  114. package/packages/ui/dist/assets/{google-CsOIXJ6V.js → google-C08SpmIy.js} +1 -1
  115. package/packages/ui/dist/assets/{help-circle-DiMkomdF.js → help-circle-DU1IFmWp.js} +1 -1
  116. package/packages/ui/dist/assets/{id-lmscL5LX.js → id-DtDRGf3L.js} +1 -1
  117. package/packages/ui/dist/assets/{image-B-ubJrY5.js → image-CgCXJEjT.js} +1 -1
  118. package/packages/ui/dist/assets/{index-Dbh5V1Z0.js → index-8chM4S5Y.js} +1 -1
  119. package/packages/ui/dist/assets/{index-BaukYv-x.js → index-B5sCtNuq.js} +1 -1
  120. package/packages/ui/dist/assets/{index-CF0KMmke.js → index-BBfBEazf.js} +3 -3
  121. package/packages/ui/dist/assets/{index-CZR1Qjhs.js → index-BhXPwltt.js} +1 -1
  122. package/packages/ui/dist/assets/index-Cm05Py20.css +1 -0
  123. package/packages/ui/dist/assets/{index-DVgfCzCo.js → index-D37bD6Yt.js} +1 -1
  124. package/packages/ui/dist/assets/index-DZfBh-cg.js +1775 -0
  125. package/packages/ui/dist/assets/{index.es-C78cE5SI.js → index.es-BEcNQEn-.js} +4 -4
  126. package/packages/ui/dist/assets/{info-Cqg57EVo.js → info-ClsdYA4P.js} +1 -1
  127. package/packages/ui/dist/assets/{info-circle-DkeSWNKV.js → info-circle-DJmn4Bsv.js} +1 -1
  128. package/packages/ui/dist/assets/{lightbulb-DNlO4qKh.js → lightbulb-CXSftjXS.js} +1 -1
  129. package/packages/ui/dist/assets/{mail-kVQ8Jb9Y.js → mail-cdYKOl9P.js} +1 -1
  130. package/packages/ui/dist/assets/{metamask-sdk-CBalSvz7.js → metamask-sdk-Co3aIEln.js} +1 -1
  131. package/packages/ui/dist/assets/{mobile-BEteuhF7.js → mobile-DEHYlk8L.js} +1 -1
  132. package/packages/ui/dist/assets/{more-DBWmXQli.js → more-Cq_fo8pI.js} +1 -1
  133. package/packages/ui/dist/assets/{network-placeholder-Dg1uUHiL.js → network-placeholder-_dLCK4xB.js} +1 -1
  134. package/packages/ui/dist/assets/{nftPlaceholder-i3AHSiD9.js → nftPlaceholder-Dz4HKEr4.js} +1 -1
  135. package/packages/ui/dist/assets/{off-BtMm0fi2.js → off-B1k1lhkr.js} +1 -1
  136. package/packages/ui/dist/assets/{parseSignature-Cb5FlWWg.js → parseSignature-Cr0ptV2X.js} +1 -1
  137. package/packages/ui/dist/assets/{play-store-iKKkXa6a.js → play-store-lYqe4eeL.js} +1 -1
  138. package/packages/ui/dist/assets/{plus-CA5NaRtb.js → plus-QMgh1krr.js} +1 -1
  139. package/packages/ui/dist/assets/{qr-code-D2kiqR7h.js → qr-code-ClVHbZWN.js} +1 -1
  140. package/packages/ui/dist/assets/{recycle-horizontal-Dcme7R03.js → recycle-horizontal-CxGYnWid.js} +1 -1
  141. package/packages/ui/dist/assets/{refresh-Dega3sDp.js → refresh-CPysMza_.js} +1 -1
  142. package/packages/ui/dist/assets/{reown-logo-xNkksyWJ.js → reown-logo-OoL_zJd0.js} +1 -1
  143. package/packages/ui/dist/assets/{search-HYl7NO8x.js → search-2GaRbf1I.js} +1 -1
  144. package/packages/ui/dist/assets/{secp256k1-Cxd6_SiH.js → secp256k1-BrB8qSSy.js} +1 -1
  145. package/packages/ui/dist/assets/{send-CJU8CUAo.js → send-CC2UuIfD.js} +1 -1
  146. package/packages/ui/dist/assets/{swapHorizontal-IMUKiUre.js → swapHorizontal-BRqYwsqT.js} +1 -1
  147. package/packages/ui/dist/assets/{swapHorizontalBold-CNYnNJ9-.js → swapHorizontalBold-Bj0GSRq9.js} +1 -1
  148. package/packages/ui/dist/assets/{swapHorizontalMedium-B9VxEYsT.js → swapHorizontalMedium-oLOjpU2A.js} +1 -1
  149. package/packages/ui/dist/assets/{swapHorizontalRoundedBold-Dz33l_Jh.js → swapHorizontalRoundedBold-TJ652QXb.js} +1 -1
  150. package/packages/ui/dist/assets/{swapVertical-CHUmjVJ0.js → swapVertical-e0NLyV3x.js} +1 -1
  151. package/packages/ui/dist/assets/{telegram-kl9S2mbU.js → telegram-WhJHVeoU.js} +1 -1
  152. package/packages/ui/dist/assets/{three-dots-U5lhA1Am.js → three-dots-BlBAOyW-.js} +1 -1
  153. package/packages/ui/dist/assets/{twitch-KTEUWXEp.js → twitch-BH7vWmPc.js} +1 -1
  154. package/packages/ui/dist/assets/{twitterIcon-BHiq8mRg.js → twitterIcon-As0Nkanp.js} +1 -1
  155. package/packages/ui/dist/assets/{verify-CfN-BXNd.js → verify-BEJ0QuLl.js} +1 -1
  156. package/packages/ui/dist/assets/{verify-filled-DwZccetj.js → verify-filled-B8Ww2N7z.js} +1 -1
  157. package/packages/ui/dist/assets/{w3m-modal-CS-PFqPE.js → w3m-modal-5rOSZgOR.js} +1 -1
  158. package/packages/ui/dist/assets/{wallet-DVlGkhOY.js → wallet-CAfC3aml.js} +1 -1
  159. package/packages/ui/dist/assets/{wallet-placeholder-CvR_iEWX.js → wallet-placeholder-4RZI464Z.js} +1 -1
  160. package/packages/ui/dist/assets/{walletconnect-8pZBDvVI.js → walletconnect-BiltKqAe.js} +1 -1
  161. package/packages/ui/dist/assets/{warning-circle-ylLEE0Yp.js → warning-circle-CI4jqpHo.js} +1 -1
  162. package/packages/ui/dist/assets/{x-C_TBsTMj.js → x-FBttjBWO.js} +1 -1
  163. package/packages/ui/dist/index.html +2 -2
  164. package/scripts/check-init.mjs +2 -3
  165. package/templates/custom-mandate/README.md +31 -0
  166. package/templates/custom-mandate/mandates/BoundedCallPermission.sol +8 -2
  167. package/templates/custom-mandate/mandates/SailCalldata.sol +118 -0
  168. package/templates/default/.env.example +20 -0
  169. package/templates/{dca-rebalancer → default}/.github/workflows/agent-tick.yml +8 -7
  170. package/templates/{dca-rebalancer → default}/.sail/config.json +2 -2
  171. package/templates/default/AGENTS.md +171 -0
  172. package/templates/default/README.md +16 -0
  173. package/templates/default/examples/dca/README.md +16 -0
  174. package/templates/default/examples/dca/agent.ts +174 -0
  175. package/templates/{dca-rebalancer/src → default/examples/dca}/mandate.ts +9 -31
  176. package/templates/{dca-rebalancer → default}/package.json +2 -2
  177. package/templates/default/src/agent.ts +37 -0
  178. package/templates/default/src/config.ts +24 -0
  179. package/templates/default/src/mandate.ts +22 -0
  180. package/templates/default/tsconfig.json +17 -0
  181. package/templates/lifi-permissions/README.md +1 -1
  182. package/packages/ui/dist/assets/cursor-DV7rOqbJ.js +0 -3
  183. package/packages/ui/dist/assets/index-CKxgNxS9.css +0 -1
  184. package/packages/ui/dist/assets/index-Q2Yai4Fe.js +0 -2103
  185. package/scripts/postinstall.js +0 -366
  186. package/templates/dca-rebalancer/.env.example +0 -6
  187. package/templates/dca-rebalancer/AGENTS.md +0 -246
  188. package/templates/dca-rebalancer/AGENT_PLAYBOOK.md +0 -110
  189. package/templates/dca-rebalancer/README.md +0 -16
  190. package/templates/dca-rebalancer/src/agent.ts +0 -253
  191. package/templates/dca-rebalancer/src/config.ts +0 -27
  192. package/templates/dca-rebalancer/tsconfig.json +0 -8
  193. /package/templates/{dca-rebalancer → default}/.cursor/rules +0 -0
  194. /package/templates/{dca-rebalancer → default}/.sail/.gitkeep +0 -0
  195. /package/templates/{dca-rebalancer → default}/.sail/README.md +0 -0
  196. /package/templates/{dca-rebalancer → default}/CLAUDE.md +0 -0
  197. /package/templates/{dca-rebalancer → default}/_gitignore +0 -0
  198. /package/templates/{dca-rebalancer → default}/docs/PERMISSION_MODEL.md +0 -0
  199. /package/templates/{dca-rebalancer → default}/ui/README.md +0 -0
package/AGENTS.md CHANGED
@@ -8,11 +8,10 @@ tooling to create SMAs, register permission contracts, and run strategy agents.
8
8
 
9
9
  | Package / path | Name | Role |
10
10
  |---|---|---|
11
- | `packages/sdk` | `@sail/sdk` | SailorClient, LocalKeyring, kernel ABIs, EIP-712 builders, deployment registry |
11
+ | `packages/sdk` | `@sail/sdk` | SailorClient, LocalKeyring, kernel ABIs, EIP-712 builders, deployment registry, per-chain address registry |
12
12
  | `packages/cli` | `sailor` | CLI: init, keys, account, mandate, onboard, station, ui, run, session, scan, status, owner, doctor, capabilities |
13
- | `packages/chains` | `@sail/chains` | Per-chain address registry (kernel, mandateFactory, governance) |
14
13
  | `packages/ui` | `sailor-ui` | Local dashboard + browser-driven onboarding wizard at localhost:3333 |
15
- | `templates/dca-rebalancer` | — | Default project scaffold: DCA rebalancer + Foundry workspace |
14
+ | `templates/default` | — | Default agent starter: neutral blank scaffold + Foundry workspace + onboarding guide (AGENTS.md) |
16
15
  | `templates/custom-mandate` | — | Solidity reference: IPermission scaffold (not a project template) |
17
16
 
18
17
  ## Protocol roles
@@ -29,16 +28,15 @@ Use the user-facing terms in all CLI output, prompts, and errors. The code ident
29
28
 
30
29
  ## Dispatch model
31
30
 
32
- Active kernels vary by chain verified on-chain via `DISPATCH_TYPEHASH()`:
31
+ All six chains share the same kernel at the same CREATE2 address, verified on-chain via `DISPATCH_TYPEHASH()`:
33
32
 
34
- | Chain | Kernel | Model | DISPATCH_TYPEHASH |
35
- |---|---|---|---|
36
- | Base 8453 | `0x6319d3dfDDe3804ba93D65752b00c52bFb05a1ab` | **selective** | `0xbe50c539...` |
37
- | Base Sepolia 84532 | `0xf1D0F4C9893612627409948BAa9d82a01a373799` | **selective** | `0xbe50c539...` |
38
- | Arbitrum 42161 | `0x2716B12832DED0EF5688519c5Fe069EFc0374E02` | **selective** | `0xbe50c539...` |
39
- | Unichain 130 | `0xD985029960a9B7C2E7E38e102C448b8b8539B156` | **selective** | `0xbe50c539...` |
33
+ | Kernel (all 6 chains) | Model | DISPATCH_TYPEHASH |
34
+ |---|---|---|
35
+ | `0x02ABC18B65A328de2e749F56ba79ACF2718a6659` | **selective** | `0xbe50c539...` |
36
+
37
+ Supported chains: Ethereum (1), Base (8453), Arbitrum (42161), Unichain (130), Base Sepolia (84532), Eth Sepolia (11155111).
40
38
 
41
- All four kernels are live and bootstrapped (genesis allowlist set, `createAccount` verified working, zero fees). Unichain (130) additionally has the full permission-template suite deployed and source-verified (7 shared + 12 standalone) it is the only chain with templates so far; the other three have core only. `packages/sdk/src/deployments.ts` is the canonical source of truth for kernel addresses, templates, and metadata.
39
+ All six kernels are live and bootstrapped (genesis allowlist set, `createAccount` verified working, zero fees). No templates are deployed against the current kernel on any chain yet`knownTemplates` and `standaloneTemplates` are empty for all six entries. `packages/sdk/src/deployments.ts` is the canonical source of truth for kernel addresses, templates, and metadata.
42
40
 
43
41
  **Always use `detectKernelCapabilities` for the real model** — it reads the on-chain typehash and
44
42
  overrides the static label in `deployments.ts`. The static label is a fallback for offline use only.
@@ -57,11 +55,11 @@ Pass the detected value — never hardcode the type shape.
57
55
 
58
56
  ## Active addresses
59
57
 
60
- All four chain records in `packages/sdk/src/deployments.ts` are live — no commented-out or pending
58
+ All six chain records in `packages/sdk/src/deployments.ts` are live — no commented-out or pending
61
59
  addresses remain. This file is the source of truth this guide mirrors.
62
60
 
63
61
  - `packages/sdk/src/deployments.ts` — `SailDeployment` records; canonical source of truth
64
- - `packages/chains/src/index.ts` — `ChainConfig` per chainId; kept in sync with deployments
62
+ - `packages/sdk/src/chains.ts` — `ChainConfig` per chainId; canonical per-chain registry
65
63
 
66
64
  ## Key files
67
65
 
@@ -79,10 +77,10 @@ addresses remain. This file is the source of truth this guide mirrors.
79
77
 
80
78
  ```bash
81
79
  pnpm install
82
- pnpm build # builds all packages; dependency order: sdk → chains → cli → ui
80
+ pnpm build # builds all packages; dependency order: sdk → cli → ui
83
81
  ```
84
82
 
85
- Build order matters — `cli` imports from `sdk` and `chains`.
83
+ Build order matters — `cli` imports from `sdk`.
86
84
 
87
85
  ## Test
88
86
 
@@ -94,6 +92,36 @@ pnpm test:ui # playwright — requires pnpm build first
94
92
  Test fixtures live in `packages/ui/test/fixtures/` — isolated directories with pre-canned `.sail/`
95
93
  state; no real RPC needed.
96
94
 
95
+ ## RPC configuration
96
+
97
+ RPC URLs are resolved by `packages/cli/src/lib/chain.ts` `getRpcUrl(chainId)` in this order (first match wins):
98
+
99
+ 1. `.sail/.env.local` — chain-specific var (e.g. `BASE_RPC_URL`, `ARBITRUM_RPC_URL`)
100
+ 2. `.sail/.env.local` — generic `RPC_URL`
101
+ 3. Shell environment — chain-specific var
102
+ 4. Shell environment — generic `RPC_URL`
103
+
104
+ Two valid patterns for `.sail/.env.local`:
105
+
106
+ ```
107
+ # Option A — single active chain
108
+ RPC_URL=https://your-base-endpoint
109
+ CHAIN_ID=8453
110
+ ```
111
+
112
+ ```
113
+ # Option B — per-chain (multi-chain projects; omit RPC_URL if all chains have a specific var)
114
+ CHAIN_ID=8453
115
+ BASE_RPC_URL=https://your-base-endpoint
116
+ ARBITRUM_RPC_URL=https://your-arbitrum-endpoint
117
+ UNICHAIN_RPC_URL=https://your-unichain-endpoint
118
+ ETH_MAINNET_RPC_URL=https://your-mainnet-endpoint
119
+ BASE_SEPOLIA_RPC_URL=https://your-base-sepolia-endpoint
120
+ SEPOLIA_RPC_URL=https://your-sepolia-endpoint
121
+ ```
122
+
123
+ Per-chain vars always take precedence for their specific chain, so multi-chain projects resolve each endpoint correctly. `sailor chains --verify` uses this to check every chain that has a configured RPC.
124
+
97
125
  ## Conventions
98
126
 
99
127
  - `SAIL_DIR` — env var pointing to the project's `.sail/` directory (used by the UI server)
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Sailor
2
2
 
3
- > A toolkit for building and operating Sail Protocol SMAs with AI agents.
3
+ > The operator toolkit for Sail Protocol — SDK, CLI, and local dashboard for building and running mandated agents.
4
4
 
5
- Sailor is the operator layer for [Sail Protocol](../SailProtocol): the tooling an agent builder uses to create a Separately Managed Account, bound it with permissions, and run a strategy against it. It wraps the on-chain primitives — SailKernel dispatch, MandateFactory registration, EIP-712 mandate signing behind a TypeScript SDK, a CLI, and a local dashboard. An agent is an async function that receives context and returns intended transactions; Sailor previews each through the kernel, executes the approved ones, and records what happened. It does not deploy the protocol or author new permission templates — that lives in Sail Protocol. It sits one level up: turning a deployed SailKernel into something an operator can actually drive.
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
6
 
7
7
  ---
8
8
 
@@ -10,39 +10,60 @@ Sailor is the operator layer for [Sail Protocol](../SailProtocol): the tooling a
10
10
 
11
11
  | Package | Name | Role |
12
12
  |---|---|---|
13
- | `packages/sdk` | `@sail/sdk` | TypeScript library wrapping SailKernel and MandateFactory |
14
- | `packages/cli` | `sailor` | CLI for account setup, mandate signing, and agent execution |
15
- | `packages/chains` | `@sail/chains` | Per-chain address registry (EVM-compatible) |
16
- | `packages/ui` | `sailor-ui` | Local dashboard running on localhost:3333 |
17
- | `templates/dca-rebalancer` | — | Starter template: DCA portfolio rebalancer (default for `sailor init`) |
18
- | `templates/custom-mandate` | — | Solidity reference: allowlist mandate contracts (not a project template) |
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 running at localhost:3333 |
16
+ | `templates/default` | | Default agent starter (neutral; what `sailor init` scaffolds) |
17
+ | `templates/custom-mandate` | — | Solidity reference: IPermission scaffold (not a project template) |
19
18
  | `templates/lifi-permissions` | — | Solidity reference: LiFi clone permission contracts (not a project template) |
20
19
 
21
20
  ---
22
21
 
23
- ## How it works
24
-
25
- The path from nothing to a running agent is seven steps:
22
+ ## Protocol model
23
+
24
+ ```mermaid
25
+ flowchart TD
26
+ Owner["**Owner**<br/>holds the Safe · signs the mandate"]
27
+ Manager["**Manager**<br/>agent · signs dispatches"]
28
+ SMA["**SMA**<br/>Safe · holds assets · executes"]
29
+ Mandate["**Mandate**<br/>set of permission contracts"]
30
+ Kernel["**Sail Kernel**<br/>evaluates permission · trusted core<br/>dispatches to Safe on success"]
31
+
32
+ Owner -- "01 deploys & owns" --> SMA
33
+ Owner -- "02 signs mandate (EIP-712)" --> Mandate
34
+ Owner -- "03 appoints · instant revocation" --> Manager
35
+ Manager -- "04 signs dispatch (EIP-712)" --> Kernel
36
+ Mandate -- "05 defines bounds" --> Kernel
37
+ Kernel -- "06 ✓ executes · ✗ outside mandate: reverts" --> SMA
38
+ ```
26
39
 
27
- 1. **Generate keys** a manager key (the agent's dispatch signer) and a permissionSigner key, both generated and encrypted on disk.
28
- 2. **Deploy SMA** — a Safe registered with SailKernel, with the manager and permissionSigner addresses set at registration.
29
- 3. **Write a strategy** — an async `tick` function that receives a context and returns a list of intended dispatches.
30
- 4. **Sign a mandate** — a set of registered permissions that bound what the agent can do, authorized via EIP-712 by the permission signer through MetaMask or a local key.
31
- 5. **Dry-run** — the kernel's `previewBatch` confirms the named permission passes before anything executes on-chain.
32
- 6. **Run the agent** — locally on a cron schedule, or via GitHub Actions on a timer.
33
- 7. **Monitor** — the local dashboard on localhost:3333 reflects live mandate state, agent status, and activity.
40
+ Sailor is the operator tooling that drives the Manager/dispatch and mandate-registration flows (steps 02–05).
34
41
 
35
42
  ---
36
43
 
37
44
  ## Roles
38
45
 
39
- Sailor operates the three roles Sail Protocol separates:
46
+ Sail Protocol separates three authority roles. Sailor operates all of them:
40
47
 
41
48
  | Role | Authority | Held by |
42
49
  |---|---|---|
43
- | **Owner** | Holds the Safe. Custody anchor. | The LP (Safe owner) — same wallet as MetaMask |
44
- | **Permission Signer** | Signs mandate registration and revocation via EIP-712. | Same as Owner, or a separate key |
45
- | **Manager** | Executes dispatches within permitted bounds. Signs each dispatch. | The agent key — encrypted in `.sail/keys/manager.json` |
50
+ | **Owner** | Holds the Safe. Custody anchor. Always self-custodial. | The LP (Safe owner) |
51
+ | **Permission Signer** | Authorizes the mandate. Signs registration and revocation via EIP-712. | Same as Owner, or a separate signing key |
52
+ | **Manager** | Executes dispatches within mandate bounds. Signs each dispatch. | The agent wallet — encrypted in `.sail/keys/manager.json` |
53
+
54
+ ---
55
+
56
+ ## How it works
57
+
58
+ The path from nothing to a running agent follows the protocol lifecycle:
59
+
60
+ 1. **Deploy your SMA** — `sailor onboard --new-sma` creates the SMA on-chain. `sailor account predict` computes the deterministic address in advance. The same owner, permission signer, manager, and salt produce the same SMA address on every supported chain.
61
+ 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.
62
+ 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.
63
+ 4. **Run** — `sailor run` executes the agent locally on a schedule, or via the GitHub Actions workflow the scaffold provides.
64
+ 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.
65
+
66
+ Run `npx sailor init my-agent`, open the scaffolded folder in Claude Code, Cursor, or any AI coding assistant, and say **"start"**. The `AGENTS.md` in the project guides the assistant through all five stages.
46
67
 
47
68
  ---
48
69
 
@@ -50,13 +71,24 @@ Sailor operates the three roles Sail Protocol separates:
50
71
 
51
72
  ### Start a new agent project (recommended)
52
73
 
53
- Open your AI coding assistant and run in its terminal:
74
+ Create a folder, step into it, then install and init:
54
75
 
55
- ```sh
56
- npx sailor init my-agent
76
+ ```bash
77
+ # bash / zsh / macOS
78
+ mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init
79
+ ```
80
+
81
+ ```powershell
82
+ # PowerShell (Windows)
83
+ mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init
57
84
  ```
58
85
 
59
- Then say **"start"** your assistant takes it from there.
86
+ Then open the folder in your AI coding assistant and say **"start"**.
87
+
88
+ > **npx shortcut** — skips the explicit install; npm downloads sailor on the fly:
89
+ > ```sh
90
+ > mkdir my-agent && cd my-agent && npx sailor init
91
+ > ```
60
92
 
61
93
  ### Global CLI (for direct sailor commands)
62
94
 
@@ -71,30 +103,53 @@ sailor init my-agent
71
103
 
72
104
  Prerequisites:
73
105
 
74
- - Node.js 18+ (the CLI runs on 18; `pnpm install` needs Node 22+)
75
- - A wallet (MetaMask or Rabby)
106
+ - Node.js 18+
107
+ - A wallet (MetaMask, Rabby, Phantom, and more)
76
108
  - An RPC URL (e.g. Alchemy free tier)
77
- - A supported chain: **Base, Base Sepolia, Arbitrum, or Unichain** — these use the verified deployments bundled in `@sail/sdk`, so no `@sail/chains` entry is needed. Other chains require kernel + mandateFactory addresses in `@sail/chains` (see [State of the project](#state-of-the-project)).
109
+ - A supported chain: **Ethereum, Base, Arbitrum, Unichain, Base Sepolia, or Eth Sepolia** — verified deployments are bundled in `@sail.money/sailor`.
110
+
111
+ ### Recommended — assistant-driven
78
112
 
79
113
  ```bash
80
- npx sailor init my-agent && cd my-agent
81
- npm install # or `pnpm install` (needs Node 22+)
114
+ # bash / zsh / macOS
115
+ mkdir my-agent && cd my-agent && npm i @sail.money/sailor && npx sailor init && npm install
116
+ ```
82
117
 
83
- # 1. Ground yourself — read-only, no gas, no wallet:
84
- sailor capabilities # what you can build on this chain
85
- sailor doctor # kernel model + RPC reachability + gas balances
118
+ ```powershell
119
+ # PowerShell (Windows)
120
+ mkdir my-agent ; cd my-agent ; npm i @sail.money/sailor ; npx sailor init ; npm install
121
+ ```
122
+
123
+ Open this folder in Claude Code, Cursor, Codex, or any AI coding assistant and say **"start"**. The scaffolded `AGENTS.md` guides the assistant through all five stages — SMA deployment, strategy definition, mandate authoring, running, and automation. No manual steps required.
86
124
 
87
- # 2. Set up the account in the browser wizard (choose chain, connect wallet,
88
- # generate the agent key, deploy your SMA):
89
- sailor ui start # open http://localhost:3333 and follow steps 1–4
125
+ ### Direct CLI reference
90
126
 
91
- # 3. Back in the terminal: configure .sail/.env.local, fund the agent key for gas,
92
- sailor mandate prepare # draft permissions → approve in the browser
93
- sailor run # start the agent (use --once for a single tick)
127
+ ```bash
128
+ # Discovery
129
+ sailor chains # list supported chains and kernel addresses
130
+ sailor capabilities # what you can build on this chain — read-only, no gas
131
+ sailor doctor # kernel model + RPC reachability + gas balances
132
+
133
+ # SMA setup
134
+ sailor account predict # compute deterministic SMA address before deploying
135
+ sailor onboard --new-sma # deploy SMA and optionally attach a mandate
136
+
137
+ # Mandate lifecycle
138
+ sailor mandate simulate # probe a permission off-chain (no gas) before registering
139
+ sailor mandate sign # sign the mandate — reconciles against live on-chain state
140
+ sailor mandate deploy # deploy a Foundry-compiled permission contract
141
+ sailor mandate attach # register an already-deployed permission on an SMA
142
+
143
+ # Agent operation
144
+ sailor run --once # single tick — confirm it works before automating
145
+ sailor run # start the agent (continuous)
146
+ sailor keys export-ci # copy encrypted agent wallet to ci-keystore.json for CI
147
+
148
+ # Dashboard
149
+ sailor ui start # open http://localhost:3333
94
150
  ```
95
151
 
96
- The SMA is deployed through the browser wizard (it submits from your wallet), not a
97
- terminal command — see the scaffolded project's `AGENTS.md` for the full 8-step flow.
152
+ `sailor run` writes reverted transactions to stderr as `reverted: <txHash> (gas used: N)`; successful dispatches are appended to `.sail/activity.jsonl`.
98
153
 
99
154
  ---
100
155
 
@@ -106,7 +161,7 @@ writes into the **current directory**; pass a name to create a subdirectory.
106
161
  ```bash
107
162
  sailor init # scaffold into cwd
108
163
  sailor init my-agent # create ./my-agent/ and scaffold there
109
- sailor init --template dca-rebalancer # explicit (same as default)
164
+ sailor init --template default # explicit (same as default)
110
165
  sailor init my-agent --template <name> # named subdirectory + specific template
111
166
  ```
112
167
 
@@ -114,7 +169,7 @@ sailor init my-agent --template <name> # named subdirectory + specific templat
114
169
 
115
170
  | Template | Description |
116
171
  |---|---|
117
- | `dca-rebalancer` | Dollar-cost-averaging portfolio rebalancer. Includes a full agent loop, Foundry workspace for permission contracts, GitHub Actions cron job, and the operator guide (`AGENTS.md`). **Default.** |
172
+ | `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.** |
118
173
 
119
174
  ### What makes a valid template
120
175
 
@@ -182,20 +237,19 @@ sailor ui stop
182
237
 
183
238
  ## Agent-driven onboarding & custom mandates
184
239
 
185
- For chains with a bundled Sail deployment (Base, Base Sepolia, Arbitrum, Unichain shipped
186
- in `@sail/sdk`, no `@sail/chains` entry required), an agent can drive the whole
187
- setup through a browser **signing station**. The station is a local HTTP +
188
- WebSocket daemon that bridges the CLI and the owner's wallet: the agent never
189
- holds the owner key — it pushes signing requests, the owner approves them in the
190
- browser, and the agent submits the transactions it's allowed to.
240
+ On any of the six supported chains, an agent can drive the whole setup through
241
+ a browser **signing station**. The station is a local HTTP + WebSocket daemon
242
+ that bridges the CLI and the owner's wallet: the agent never holds the owner
243
+ key it pushes signing requests, the owner approves them in the browser, and
244
+ the agent submits the transactions it's allowed to.
191
245
 
192
246
  ```bash
193
- sailor keys generate # manager (agent) key
194
- sailor station start & # signing daemon (serves the UI)
247
+ sailor keys generate # create the manager (agent) key
248
+ sailor station start & # signing daemon (serves the UI)
195
249
  # owner opens the printed URL once and connects their wallet
196
- sailor owner connect # detect & persist the owner
197
- sailor scan # discover the owner's Safes + state
198
- sailor onboard --new-sma # create an SMA + (optionally) attach a mandate
250
+ sailor owner connect # detect & persist the owner
251
+ sailor scan # discover the owner's Safes + state
252
+ sailor onboard --new-sma # create an SMA + (optionally) attach a mandate
199
253
  ```
200
254
 
201
255
  Agents author their own permission contracts and deploy them from the scaffolded
@@ -217,35 +271,98 @@ a `RegisterPermission` EIP-712 message, then the agent submits
217
271
  `--json` for headless agent use; set `SAIL_PASSPHRASE` to unlock the manager key
218
272
  non-interactively.
219
273
 
274
+ `sailor mandate sign` reconciles against the live on-chain `getPermissions()` call
275
+ before building the mandate payload — permissions revoked on-chain are excluded even
276
+ if they remain in the local `.sail/state/mandates.json` (which is an append-only
277
+ historical record and is never modified by the reconciliation).
278
+
279
+ ### GitHub Actions CI
280
+
281
+ The scaffolded `.github/workflows/agent-tick.yml` runs `sailor run --once` on a
282
+ cron schedule using `npm ci` (no pnpm required). Setup:
283
+
284
+ 1. `sailor keys export-ci` — copies the encrypted agent wallet to `ci-keystore.json`
285
+ in the project root and allowlists it in `.gitignore`. The geth v3 keystore is
286
+ safe to commit; the raw private key is never exposed.
287
+ 2. Commit `ci-keystore.json`, `.sail/account.json`, and `.sail/mandate.json`.
288
+ 3. Add two repository secrets (Settings → Secrets → Actions):
289
+ - `SAIL_PASSPHRASE` — the passphrase that encrypts the agent wallet
290
+ - `RPC_URL` — your RPC endpoint
291
+
292
+ The workflow copies `ci-keystore.json` to `.sail/keys/manager.json`, then calls
293
+ `npx sailor run --once` with `SAIL_PASSPHRASE` set so the key is unlocked
294
+ non-interactively. No private key ever appears in the workflow file or in secrets.
295
+
220
296
  ---
221
297
 
222
- ## Architecture
298
+ ## Packages
299
+
300
+ Sailor ships as a **single npm package** — the SDK is bundled inside it and exposed via a subpath export:
301
+
302
+ | Package | Contents |
303
+ |---|---|
304
+ | `@sail.money/sailor` | CLI binary, UI server, templates, examples, and SDK |
305
+
306
+ The SDK is available as a subpath export for use in agent code:
307
+
308
+ ```ts
309
+ import type { Agent, AgentContext, Dispatch } from '@sail.money/sailor/sdk'
310
+ ```
311
+
312
+ The SDK is also published separately as `@sail.money/sdk` for projects that consume it independently of the CLI.
313
+
314
+ ### npm (`publish-npm.yml`)
315
+
316
+ Published to the public npm registry under the `@sail.money` scope.
223
317
 
318
+ | Trigger | Package | Version | dist-tag |
319
+ |---|---|---|---|
320
+ | Tag push (`v*`) | `@sail.money/sailor` | `0.1.0` | `latest` |
321
+ | Manual dispatch | `@dev.sail.money/sailor` | `0.1.0-42` | `dev` |
322
+
323
+ ```bash
324
+ npm install @sail.money/sailor # latest stable (tag push)
325
+ ```
326
+
327
+ For dev builds, the package name changes scope to `@dev.sail.money`. Use an alias so your import paths stay the same:
328
+
329
+ ```bash
330
+ npm install "@sail.money/sailor@npm:@dev.sail.money/sailor@dev"
331
+ ```
332
+
333
+ This installs the latest dev build and makes it available as `@sail.money/sailor` locally — `@sail.money/sailor/sdk` imports continue to work unchanged.
334
+
335
+ ### GitHub Packages (`publish.yml`)
336
+
337
+ Published to GitHub Packages under the `@sail-money` scope for internal testing — no public npm registry required.
338
+
339
+ | Trigger | Package | dist-tag |
340
+ |---|---|---|
341
+ | Merge to `main` | `@sail-money/sailor` | `latest` |
342
+ | Manual dispatch | `@sail-money/sailor-dev` | `dev` |
343
+
344
+ Both builds require an alias since the package scope differs from `@sail.money`:
345
+
346
+ ```bash
347
+ npm install "@sail.money/sailor@npm:@sail-money/sailor@latest" --registry https://npm.pkg.github.com
348
+ npm install "@sail.money/sailor@npm:@sail-money/sailor-dev@dev" --registry https://npm.pkg.github.com
349
+ ```
350
+
351
+ Or pin in `package.json`:
352
+
353
+ ```json
354
+ "dependencies": {
355
+ "@sail.money/sailor": "npm:@sail-money/sailor@latest"
356
+ }
224
357
  ```
225
- ┌────────────────────┐ ┌────────────────────┐
226
- │ Permission Signer │ │ Manager/Agent │
227
- │ MetaMask / local │ │ .sail/keys/manager │
228
- └─────────┬──────────┘ └─────────┬──────────┘
229
- │ │
230
- │ EIP-712 mandate │ dispatch
231
- ▼ ▼
232
- ┌─────────────────────────────────────────────────────────────────────┐
233
- │ SailKernel │
234
- │ (Sail Protocol) │
235
- └─────────┬───────────────────────┬───────────────────────┬───────────┘
236
- │ │ │
237
- │ registration │ execution │ evaluation
238
- ▼ ▼ ▼
239
- ┌────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
240
- │ MandateFactory │ │ Safe │ │ Permissions │
241
- │ (register perms) │ │ (custody) │ │ (named, per-call) │
242
- └────────────────────┘ └────────────────────┘ └────────────────────┘
243
-
244
- sailor CLI / @sail/sdk drive both signing paths above.
245
- .sail/ (account · mandate · activity) ──→ sailor-ui (localhost:3333)
358
+
359
+ ```json
360
+ "dependencies": {
361
+ "@sail.money/sailor": "npm:@sail-money/sailor-dev@dev"
362
+ }
246
363
  ```
247
364
 
248
- The CLI and SDK sit between the operator and SailKernel: they build the EIP-712 payloads, submit dispatches, and read kernel state via viem. The permission signer authorizes the mandate — registration runs through MandateFactory — while the manager key signs each dispatch the kernel evaluates against a named permission before executing it through the Safe. All local state — the deployed account, the signed mandate, and the agent's activity log — lives under `.sail/` on disk, which the dashboard reads through a small local server. Sailor never holds the Owner key and runs no hosted backend; the wallet talks to the chain directly.
365
+ Either way, `@sail.money/sailor/sdk` imports work unchanged.
249
366
 
250
367
  ---
251
368
 
@@ -255,74 +372,48 @@ The CLI and SDK sit between the operator and SailKernel: they build the EIP-712
255
372
  - The Owner key controls the Safe and is never read by Sailor. Mandate signing requires a deliberate action by the permission signer.
256
373
  - The manager key is encrypted on disk using geth keystore v3 (scrypt + aes-128-ctr) and is never transmitted.
257
374
  - The session can be paused instantly via `sailor session pause` or the dashboard stop button; this does not affect Safe custody.
375
+ - All addresses passed to the CLI are normalized with `getAddress()` (EIP-55 checksum). Mixed-case or lowercase inputs are accepted and canonicalized before any on-chain call or state write.
258
376
 
259
377
  ---
260
378
 
261
379
  ## State of the project
262
380
 
263
- Sailor is functional and published as [`@sail.money/sailor`](https://www.npmjs.com/package/@sail.money/sailor) on npm (v0.0.1). The SDK, CLI, keystore, mandate flows, agent runner, and dashboard are implemented and have been exercised end to end against Base Sepolia.
381
+ Sailor is functional and published as [`@sail.money/sailor`](https://www.npmjs.com/package/@sail.money/sailor) on npm (v0.1.0). The SDK, CLI, keystore, mandate flows, agent runner, and dashboard are implemented and have been exercised end to end.
382
+
383
+ 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.
264
384
 
265
- The Sail Protocol trusted core is deployed on Base, Base Sepolia, Arbitrum, and Unichain as staging deployments for testing ahead of a formal launch. All four run the selective dispatch model, with verified deployments bundled in `@sail/sdk`. 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. Permission templates are not yet deployed against the Base, Arbitrum, and Base Sepolia kernels; **Unichain** ships the full template suite (7 shared + 12 standalone, source-verified) and its template registries in `@sail/sdk` are populated. `@sail/chains` and the remaining template registries will be filled in as templates are deployed on the other chains and at mainnet launch.
385
+ 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.
266
386
 
267
387
  ---
268
388
 
269
389
  ## Deployments
270
390
 
271
- The Sail Protocol trusted core is live on the following chains as **staging deployments** ahead of a formal launch, bundled in `@sail/sdk`. All run the selective dispatch model with zero fees. Permission templates are not yet deployed against the Base, Arbitrum, and Base Sepolia kernels; **Unichain** ships the full template suite (7 shared + 12 standalone, source-verified on uniscan.xyz) and has its onboarding allowlists seeded at genesis.
391
+ All core contracts are deployed at the same address on every supported chain via CREATE2 (commit `1199b33`, 2026-06-09). An SMA created with the same owner, permission signer, manager, fee policy, and salt has the same address on every supported chain.
272
392
 
273
- ### Base (8453)
393
+ ### Core addresses (identical on all 6 chains)
274
394
 
275
395
  | Contract | Address |
276
396
  |---|---|
277
- | SailKernel | `0x6319d3dfDDe3804ba93D65752b00c52bFb05a1ab` |
278
- | SailGovernance | `0x7E897D919872b1587577617ffFC42113679d0C50` |
279
- | Timelock | `0x8eC3Ca951E193C6E3713A70022454d7A1f083281` |
280
- | PermissionFactory | `0x7724EACd97C8601d5AC244Aadbf76ad87353Ff31` |
281
- | StandardFeePolicy | `0x65850a8D5050aeAade68289ff96c4F119a24B82e` |
282
- | SafeModuleEnabler | `0xC84EdE78f93291A1fab19F51c4c7e938AB302Edf` |
397
+ | SailKernel | `0x02ABC18B65A328de2e749F56ba79ACF2718a6659` |
398
+ | SailGovernance | `0x7A478118715791728BDE3bc7A4D7ECfdEB89C6EC` |
399
+ | TimelockController | `0xE48Ba8DB6d748adafD13155c3590f62e58a77f56` |
400
+ | MandateFactory | `0x14EDd6c2a56EfC0d71E215ab13094B9AF90543d2` |
401
+ | StandardFeePolicy | `0xe7B5901b839cFFDEd9D4108A22712C8BfdA1D80D` |
402
+ | SafeModuleEnabler | `0x7897Cb53a4be4a2eaAf46D60573C4Fd83b33fE1F` |
283
403
  | Treasury | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
284
404
 
285
- ### Arbitrum (42161)
405
+ 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).
286
406
 
287
- | Contract | Address |
288
- |---|---|
289
- | SailKernel | `0x2716B12832DED0EF5688519c5Fe069EFc0374E02` |
290
- | SailGovernance | `0xd6AbB7A1036ADc7958Abffec9Da03450c5a2Ec8e` |
291
- | Timelock | `0x114CB7110C780f7E3a6093AfE0B52463a569857C` |
292
- | PermissionFactory | `0x23681A8A4C9819D8EaB37E46B858da6F3c85E683` |
293
- | StandardFeePolicy | `0xAdfB986D48480bC67a7cF3751d30599161632e0D` |
294
- | SafeModuleEnabler | `0xabe2a6D03F592BC602cA1dBDCD885ba2493274f9` |
295
- | Treasury | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
296
-
297
- ### Base Sepolia (84532)
407
+ ### Supported chains
298
408
 
299
- | Contract | Address |
409
+ | Chain | Chain ID |
300
410
  |---|---|
301
- | SailKernel | `0xf1D0F4C9893612627409948BAa9d82a01a373799` |
302
- | SailGovernance | `0xEaD44bC6999E7b00b9b2E11c1660248DC2a30993` |
303
- | Timelock | `0x97B863e392C9859336788D5Ec454527d33C95B74` |
304
- | PermissionFactory | `0xdfF6a2272F667cDf78Af4681b9c88A219998db95` |
305
- | StandardFeePolicy | `0x05570F7973b46Eb9Ed4518422891EFC26BD58b97` |
306
- | SafeModuleEnabler | `0xB2C2B52d94412e3472C9fb2B52186eA12a935869` |
307
- | Treasury | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
308
-
309
- ### Unichain (130)
310
-
311
- First chain to ship the full permission-template suite (7 shared + 12 standalone, source-verified on [uniscan.xyz](https://uniscan.xyz)). Genesis allowlist bootstrap — onboarding usable without the 48h timelock.
312
-
313
- | Contract | Address |
314
- |---|---|
315
- | SailKernel | `0xD985029960a9B7C2E7E38e102C448b8b8539B156` |
316
- | SailGovernance | `0xAb5C90ECfF2763f6f20f8E553E3b8778dD9C349A` |
317
- | Timelock | `0xd44FbBB37f01e235E0EE5386948F216d36D0CEf2` |
318
- | PermissionFactory | `0x8edDb62Aa49CeB837abf2653be2d93Ad9Fe6777D` |
319
- | StandardFeePolicy | `0x7bBA8BE3c01c972757aA4a230A00D58aB600A1F1` |
320
- | SafeModuleEnabler | `0xFE9227A9F2baf704060c604466df354a5A137b9B` |
321
- | Treasury | `0xB01dCE443d052e44b7D13726c0EC9fFB7f5815B6` |
322
-
323
- The 19 template addresses are in `@sail/sdk` (`knownTemplates` + `standaloneTemplates` for chain 130).
324
-
325
- Addresses are sourced from `@sail/sdk` (`packages/sdk/src/deployments.ts`), the canonical registry.
411
+ | Ethereum | 1 |
412
+ | Base | 8453 |
413
+ | Arbitrum | 42161 |
414
+ | Unichain | 130 |
415
+ | Base Sepolia | 84532 |
416
+ | Eth Sepolia | 11155111 |
326
417
 
327
418
  ---
328
419