@subly_fi/pay 0.6.1 → 0.7.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 +21 -0
- package/README.md +98 -61
- package/dist/budget.js +2267 -0
- package/dist/cli.js +37 -20
- package/dist/deposit.js +1031 -183
- package/dist/doctor.js +188 -0
- package/dist/mcp-server.js +3404 -2415
- package/dist/pay.js +2764 -1873
- package/dist/setup-link.js +950 -104
- package/dist/vaults.js +129 -0
- package/dist/withdraw.js +950 -104
- package/package.json +25 -6
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
|
@@ -1,73 +1,110 @@
|
|
|
1
1
|
# @subly_fi/pay
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
**Kamino vault yield** — your agent pays for paywalled APIs from the yield on
|
|
5
|
-
deposited USDC, and the principal is never spent. Non-custodial: it signs
|
|
6
|
-
locally with your own Solana key; Subly never holds it.
|
|
7
|
-
|
|
8
|
-
Current payments target standard x402 sellers that offer a Solana USDC `exact`
|
|
9
|
-
rail with facilitator `extra.feePayer` support.
|
|
10
|
-
|
|
11
|
-
Ships one `pay` dispatcher bin with subcommands, all runnable with `npx` (no clone):
|
|
12
|
-
|
|
13
|
-
- `pay mcp` — an MCP server (Claude Code, Cursor, any MCP client) exposing
|
|
14
|
-
the full lifecycle as tools: `create_subly_setup_link` /
|
|
15
|
-
`check_subly_setup` (owner onboarding: the human approves the spending
|
|
16
|
-
mandate + first deposit with one Face ID), `deposit_to_subly_vault`,
|
|
17
|
-
`get_subly_yield_budget`, `fetch_with_subly_payment`,
|
|
18
|
-
`withdraw_from_subly_vault`. Payments above the owner's approval
|
|
19
|
-
threshold, deposits, and (when the mandate opts in) withdrawals return an
|
|
20
|
-
`approveUrl` to paste into chat; retry with the `approvalId` once the
|
|
21
|
-
human approved.
|
|
22
|
-
- `pay fetch <url> [maxAmountRawUsdc] [apr_<approvalId>]` — one-shot: pay for
|
|
23
|
-
a URL, print the receipt (used by the OpenClaw skill); retry with the
|
|
24
|
-
`apr_...` id after an `approval_required` refusal
|
|
25
|
-
- `pay deposit <amountRawUsdc> [apr_...]` / `pay withdraw <amountRawUsdc>
|
|
26
|
-
[apr_...]` — vault deposit / withdraw with the same owner-approval flow
|
|
27
|
-
- `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)
|
|
30
|
-
|
|
31
|
-
## Wallet
|
|
32
|
-
|
|
33
|
-
Subly does not create wallets — bring your own Solana keypair:
|
|
3
|
+
CLI and stdio MCP client for paying compatible x402 APIs with Kamino USDC vault yield on Solana. MIT licensed. Works with your own [Subly relayer](https://github.com/SublyFi/subly-payment-protocol/tree/main/deploy); no Subly account is required.
|
|
34
4
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
```
|
|
5
|
+
Version 0.7 is beta software and has not had an external security audit. Vault operations use real mainnet funds. Yield accounting and owner policies depend on your relayer operator. Read the [security model](https://github.com/SublyFi/subly-payment-protocol/blob/main/docs/security-model.md).
|
|
6
|
+
|
|
7
|
+
## Quick start
|
|
39
8
|
|
|
40
|
-
|
|
41
|
-
sponsored — then deposit (vault minimum is just over 1 USDC: share rounding
|
|
42
|
-
refuses exactly 1.000000; deposit self-registers the wallet):
|
|
9
|
+
You need **Node.js 24+**, a Solana agent wallet with mainnet USDC, a trusted relayer URL, and a mainnet RPC endpoint that supports transaction simulation with inner instructions. Your wallet can be a local keypair or a supported custody signer. The owner who approves spending controls can use a passkey or a separate Solana wallet.
|
|
43
10
|
|
|
44
11
|
```bash
|
|
45
|
-
npx -y @subly_fi/pay
|
|
12
|
+
npx -y @subly_fi/pay@0.7.0 --help
|
|
13
|
+
export SUBLY_RELAYER_URL=https://your-relayer.example.com
|
|
14
|
+
export SOLANA_RPC_URL=https://your-mainnet-rpc.example.com
|
|
15
|
+
export SUBLY_DEMO_AGENT_KEYPAIR_PATH=/absolute/path/to/agent.json
|
|
16
|
+
npx -y @subly_fi/pay@0.7.0 doctor
|
|
17
|
+
npx -y @subly_fi/pay@0.7.0 vaults
|
|
46
18
|
```
|
|
47
19
|
|
|
48
|
-
|
|
20
|
+
Use an existing dedicated agent wallet, or create one with `solana-keygen new -o agent.json`. Keep its recovery material private and restrict the file to its owner (`chmod 600 agent.json`). Fund its public address with **USDC on Solana mainnet**. Subly does not create or fund wallets. Vault fees require a funded relayer sponsor; the final API payment requires the seller's facilitator fee payer.
|
|
49
21
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
22
|
+
1. Review the selected vault, its curator, fees and liquidity. For a catalogue supplied by your operator, install the reviewed file locally and set `SUBLY_VAULTS_FILE=/absolute/path/vaults.json`. `SUBLY_VAULT_ADDRESS` selects one listed vault for CLI commands. Never install transaction trust anchors merely because a remote response says to.
|
|
23
|
+
2. Create an owner setup link. This example pre-approves a **1.01 USDC** deposit; the selected vault's minimum can differ:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npx -y @subly_fi/pay@0.7.0 setup-link --initial-deposit 1010000
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Open the returned `setupUrl`, review the wallet, vault and limits, then approve with your passkey or wallet. Links expire in 10 minutes. Treat setup and approval links as private capabilities. The first person completing an initial setup becomes the owner for that wallet/vault.
|
|
30
|
+
3. Check completion and deposit promptly; initial deposit approval lasts about 15 minutes:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npx -y @subly_fi/pay@0.7.0 setup-status <sessionId>
|
|
34
|
+
npx -y @subly_fi/pay@0.7.0 deposit 1010000
|
|
35
|
+
npx -y @subly_fi/pay@0.7.0 budget
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
4. Wait until **spendable yield** covers the price and vault fees. A new deposit does not immediately provide a payment budget. Then request a compatible API:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx -y @subly_fi/pay@0.7.0 fetch https://seller.example.com/paid-resource
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
5. Withdraw funds back to the same agent wallet when needed:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx -y @subly_fi/pay@0.7.0 withdraw 1000000
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
All amounts are raw USDC integers: `1000000` = 1 USDC. `fetch` defaults to a **0.01 USDC cap**, configurable with `SUBLY_MCP_MAX_AMOUNT_RAW_USDC` or `fetch <URL> <capRawUSDC>`. The owner mandate may set stricter limits. `setup-link --help` lists policy options. A withdrawal can include principal and is subject to liquidity, fees and the owner's policy. A revoked mandate also blocks relayer withdrawals.
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
A subsequent deposit/payment/withdrawal may return `approvalRequired` with an `approveUrl`. After the owner approves, retry the same operation with the returned `apr_...` as a trailing argument. Never automatically retry a transaction reported as submitted or an API payment with an unknown outcome.
|
|
53
|
+
|
|
54
|
+
## MCP configuration
|
|
55
|
+
|
|
56
|
+
Add this to the MCP configuration of your editor or agent host. Replace all example values with your own absolute paths and endpoints. Pinning the version keeps upgrades explicit.
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"subly": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "@subly_fi/pay@0.7.0", "mcp"],
|
|
64
|
+
"env": {
|
|
65
|
+
"SUBLY_RELAYER_URL": "https://your-relayer.example.com",
|
|
66
|
+
"SOLANA_RPC_URL": "https://your-mainnet-rpc.example.com",
|
|
67
|
+
"SUBLY_DEMO_AGENT_KEYPAIR_PATH": "/absolute/path/to/agent.json",
|
|
68
|
+
"SUBLY_MCP_STATE_PATH": "/absolute/path/to/subly-pending.json",
|
|
69
|
+
"SUBLY_MCP_MAX_AMOUNT_RAW_USDC": "10000"
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
56
74
|
```
|
|
57
75
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
|
63
|
-
|
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
`
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
Tools: `list_subly_vaults`, `select_subly_vault`, `create_subly_setup_link`, `check_subly_setup`, `deposit_to_subly_vault`, `get_subly_yield_budget`, `withdraw_from_subly_vault`, `fetch_with_subly_payment`. Ask the agent to list vaults and follow owner setup before depositing. Each selected vault has its own mandate and accounting; changing selection never moves funds. Stdio stdout is reserved for MCP messages.
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
| Variable | Meaning |
|
|
81
|
+
| --- | --- |
|
|
82
|
+
| `SUBLY_RELAYER_URL` | Chosen operator's HTTPS URL. Set explicitly; the historical demo fallback has no availability promise. |
|
|
83
|
+
| `SOLANA_RPC_URL` | Your trusted mainnet RPC; fallback is the rate-limited public mainnet RPC. Used to verify lookup tables and simulate withdrawals before signing. |
|
|
84
|
+
| `SUBLY_DEMO_AGENT_KEYPAIR_PATH` | Local Solana 64-byte JSON keypair; the historical `DEMO` name also applies in production. |
|
|
85
|
+
| `SUBLY_DEMO_AGENT_KEYPAIR` | Alternative base58 64-byte secret; if set, takes precedence over the file. Avoid putting secrets in shell history. |
|
|
86
|
+
| `SUBLY_SIGNER_PROVIDER` | `local` (default), `circle` or `privy`. |
|
|
87
|
+
| `SUBLY_VAULTS_FILE` | Reviewed local vault catalogue. Without it, the built-in vault is used. |
|
|
88
|
+
| `SUBLY_VAULT_ADDRESS` | Selected catalogue entry (or custom single-vault address with matching share mint/farm settings). |
|
|
89
|
+
| `SUBLY_MCP_MAX_AMOUNT_RAW_USDC` | Client payment cap; default `10000`. |
|
|
90
|
+
| `SUBLY_MCP_STATE_PATH` | Persistent pending-payment file. Default `~/.subly/standard-x402-pending.json`. Use one shared file for all clients paying from the same wallet. |
|
|
91
|
+
| `SUBLY_PAY_METHOD` / `SUBLY_PAY_BODY` | Optional HTTP method and body for CLI `fetch`; MCP accepts these as tool arguments. |
|
|
92
|
+
|
|
93
|
+
For Circle configure `CIRCLE_API_KEY`, `CIRCLE_ENTITY_SECRET`, `CIRCLE_WALLET_ID`. For Privy use `PRIVY_APP_ID`, `PRIVY_APP_SECRET`, `PRIVY_WALLET_ID`, and `PRIVY_AUTHORIZATION_KEY` when required by wallet ownership. Each accepts a `SUBLY_` prefix which takes precedence. See [provider details](https://github.com/SublyFi/subly-payment-protocol/blob/main/docs/agent-wallet-providers.md).
|
|
94
|
+
|
|
95
|
+
Only sellers offering **Solana mainnet USDC `exact`** with `extra.feePayer` are supported. EVM, unsupported tokens and unsponsored rails are refused. A supported seller does not need a Subly integration. Yield realization and x402 payment are separate transactions: if the payment fails after realization, USDC may remain in the agent wallet.
|
|
96
|
+
|
|
97
|
+
## Recovery and troubleshooting
|
|
98
|
+
|
|
99
|
+
- `doctor` performs read-only configuration, relayer/vault and RPC checks. It never signs or transacts; it does not prove vault safety or available yield.
|
|
100
|
+
- A withdrawal preview failure is a refusal to sign. Check your RPC's simulation support and liquidity; do not disable transaction validation.
|
|
101
|
+
- Preserve the pending-state JSON across restarts and upgrades. An `external_outcome_unknown` record blocks a second payment until you investigate the seller/facilitator outcome.
|
|
102
|
+
- Concurrent clients using the same state file serialize payments with a `.lock` file. After a crash, stop **all** clients using that file before removing only the stale `.lock`. Preserve the JSON. A new file or another machine cannot coordinate with the old one.
|
|
103
|
+
- `submitted` means the transaction may still confirm. Poll the original intent ID / transaction instead of preparing another deposit or withdrawal.
|
|
104
|
+
- Setup passkeys bind to the operator's domain. Use the original domain and device credential; follow the documented recovery delay if access is lost.
|
|
105
|
+
|
|
106
|
+
[Full troubleshooting](https://github.com/SublyFi/subly-payment-protocol/blob/main/docs/troubleshooting.md) · [Support](https://github.com/SublyFi/subly-payment-protocol/blob/main/SUPPORT.md) · [Private security reports](https://github.com/SublyFi/subly-payment-protocol/security/advisories/new)
|
|
107
|
+
|
|
108
|
+
## Build from source
|
|
109
|
+
|
|
110
|
+
In the repository root: `npm ci`, then `npm ci --prefix packages/pay` and `npm run check --prefix packages/pay`. `npm run test:package` verifies a packed installation from outside the checkout, including the MCP handshake. The published package contains the client only; it does not include the relayer or Kamino server SDK.
|