@subly_fi/pay 0.6.1 → 0.6.2

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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SublyFi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -6,7 +6,12 @@ deposited USDC, and the principal is never spent. Non-custodial: it signs
6
6
  locally with your own Solana key; Subly never holds it.
7
7
 
8
8
  Current payments target standard x402 sellers that offer a Solana USDC `exact`
9
- rail with facilitator `extra.feePayer` support.
9
+ rail with facilitator `extra.feePayer` support (meaning the seller side
10
+ sponsors the payment transaction's network fee — true of common facilitators
11
+ such as PayAI and Coinbase CDP).
12
+
13
+ > [!WARNING]
14
+ > `@subly_fi/pay` is beta software and has not undergone an external security audit. It signs and submits transactions involving real Solana mainnet funds through a separate relayer and Kamino vault. The client package currently passes its production dependency audit, but this is not a guarantee of relayer, protocol, or vault safety. Use only amounts you can afford to lose and review the relayer operator and configuration before use.
10
15
 
11
16
  Ships one `pay` dispatcher bin with subcommands, all runnable with `npx` (no clone):
12
17
 
@@ -25,18 +30,42 @@ Ships one `pay` dispatcher bin with subcommands, all runnable with `npx` (no clo
25
30
  - `pay deposit <amountRawUsdc> [apr_...]` / `pay withdraw <amountRawUsdc>
26
31
  [apr_...]` — vault deposit / withdraw with the same owner-approval flow
27
32
  - `pay setup-link [--initial-deposit <raw>] [--approval-threshold <raw>] ...`
28
- / `pay setup-status <sessionId>` — owner onboarding for CLI/skill harnesses
29
- (same flow as the MCP setup tools)
33
+ / `pay setup-status <st_sessionId | setupUrl>` — owner onboarding for
34
+ CLI/skill harnesses (same flow as the MCP setup tools)
30
35
 
31
36
  ## Wallet
32
37
 
33
- Subly does not create wallets — bring your own Solana keypair:
38
+ Subly does not create wallets — bring your own Solana keypair (`solana-keygen`
39
+ ships with the [Solana CLI](https://docs.anza.xyz/cli/install)):
34
40
 
35
41
  ```bash
36
42
  solana-keygen new --no-bip39-passphrase -o ~/.subly/agent.json
37
43
  export SUBLY_DEMO_AGENT_KEYPAIR_PATH=~/.subly/agent.json
38
44
  ```
39
45
 
46
+ Or bring a custody-held agent wallet — the key then never touches this
47
+ machine; every signature is requested from the provider's API and verified
48
+ locally before use:
49
+
50
+ ```bash
51
+ # Circle developer-controlled wallet (a Solana wallet in your wallet set):
52
+ export SUBLY_SIGNER_PROVIDER=circle
53
+ export CIRCLE_API_KEY=... CIRCLE_ENTITY_SECRET=... CIRCLE_WALLET_ID=...
54
+
55
+ # Privy server wallet (Solana), incl. agentic wallets owned by an
56
+ # authorization key — pass that key so requests carry the required
57
+ # privy-authorization-signature:
58
+ export SUBLY_SIGNER_PROVIDER=privy
59
+ export PRIVY_APP_ID=... PRIVY_APP_SECRET=... PRIVY_WALLET_ID=...
60
+ export PRIVY_AUTHORIZATION_KEY=wallet-auth:... # only for owner-key wallets
61
+ ```
62
+
63
+ Each Circle/Privy credential var also accepts a `SUBLY_`-prefixed form (e.g.
64
+ `SUBLY_CIRCLE_API_KEY`) that wins over the plain one, so Subly can use a
65
+ different credential than other tooling on the same machine. Note the
66
+ `circle` CLI "agent wallet" (email + OTP) is a different Circle product that
67
+ exposes no signing API and cannot be used here.
68
+
40
69
  Send USDC (Solana mainnet) to the printed address — no SOL needed, fees are
41
70
  sponsored — then deposit (vault minimum is just over 1 USDC: share rounding
42
71
  refuses exactly 1.000000; deposit self-registers the wallet):
@@ -55,14 +84,80 @@ claude mcp add subly -- npx -y @subly_fi/pay mcp
55
84
  npx -y @subly_fi/pay fetch https://seller.example.com/api/premium
56
85
  ```
57
86
 
87
+ ### Claude Desktop
88
+
89
+ Prerequisites: [Node.js](https://nodejs.org) 20+ installed, and an agent
90
+ keypair (see [Wallet](#wallet) above).
91
+
92
+ 1. Open the config file (create it if it does not exist):
93
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
94
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
95
+
96
+ Or in the app: **Settings → Developer → Edit Config**.
97
+
98
+ 2. Add the `subly` server. Claude Desktop is a GUI app and does **not**
99
+ inherit your shell environment (`.zshrc`, `.env` files), so every
100
+ variable must go in the `env` block:
101
+
102
+ ```json
103
+ {
104
+ "mcpServers": {
105
+ "subly": {
106
+ "command": "npx",
107
+ "args": ["-y", "@subly_fi/pay", "mcp"],
108
+ "env": {
109
+ "SUBLY_DEMO_AGENT_KEYPAIR_PATH": "/Users/you/.subly/agent.json"
110
+ }
111
+ }
112
+ }
113
+ }
114
+ ```
115
+
116
+ Use an absolute path for the keypair (`~` is not expanded). For a
117
+ custody wallet, replace the keypair var with the `circle` / `privy`
118
+ variables from [Environment](#environment). Optional vars
119
+ (`SUBLY_MCP_MAX_AMOUNT_RAW_USDC`, `SOLANA_RPC_URL`, …) go in the same
120
+ `env` block.
121
+
122
+ 3. Restart Claude Desktop (quit fully, then reopen). The tools icon under
123
+ the chat input should now list **subly-payments** with the tools above.
124
+
125
+ If the server fails to start, the usual cause is that Claude Desktop
126
+ cannot find `npx` (e.g. Node installed via nvm). Point `command` at the
127
+ absolute path instead — run `which npx` in a terminal and use that
128
+ value, e.g. `"command": "/opt/homebrew/bin/npx"`.
129
+
130
+ 4. Use it by chatting. First time: "set up Subly" walks you through the
131
+ owner setup link (spending mandate + first deposit). After that,
132
+ asking for anything behind an x402 paywall ("fetch
133
+ https://seller.example.com/api/premium") pays from vault yield
134
+ automatically and returns the response plus a payment receipt.
135
+ Payments above the owner's approval threshold return an `approveUrl` —
136
+ open it in a browser, approve, then tell Claude to retry.
137
+
138
+ Claude Desktop asks for permission on each first tool use. The permission
139
+ prompt is effectively your payment confirmation: "Allow always" on
140
+ `fetch_with_subly_payment` removes that human check and relies entirely on
141
+ the spending-mandate caps — keep per-use approval for payments, and reserve
142
+ "Allow always" for read-only tools like `get_subly_yield_budget`.
143
+
58
144
  ## Environment
59
145
 
60
146
  | Var | Required | Default |
61
147
  |---|---|---|
62
- | `SUBLY_DEMO_AGENT_KEYPAIR_PATH` | yes (or `SUBLY_DEMO_AGENT_KEYPAIR` base58) | |
148
+ | `SUBLY_SIGNER_PROVIDER` | no | `local` (`circle` / `privy` for custody wallets) |
149
+ | `SUBLY_DEMO_AGENT_KEYPAIR_PATH` | with `local` (or `SUBLY_DEMO_AGENT_KEYPAIR` base58) | — |
150
+ | `CIRCLE_API_KEY` / `CIRCLE_ENTITY_SECRET` / `CIRCLE_WALLET_ID` | with `circle` | — |
151
+ | `PRIVY_APP_ID` / `PRIVY_APP_SECRET` / `PRIVY_WALLET_ID` | with `privy` | — |
152
+ | `PRIVY_AUTHORIZATION_KEY` | only for owner-key (agentic) Privy wallets | — |
63
153
  | `SUBLY_RELAYER_URL` | no | `https://api.demo.sublyfi.com` |
64
154
  | `SOLANA_RPC_URL` | no | public mainnet RPC |
65
155
  | `SUBLY_MCP_MAX_AMOUNT_RAW_USDC` | no | `10000` (0.01 USDC) per-payment cap |
156
+ | `SUBLY_MCP_STATE_PATH` | no | `~/.subly/standard-x402-pending.json` (pending-payment store, double-payment protection) |
157
+ | `SUBLY_PAY_METHOD` / `SUBLY_PAY_BODY` | no (`pay fetch` only) | `GET` / — (JSON body for POST-body sellers) |
158
+ | `SUBLY_PAY_FORCE_NEW_PAYMENT` | no (`pay fetch` only) | unset (`1` forces a fresh payment — may double-pay) |
159
+ | `CIRCLE_BASE_URL` / `PRIVY_BASE_URL` | no | provider API defaults |
160
+ | `SUBLY_VAULT_ADDRESS` / `SUBLY_VAULT_SHARE_MINT` / `SUBLY_VAULT_USDC_MINT` / `SUBLY_VAULT_FARM` | only with a custom-vault relayer | Subly's public vault and Farm. These are your signer's trust anchor (intents are validated against this local config, never the relayer's claims) — set them only to addresses you independently verified or control |
66
161
 
67
162
  Requests authenticate with a signature from your wallet key — there is no API
68
163
  token. `SUBLY_FACILITATOR_URL` is still accepted as a legacy fallback for
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // Single dispatcher bin for @sublyfi/pay so `npx -y @sublyfi/pay <subcommand>`
2
+ // Single dispatcher bin for @subly_fi/pay so `npx -y @subly_fi/pay <subcommand>`
3
3
  // resolves cleanly. Subcommands map to the bundled entry points; argv is
4
4
  // reshaped so each entry sees its own positional args at the usual index.
5
5
  import { dirname, join } from "node:path";
@@ -18,7 +18,7 @@ const [sub, ...rest] = process.argv.slice(2);
18
18
  const target = sub === undefined ? undefined : TARGETS[sub];
19
19
  if (target === undefined) {
20
20
  console.error(
21
- "usage: subly <mcp|fetch <url>|deposit <amountRawUsdc>|withdraw <amountRawUsdc>|setup-link|setup-status <sessionId>>"
21
+ "usage: pay <mcp|fetch <url>|deposit <amountRawUsdc>|withdraw <amountRawUsdc>|setup-link|setup-status <sessionId|setupUrl>>"
22
22
  );
23
23
  process.exit(1);
24
24
  }