@mysten-incubation/sui-agent-pass 0.0.0-stage → 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,201 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
package/README.md CHANGED
@@ -1,3 +1,424 @@
1
- # Temporary Holding Version
1
+ # Sui Agent Pass
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **Your money. Your rules. AI at work.**
4
+
5
+ Sui Agent Pass lets an AI agent run your onchain finance under a policy you write once. The agent
6
+ pays, trades, lends and stakes; Sui checks every transaction against the policy at settlement.
7
+ A policy is more than a spending limit: it names who the agent can pay, which markets it can
8
+ trade on and at what price, how much lending risk it can take, which validators it can stake
9
+ with, and how long its access lasts. Each new protocol plugs in as a new policy module.
10
+
11
+ An owner authorizes a new agent key with Slush. The agent builds its own programmable
12
+ transactions, a local MCP signer holds the agent key on the owner's machine and signs complete
13
+ transaction bytes, and the chain decides what executes. No hosted service ever holds a key.
14
+
15
+ One pass per agent, and the agent never owns anything:
16
+
17
+ - **Your coins stay in your own address.** Setup issues two allowances (`sui::allowance`) bound
18
+ to the pass, one per coin. Every agent action draws from your address balance through an
19
+ allowance, is checked by the pass's policies, and returns its proceeds to your address. The
20
+ pass never holds a coin.
21
+ - **The pass holds the rules and the objects the agent operates.** A NAVI lending position is
22
+ an object that can only be used under its owner's signature, so it sits in the pass where the
23
+ agent can run it. Only you can take it out, and taking it out hands you the position directly.
24
+ - **A receipt in your wallet points at each pass**, so from any device you can find your passes,
25
+ read their positions, and reclaim them. Authority stays with your address, never the receipt.
26
+
27
+ The pass is an account, not a typed container: each action names its coin. The owner installs
28
+ one policy per kind of action and coin. Transfers go to recipients the owner named; the agent
29
+ never supplies an address. Swaps run on the DeepBook and Cetus pools the owner listed, within
30
+ per-trade and daily caps and above a price floor. Lending supplies collateral to NAVI and, if
31
+ enabled, borrows against it while keeping the health factor above the owner's floor. Staking
32
+ puts SUI with the validators the owner listed (or any active one), within per-stake and daily
33
+ caps; the stake object stays in the pass and unstaking returns the SUI to the owner. An action
34
+ with no policy for its coin is refused. Revocation ends the agent's term and deletes the
35
+ allowances. The package references `sui::allowance`, so it needs protocol 137 or later, which
36
+ testnet, devnet and mainnet all run. The demo stays on localnet, testnet and devnet; mainnet
37
+ serves compatibility tests with small sums until launch.
38
+
39
+ The agent pays its own gas from the session address. Setup seeds an initial gas stipend and issues
40
+ a separate small SUI allowance for gas; when the session's balance runs low the agent tops it up
41
+ from that allowance, within its own lifetime cap and daily window, so gas spend is bounded apart
42
+ from the asset rules. Owners cannot bill an agent's transaction gas to the wallet directly yet,
43
+ because gas is authorized by a signature and `sui::allowance` cannot authorize it.
44
+
45
+ Transfers and staking are the real thing on every network. DeepBook, Cetus and NAVI are called
46
+ through their mainnet interfaces; off mainnet the demo publishes local stand-ins with the same
47
+ signatures over small mock markets, and the Move manifest lists the real packages as mainnet
48
+ replacements. See `move/protocols/README.md`.
49
+
50
+ This repository is fully self-contained. There is no broker, authorization database,
51
+ intent adapter, or transaction builder inside MCP.
52
+
53
+ ## Install (planned distribution)
54
+
55
+ Not published yet. Once the package is on npm and the immutable contracts are published on chain,
56
+ a user needs no clone, no build, and no toolchain. The client ships the per-network deployment IDs
57
+ (`deployments/<network>.json`) and resolves them with `--network`:
58
+
59
+ ```sh
60
+ npm install -g @mysten-incubation/sui-agent-pass
61
+ agent-pass connect # pick the agents on this machine; nothing stays running
62
+ ```
63
+
64
+ That is the only command. Then open the agent and tell it what to do with your money. It
65
+ proposes a pass (`propose_authorization`) and opens the review page with the proposal in its URL.
66
+ Connect a wallet, check the rules the agent quoted to you, and sign once; the session key stays
67
+ local, and the agent sees your signature land on chain and acts within the rules. Claude Code
68
+ starts the signer when it needs it. In production the page is our site at a fixed origin, so the
69
+ agent cannot change what you see or sign; in development the same build is served from the local
70
+ port (see "The site" in `docs/ARCHITECTURE.md`). There is no setup wizard: the agent composes
71
+ the rules from your words and the facts the server gives it (coins, pools, balances, quotes), and
72
+ the review page is where you check them. For a private publish:
73
+
74
+ ```sh
75
+ agent-pass connect # asks which agents; or --client <name>
76
+ ```
77
+
78
+ Publishing the Move package and installing the Sui toolchain are maintainer steps, never on a
79
+ user's machine. See the release checklist below.
80
+
81
+ ## Use it with your agent
82
+
83
+ The signer speaks MCP, so any agent that can load an MCP server can use it. The protocol is
84
+ the same for every client; where each one keeps its server list is not, so `connect --client`
85
+ writes or prints the entry in the right place:
86
+
87
+ | `--client` | What it does |
88
+ | ---------------- | ---------------------------------------------------------------------- |
89
+ | `claude-code` | `claude mcp add` in user scope |
90
+ | `claude-desktop` | Writes into `claude_desktop_config.json` |
91
+ | `cursor` | Writes into `~/.cursor/mcp.json` |
92
+ | `hermes` | Prints the `mcp_servers` block for `~/.hermes/config.yaml` |
93
+ | `codex` | Prints the `[mcp_servers.agent-pass]` block for `~/.codex/config.toml` |
94
+ | `json` | Prints a generic `mcpServers` entry |
95
+
96
+ The entry is `agent-pass mcp`, a stdio server the client starts when it needs it and stops with
97
+ it. It covers every pass on this machine, exposes `session_info` and `sign_transaction`, and
98
+ adds the owner tools (`list_passes`, `propose_authorization`, `revoke_pass`), so the agent can
99
+ also set a pass up. While it runs it also serves each pass's HTTP signer, which the SDK uses.
100
+ `connect --session <directory>` instead points a client at one session's foreground signer
101
+ (`agent-pass serve`), for agents that cannot start a process themselves.
102
+
103
+ Acting is a Node script against the SDK. `session_info.sdk.install` is the install command
104
+ (`npm install <this checkout>` after `npm run build` while the package is unpublished), then:
105
+
106
+ ```ts
107
+ import { Agent, pickValidator, send, stake, swap } from '@mysten-incubation/sui-agent-pass/agent';
108
+ import { SUI, units } from '@mysten-incubation/sui-agent-pass/domain';
109
+
110
+ const agent = await Agent.open(directory); // from session_info
111
+ const usdc = agent.identity.deployment.coins.find((c) => c.symbol === 'USDC')!;
112
+ const out = await agent.submit(
113
+ swap(agent.identity, { coinIn: SUI, coinOut: usdc.type }, units('0.01', 9), units('0.019', 6)),
114
+ );
115
+ // out.success, out.reason (the owner's rule on a refusal), out.balanceChanges
116
+ ```
117
+
118
+ `submit` signs through the session signer, submits to Sui and returns the persisted outcome; it
119
+ throws when nothing executed, so a dry-run refusal is never mistaken for enforcement.
120
+ [docs/AGENT.md](docs/AGENT.md) documents the SDK and the contract for hand-built PTBs. Agents
121
+ that do not speak MCP get the same two operations as plain HTTP with the bearer from
122
+ `mcp.token`: `GET /v1/session` and `POST /v1/sign` with `{ "transactionBytes": "<base64>" }`.
123
+
124
+ ## Run the rehearsal
125
+
126
+ Clone the repository with your authorized GitHub account:
127
+
128
+ ```sh
129
+ gh repo clone MystenLabs/sui-agent-pass ~/github/sui-agent-pass
130
+ ```
131
+
132
+ Requires Node 22+, npm, and Sui 1.81.1 (`mainnet-v1.81.1`, the release mainnet runs; `npm run
133
+ toolchain` installs it with `mvr`). The project checks `SUI_BIN`, then
134
+ `~/.cache/sui-agent-pass/toolchain/sui`, then `sui` on PATH. Older installations are not used if
135
+ the project toolchain is present. The single Move package references `sui::allowance`, so it
136
+ builds and publishes only with a chain that has it enabled: localnet from this toolchain,
137
+ testnet, devnet, or mainnet (protocol 138).
138
+
139
+ ```sh
140
+ cd ~/github/sui-agent-vault
141
+ npm ci
142
+ npm run toolchain
143
+ npm run build
144
+ npm run demo
145
+ ```
146
+
147
+ The command starts its own fresh local Sui network, publishes immutable demo contracts,
148
+ creates separate owner/publisher/session identities, authorizes the session, starts MCP,
149
+ and prints an owner dashboard URL and Claude connection command. It keeps the chain and
150
+ signer alive until `quit` or Ctrl-C. Keys stay in ignored private directories.
151
+
152
+ Commands in the rehearsal: `status`, `send` (5 USDC to the recipient named `owner`), `swap`
153
+ (0.01 SUI on DeepBook), `cetus` (0.01 SUI on Cetus), `supply` (0.2 SUI to NAVI), `borrow`
154
+ (0.15 USDC from NAVI), `stake` (1 SUI with the localnet validator), `unstake` (the held
155
+ stake, back to the owner), `over` (11 USDC against a 10 per-transfer limit), `revoke`, `quit`.
156
+ `npm run demo -- --smoke` runs the sequence automatically and exits. After revocation the
157
+ allowance objects no longer exist, so a transaction that names one is refused before execution
158
+ rather than recorded as a chain failure.
159
+
160
+ **The default rehearsal uses a generated test owner, not Slush.** It proves chain execution
161
+ and MCP signing. For the wallet connection/signature flow use the flow below.
162
+
163
+ ## Slush + Claude Code
164
+
165
+ Use a deployed configuration, or `npm run devnet -- --owner <address>`, which publishes to
166
+ devnet with a faucet-funded publisher, funds your wallet address from the faucet and writes the
167
+ deployment to `~/.sui-agent-pass/deployment.json` for the Claude Code plugin. Slush offers
168
+ mainnet, testnet and devnet only. `npm run demo -- --wallet` keeps a localnet alive and prints a
169
+ funded throwaway owner key for a wallet that accepts a custom RPC URL; not verified with any.
170
+
171
+ ```sh
172
+ # Prepare valueless testnet contracts using a separate deployment identity (testnet is the
173
+ # default network):
174
+ npm run deploy -- create --directory .local/testnet
175
+ # If the faucet cannot provide enough funds, the command prints the deployment address.
176
+ # Fund it with at least 11 test SUI, then:
177
+ npm run deploy -- resume --directory .local/testnet
178
+
179
+ # A private deployment.json replaces the bundled network for new passes:
180
+ node dist/cli.js connect # then ask the agent; it passes deployment: .local/testnet/deployment.json
181
+ # devnet works the same way:
182
+ npm run deploy -- create --network devnet --directory .local/devnet
183
+ ```
184
+
185
+ The agent asks what the pass is for and proposes the rules: recipients with per-transfer and
186
+ daily caps for each coin; for each trade direction the pools, per-trade and daily caps and a
187
+ price floor; for each lent coin per-action and daily caps, whether borrowing is allowed and a
188
+ health-factor floor; the validators it may stake with and per-stake and daily caps (a stake is
189
+ at least 1 SUI, the system's minimum); a lifetime cap per coin and the gas terms. It quotes the
190
+ exact rules text the page will show, generates a key and opens the review page. Connect Slush;
191
+ allowances draw only from your address balance, never from coin objects, so the page reads what
192
+ you hold on both sides and shows how much of your coins the signature converts into that balance
193
+ to cover the caps, with a faucet link if your wallet is short. Gas for your own signature comes
194
+ from either side. Sign. One PTB creates the pass and hands you its receipt, converts the coins,
195
+ issues the allowances over your own balance, installs the policies, opens the pass's NAVI
196
+ account when lending is allowed, and sends SUI to the session's **address balance** for gas. The
197
+ service re-reads everything that landed on chain and compares it with what you reviewed before
198
+ the signer serves the key.
199
+
200
+ Register the agents that may use your passes once with `connect` (it asks which ones it finds on
201
+ the machine). Then start Claude anywhere:
202
+
203
+ ```sh
204
+ claude
205
+ ```
206
+
207
+ The registration is `agent-pass mcp` in Claude Code's user scope, a stdio server Claude starts
208
+ when it needs it. It contains no key and no token. If that MCP name already exists, remove the
209
+ old entry with `claude mcp remove agent-pass` before reconnecting.
210
+
211
+ ```sh
212
+ node dist/cli.js status --session /absolute/session/directory
213
+ node dist/cli.js serve --session /absolute/session/directory # advanced: a foreground HTTP signer
214
+ ```
215
+
216
+ Closing Claude does not revoke the chain session;
217
+ the owner page's **Stop the agent now** button does, and **Close the pass** returns everything.
218
+ Your coins never left your address. If the
219
+ agent opened a NAVI position, **Reclaim NAVI position** on the owner page takes the account cap
220
+ into your wallet: the position is then yours to manage on NAVI directly and the agent has
221
+ nothing to lend on. Each stake the agent opened has a **Reclaim** button of its own, which moves
222
+ that `StakedSui` into your wallet. The pass also provides owner-only policy edits, documented in
223
+ the agent API guide.
224
+
225
+ ## Claude Code plugin
226
+
227
+ The plugin runs the whole owner flow from inside Claude Code. You describe what the agent may
228
+ do; Claude proposes rules; the plugin renders them, opens the review page, and you sign once in
229
+ Slush. After that Claude acts through the same session, with no `connect` step and no second
230
+ terminal.
231
+
232
+ ```sh
233
+ cd ~/github/sui-agent-vault
234
+ npm ci && npm run toolchain && npm run build
235
+ # Publish with a faucet-funded key, fund your Slush address from the faucet, and write
236
+ # ~/.sui-agent-pass/deployment.json:
237
+ npm run devnet -- --owner <your Slush address>
238
+ cd ~/anywhere && claude --plugin-dir ~/github/sui-agent-vault/plugin
239
+ ```
240
+
241
+ Then, in Claude Code:
242
+
243
+ > Manage 1 SUI and 100 USDC for me. Sell at most 0.1 SUI a day on DeepBook, never below
244
+ > 1.8 USDC. You may pay alice (0x…) up to 10 USDC a time and 20 a day. One week.
245
+
246
+ Claude calls `propose_authorization`, prints the rules text the tool returned, and the review
247
+ page opens. Connect Slush, check that the page shows the same rules, sign. Claude waits on
248
+ `session_info` until the pass is confirmed and its policies match, then works within the rules
249
+ with scripts against the SDK (`@mysten-incubation/sui-agent-pass/agent`), or with its own PTBs and
250
+ `sign_transaction`. `/agent-pass:pass-status` shows balances and today's
251
+ usage; `/agent-pass:pass-revoke` reopens the owner page for the revocation signature. The
252
+ guidance Claude follows is [`docs/PLAYBOOK.md`](docs/PLAYBOOK.md), which the MCP serves to every
253
+ client as the `agent-pass://playbook` resource; the plugin skills only point at it.
254
+
255
+ The MCP is `node dist/cli.js mcp`. It keeps sessions under `~/.sui-agent-pass/sessions/` and
256
+ reads `deployment.json` from that directory; Claude can also pass another deployment path to
257
+ `propose_authorization`. The plugin and Claude Code run as the same OS user: the session key
258
+ is not hidden from Claude by the operating system, and the on-chain rules are the boundary.
259
+
260
+ ## The site
261
+
262
+ `npm run build` produces `web-dist/`, one static site that reads the chain directly and needs
263
+ no signer or session. `#/authorize/<proposal>` is the review page `setup` and the plugin open:
264
+ the rules come from the URL, the page builds the authorization against the package IDs it was
265
+ built with, your wallet signs, and the local signer finds the result on chain. Paste a pass id
266
+ or an owner address, or connect a wallet, and see the pass's rules, the owner's balances and
267
+ allowances, what the pass holds, and every transaction the agent sent with the chain's verdict
268
+ and the rule behind each refusal. Owner actions (revoke, reclaim a position or a stake, close
269
+ the pass) are wallet signatures from the same page. Closing deletes the pass, its policies, its
270
+ receipt and any remaining allowances in one transaction and hands back anything it still holds;
271
+ the storage deposits of everything deleted return with that transaction's gas. `#/booth` is the event view: the latest passes on the
272
+ package and a live feed of every call into it, refreshing every four seconds.
273
+
274
+ The pages use the Sui brand fonts, which are licensed and not in git: put the brand kit under
275
+ `.local/brand/` and run `npm run brand` before building, or the pages fall back to system fonts.
276
+ The build bundles `deployments/<network>.json`; `?network=testnet` picks one, otherwise the
277
+ first of testnet, devnet, localnet, mainnet that exists. To host it, serve `web-dist/` as static
278
+ files at a fixed origin and set `siteUrl` in the deployment file. To run it locally against any
279
+ deployment:
280
+
281
+ ```sh
282
+ npm run explorer -- --deployment .local/devnet/deployment.json
283
+ ```
284
+
285
+ ## Basecamp film and slides
286
+
287
+ Every word of the film (voiceover and on-screen text) and of the two slides lives in
288
+ [`presentation/copy.md`](presentation/copy.md). Edit it, then run `npm run slides` (seconds) or
289
+ `npm run demo:film` (about six minutes, since the voice paces the recording).
290
+
291
+ `npm run demo:film` records the three-minute cut on a fresh localnet and writes
292
+ `scripts/film/out/basecamp-silent.mp4` (picture only, for the presenter's voiceover),
293
+ `basecamp-scratch-vo.mp4` (the same cut read by a scratch voice, for pacing) and
294
+ `basecamp-script.md` (the voiceover with a timecode per line). The voice paces the recording, and quiet waits on the agent are cut. On a
295
+ published network: `npm run film:record -- --deployment <deployment.json> --funder <key file>`,
296
+ then `npm run film:edit`. There the owner signs in the real Slush extension, copied from the
297
+ local Chrome profile (or `SLUSH_EXTENSION`) into a throwaway browser profile with a fresh key;
298
+ the stage shows Slush's own screens as a docked panel, and what the key has left goes back to
299
+ the funder afterwards. Localnet keeps the page's dev wallet, since Slush has no localnet.
300
+ `node --import tsx scripts/slides/render.ts` renders the two concept
301
+ slides to `.local/basecamp/`. Both need the brand kit (`npm run brand`) and Codex on the PATH.
302
+ Drafts use the free edge-tts voice. `npm run film:final` (with `ELEVENLABS_API_KEY` set) reads the
303
+ lines in the account's ElevenLabs voice (`ELEVENLABS_VOICE`, default `Tech`); clips are cached
304
+ under `.local/tts-cache/`, so an unchanged line costs no credits on a re-recording.
305
+
306
+ ### Changing the voice or the words
307
+
308
+ The voice paces the recording, so a new voice or a new line means a new recording. To re-record
309
+ the testnet cut as it was made for Basecamp, with the owner signing in Slush:
310
+
311
+ 1. Have Codex (`codex`) on the PATH and Slush installed in Chrome, then `npm install`, `npm run
312
+ brand` and `npx playwright install chromium`.
313
+ 2. Put a funded testnet key (the `suiprivkey…` string, a few SUI; each run uses about 2) in a
314
+ file, for example `.local/testnet/funder.key`. Get testnet SUI at <https://faucet.sui.io>.
315
+ 3. Change the words in `presentation/copy.md` if you want to. `[tone]` tags and `...` shape the
316
+ ElevenLabs reading; the free draft voice ignores them.
317
+ 4. Record with your own ElevenLabs voice:
318
+
319
+ ```sh
320
+ export ELEVENLABS_API_KEY=… ELEVENLABS_VOICE="Your voice name"
321
+ npm run film:record -- --final --deployment deployments/testnet.json --funder .local/testnet/funder.key
322
+ npm run film:edit
323
+ ```
324
+
325
+ Leave out `--final` for a free draft first. The cut lands in `scripts/film/out/`:
326
+ `basecamp-scratch-vo.mp4` is the voiced film and `basecamp-silent.mp4` the same picture with no
327
+ sound, for recording a human voiceover over it with `basecamp-script.md` as the timecoded script.
328
+
329
+ ## Show it to someone
330
+
331
+ - [English demo script](docs/DEMO.md): pitch, exact commands, Claude prompts, expected results.
332
+ - [Chinese presenter instructions](docs/DEMO.zh-CN.md): operator notes with English prompts and narration.
333
+ - [Agent transaction guide](docs/AGENT.md): complete interface and agent-side examples.
334
+ - [Architecture and boundaries](docs/ARCHITECTURE.md).
335
+ - [Status: implemented and todo](docs/STATUS.md).
336
+ - [Verification record](docs/VERIFICATION.md) and [generated chain evidence](docs/evidence/localnet.json),
337
+ including the explorer's [pass page](docs/evidence/explorer-pass.png) and
338
+ [booth view](docs/evidence/explorer-booth.png).
339
+ - [Real Claude execution evidence](docs/evidence/claude.json): Claude Code with the plugin,
340
+ from prompt to signed pass to on-chain actions on a localnet.
341
+
342
+ ## Checks
343
+
344
+ ```sh
345
+ npm run check
346
+ npm test
347
+ npm run test:move
348
+ npm run build
349
+ AGENT_PASS_BROWSER_TEST=1 npm run test:integration
350
+ # Optional live model check, using fresh localnet funds and your Claude login:
351
+ npm run test:claude
352
+ ```
353
+
354
+ Browser verification uses installed Google Chrome and a wallet-standard **test wallet**.
355
+ It runs with a Chinese browser locale to verify the demo still displays English dates and copy.
356
+ It is not evidence of a live Slush extension signature. Integration tests submit signed
357
+ invalid transactions and inspect persisted failures; ordinary SDK simulations are not
358
+ counted as chain refusals. Each test owns and stops its localnet process.
359
+
360
+ ## Release checklist
361
+
362
+ Publishing is a maintainer step, done once per network and once per npm release. None of it runs
363
+ on a user's machine.
364
+
365
+ Publish the contracts to a network:
366
+
367
+ 1. `npm run toolchain` and `npm run build`.
368
+ 2. `npm run deploy -- create --network testnet --directory .local/testnet`. Testnet is the
369
+ default. Mainnet needs a manually funded publisher (no faucet): `create --network mainnet`
370
+ prints the address, `resume` publishes once it holds 2 SUI.
371
+ 3. Commit the resulting `deployment.json` here as `deployments/<network>.json`.
372
+
373
+ Publish the npm client:
374
+
375
+ 1. Confirm `npm run check`, `npm test`, `npm run test:move`, `npm run build`, and
376
+ `AGENT_PASS_BROWSER_TEST=1 npm run test:integration` pass.
377
+ 2. `npm pack --dry-run` to confirm the tarball holds `dist/`, `web-dist/` and `deployments/`.
378
+ 3. Finalize the package name and version, remove `"private": true`, then `npm publish`;
379
+ `prepublishOnly` rebuilds first.
380
+
381
+ ## Scope
382
+
383
+ Demo only, localnet/testnet/devnet, SUI and a test **USDC** that the demo faucet mints (not
384
+ Circle's USDC). Off mainnet DeepBook, Cetus and NAVI are exercised through local stand-ins that
385
+ keep the mainnet function signatures over constant-product pools and a principal-only lending
386
+ market. The package also builds against the real protocols (`sui move build -e mainnet`) and
387
+ `npm run deploy -- create --network mainnet` publishes it there with Circle's USDC and the real
388
+ pools, for compatibility tests; no mainnet publication is claimed yet. The demo packages are
389
+ made immutable when published; the mainnet package keeps its upgrade cap.
390
+
391
+ **Policies.** Each rule set is one on-chain policy object for one coin type, installed by the
392
+ owner and metered per UTC calendar day. Transfers reach only named recipients. Swaps run only
393
+ on listed pools, within input caps, above a static price floor and the agent's own `min_out`;
394
+ proceeds return to the owner's address. Lending pins the NAVI pool and asset index, caps each
395
+ action, and refuses a withdraw or borrow that would leave the position below the owner's
396
+ health-factor floor; the floor sits on the collateral policy too, so a withdraw cannot breach
397
+ it. Positions belong to the pass's own NAVI account cap, never to the agent. Owners edit
398
+ policies by removing and reinstalling them, which keeps the meters.
399
+
400
+ **Allowances.** `sui::allowance` draws from address balances only, so setup moves the chosen
401
+ coins from the owner's coin objects into the owner's own address balance. Anything the owner
402
+ spends from that balance later simply reduces what the agent can withdraw; a spend above the
403
+ live balance is refused at signing. A session's allowances, the two asset allowances and the
404
+ separate SUI gas allowance, share one expiry and are deleted together on revocation. The pass
405
+ accepts only allowances funded by its owner for its agent, and only it can spend them. A
406
+ repayment to NAVI is charged to the allowance in full before NAVI runs, so an over-payment
407
+ returns to the owner but still counts against the allowance; the agent should size repayments
408
+ from the live debt.
409
+
410
+ **Staking.** Real on every network. The policy lists validators (empty means any active one)
411
+ and caps each stake and the day. The `StakedSui` the agent opens is held by the pass; the
412
+ agent may unstake it, which sends principal and rewards to the owner's address, and the owner
413
+ may reclaim it as an object. The system's own 1 SUI minimum per stake applies.
414
+
415
+ **Objects.** The pass holds objects under typed keys: a protocol account under its adapter's
416
+ key, a stake under its ID, anything else under its own ID. Only the owner deposits or withdraws
417
+ them. Withdrawing the NAVI account cap moves the position with it, into the owner's wallet,
418
+ where NAVI's own UI shows it; withdrawing a stake makes it an ordinary `StakedSui` there. An
419
+ emptied pass (no policies, no objects) can be destroyed by the owner.
420
+
421
+ The gas stipend belongs to the session address and is freely spendable. A local service and
422
+ Claude running under the same OS user are not a private-key isolation boundary: the chain rules
423
+ survive key theft, while key confidentiality needs a separate identity or container. The private
424
+ owner/publisher fixture keys never enter the signing service.
@@ -0,0 +1,28 @@
1
+ <!-- Copyright (c) Mysten Labs, Inc. -->
2
+ <!-- SPDX-License-Identifier: Apache-2.0 -->
3
+
4
+ # Bundled deployments
5
+
6
+ One `deployment.json` per public network, committed here and shipped in the npm package (see the
7
+ `files` field in `package.json`). Each records the published package and object IDs, the gRPC URL
8
+ and the chain identifier for that network. The stdio server loads one of these when
9
+ the agent names a `network` in `propose_authorization`, so an installed client needs no local
10
+ publish; a private `deployment.json` under `~/.sui-agent-pass` or a `deployment` path overrides.
11
+
12
+ `mainnet.json` is the mainnet test copy of the package (`0x4c9010b0…f403`, upgraded to
13
+ `0x08d82880…f744`, version 2), published for dogfooding and for testing the publish and upgrade
14
+ process with small sums; the real launch will be a fresh publish and a new file here. Add
15
+ `siteUrl` to it once the hosted site has its address, so the plugin sends owners there.
16
+ `testnet.json` is the current package (Sui Agent Pass), published to testnet on 2026-10-20 with
17
+ the version gate and the per-coin deployment shape (`coins`, `pools`, NAVI `reserves`, the demo
18
+ faucet). Any Move change means a new publish and a new file here. `npm run devnet` publishes to devnet and writes its
19
+ `deployment.json` for the plugin; `npm run deploy -- create --network <name>` publishes to
20
+ testnet or devnet. At launch, commit the resulting `deployment.json` here as `<name>.json`.
21
+
22
+ The site build (`npm run build`) copies these files into `web-dist/deployments/`, so the hosted
23
+ site serves whichever networks are committed here. A deployment's `siteUrl` is where the
24
+ plugin sends owners to review and sign; without it the local signer serves the same build.
25
+
26
+ The package references `sui::allowance`, which testnet, devnet and mainnet (protocol 138) all
27
+ have. A mainnet publish needs a manually funded publisher (mainnet has no faucet):
28
+ `npm run deploy -- create --network mainnet`.