@rozoai/checkout 0.1.10 → 0.1.12
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/README.md +66 -6
- package/docs/review-history.md +77 -0
- package/llms.txt +21 -3
- package/package.json +29 -9
- package/scripts/dist/cli.js +1967 -2937
- package/scripts/dist/create-order.js +31 -2
- package/scripts/dist/quote.js +17 -1
- package/scripts/dist/send-evm.js +176 -48
- package/scripts/dist/send-sol.js +1233 -2757
- package/scripts/dist/status.js +173 -18
package/README.md
CHANGED
|
@@ -2,11 +2,34 @@
|
|
|
2
2
|
|
|
3
3
|
**English** | [简体中文](docs/README.zh.md) | [日本語](docs/README.ja.md) | [Español](docs/README.es.md)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
### When your agent needs to pay OpenRouter (or any Coinbase invoice) with the crypto you already hold
|
|
6
|
+
|
|
7
|
+
OpenRouter crypto top-ups and other Coinbase-hosted invoices settle in USDC on
|
|
8
|
+
Base. This skill pays them from whatever you hold instead, and it does three
|
|
9
|
+
things the official path cannot:
|
|
10
|
+
|
|
11
|
+
- **Pay from the chain you are already on.** USDT or USDC on Solana, BNB Chain,
|
|
12
|
+
Ethereum or Polygon, USDC on Base or Stellar, or BTC over Lightning. Coinbase's
|
|
13
|
+
own direct pay takes USDC on Base.
|
|
14
|
+
- **No Coinbase account.** Pay the deposit address from any wallet or straight
|
|
15
|
+
from an exchange withdrawal. No sign-up, no API key, no browser.
|
|
16
|
+
- **Scriptable.** OpenRouter's crypto credits API (`POST /api/v1/credits/coinbase`)
|
|
17
|
+
now returns `410 Gone`, so top-ups can no longer be automated there. Once you
|
|
18
|
+
have the payment link, paying it is one command an agent or a cron job can
|
|
19
|
+
run: without a terminal it stops for confirmation, so an unattended caller
|
|
20
|
+
reviews the quote and then passes `--yes`.
|
|
21
|
+
|
|
22
|
+
Merchants we have been paid through so far: **OpenRouter, Venice.ai, Porkbun
|
|
23
|
+
and Alchemy**. Any `payments.coinbase.com` link is quoted the same way.
|
|
24
|
+
|
|
25
|
+
Before you pay, know two things:
|
|
26
|
+
|
|
27
|
+
- **The fee is in the live quote.** You pay the full invoice, no discount and no
|
|
28
|
+
markup on it; the bridge and network fee is added to the deposit amount, which
|
|
29
|
+
is shown in the order summary before the deposit address is released. Send
|
|
30
|
+
exactly that amount, nothing more is charged.
|
|
31
|
+
- **Crypto payments to OpenRouter are never refundable.** That is OpenRouter's
|
|
32
|
+
policy, not ours; check the credit amount before you send.
|
|
10
33
|
|
|
11
34
|
```bash
|
|
12
35
|
npx @rozoai/checkout pay <coinbase-link>
|
|
@@ -17,6 +40,14 @@ prompt and it will mark which coins you can actually afford — then prints a
|
|
|
17
40
|
deposit address for you to pay from any wallet — **no private key, no environment variable, no
|
|
18
41
|
configuration** — and waits until the invoice is settled.
|
|
19
42
|
|
|
43
|
+
Paying a **Bitrefill** invoice instead? Create it on Bitrefill with "USDC on
|
|
44
|
+
Base", then pass its id, address and amount (Coinbase payment links and
|
|
45
|
+
Bitrefill invoices are the two supported targets; Stripe is not):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx @rozoai/checkout pay --bitrefill-invoice <id> --to <0x…> --amount 7.90 --expires-at <ISO> --with usdc-stellar
|
|
49
|
+
```
|
|
50
|
+
|
|
20
51
|
Know your coin already? Skip the question:
|
|
21
52
|
|
|
22
53
|
```bash
|
|
@@ -62,6 +93,21 @@ already hold and pay from wherever it already lives.
|
|
|
62
93
|
|
|
63
94
|
## Use it from your agent
|
|
64
95
|
|
|
96
|
+
Install it as a skill, or just run the CLI:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
# Claude Code
|
|
100
|
+
/plugin marketplace add RozoAI/rozo-checkout-skill
|
|
101
|
+
/plugin install rozo-checkout@rozo
|
|
102
|
+
|
|
103
|
+
# OpenClaw / ClawHub
|
|
104
|
+
clawhub install rozo-checkout
|
|
105
|
+
|
|
106
|
+
# Any agent that can run a shell: review the quote, then pay unattended
|
|
107
|
+
npx @rozoai/checkout quote <coinbase-link>
|
|
108
|
+
npx @rozoai/checkout pay <coinbase-link> --with usdt-solana --yes
|
|
109
|
+
```
|
|
110
|
+
|
|
65
111
|
The payload is the same everywhere: the one-liner above, or point the agent at
|
|
66
112
|
[llms.txt](llms.txt). Agents and scripts should always pass `--with` — the
|
|
67
113
|
picker only appears on a terminal, and there is deliberately no default coin. **Paying from your own wallet never needs a key.** Only
|
|
@@ -274,7 +320,7 @@ Stellar and Lightning are Mode A only.
|
|
|
274
320
|
<summary><b>Terminal — no agent at all</b> — run the scripts step by step</summary>
|
|
275
321
|
|
|
276
322
|
Drive each step yourself. The bundles are self-contained; nothing to install
|
|
277
|
-
beyond Node 18+.
|
|
323
|
+
beyond Node 20.18+.
|
|
278
324
|
|
|
279
325
|
```bash
|
|
280
326
|
git clone https://github.com/RozoAI/rozo-checkout-skill && cd rozo-checkout-skill
|
|
@@ -348,6 +394,16 @@ The full list of what this refuses to do, and why, is in
|
|
|
348
394
|
|
|
349
395
|
## Changelog
|
|
350
396
|
|
|
397
|
+
- **0.1.12**: pay Bitrefill invoices. `pay --bitrefill-invoice <id> --to <0x…>
|
|
398
|
+
--amount <USDC> --expires-at <ISO>` creates a Rozo exactOut order through
|
|
399
|
+
mpprouter that delivers the exact USDC on Base straight to the Bitrefill
|
|
400
|
+
invoice address, payable from Stellar USDC or any supported coin.
|
|
401
|
+
- **0.1.11**: each order now carries `attribution.client`
|
|
402
|
+
(`rozo-checkout-skill/<version>`) so skill-created orders can be told apart
|
|
403
|
+
from the web checkout. Installable as a Claude Code plugin
|
|
404
|
+
(`/plugin marketplace add RozoAI/rozo-checkout-skill`). README and skill
|
|
405
|
+
description rewritten around paying Coinbase invoices from the crypto you
|
|
406
|
+
already hold.
|
|
351
407
|
- **0.1.3** — fixes found by the first real payment. The built bundles no
|
|
352
408
|
longer crash with `__filename is not defined` on Node 22+ (the esbuild banner
|
|
353
409
|
now shims `__filename`/`__dirname` as well as `require`, and every bundle is
|
|
@@ -372,3 +428,7 @@ The full list of what this refuses to do, and why, is in
|
|
|
372
428
|
## License
|
|
373
429
|
|
|
374
430
|
MIT.
|
|
431
|
+
|
|
432
|
+
## Secret scanning
|
|
433
|
+
|
|
434
|
+
Enable the local gitleaks pre-commit hook once per clone: `brew install gitleaks pre-commit && pre-commit install` (config in `.pre-commit-config.yaml`). CI also runs a report-only scan in `.github/workflows/secret-scan.yml`.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Review history
|
|
2
|
+
|
|
3
|
+
[← back to the README](../README.md) · [Safety design](safety.md)
|
|
4
|
+
|
|
5
|
+
This tool moves other people's money. It was reviewed adversarially before it
|
|
6
|
+
was written, again after it was written, and again after the first real payment.
|
|
7
|
+
This page is the record of that.
|
|
8
|
+
|
|
9
|
+
## Design review — 3 rounds, before any code existed
|
|
10
|
+
|
|
11
|
+
The design was written as a plan document and reviewed by an independent model
|
|
12
|
+
with a standing instruction to hunt for anything that could lose funds. No code
|
|
13
|
+
was written until the plan passed with no P0 findings.
|
|
14
|
+
|
|
15
|
+
| Round | Verdict |
|
|
16
|
+
|---|---|
|
|
17
|
+
| 1 | 6 P0, 7 P1, 2 P2 — plan revised |
|
|
18
|
+
| 2 | still had P0s: several round-1 fixes were incomplete, plus one new P0 — plan revised again |
|
|
19
|
+
| 3 | no P0 — implementation began |
|
|
20
|
+
|
|
21
|
+
The P0s were about the plan being wrong regarding the payment rails, not about
|
|
22
|
+
style. Among them: the reuse rule was mis-stated (an existing order is reused
|
|
23
|
+
whenever it is merely unexpired, not only when it is unpaid); the binding
|
|
24
|
+
confirmation was placed before the deposit details existed, so it could not
|
|
25
|
+
bind them; and the payment link could be consumed by another payer between the
|
|
26
|
+
quote and the signature, which needed a re-check immediately before paying.
|
|
27
|
+
|
|
28
|
+
## Code review — 2 rounds, after implementation
|
|
29
|
+
|
|
30
|
+
| Round | Verdict |
|
|
31
|
+
|---|---|
|
|
32
|
+
| 1 | 8 P0, 10 P1, 5 P2 |
|
|
33
|
+
| 2 | 20 of 23 resolved; 3 residual findings, then fixed |
|
|
34
|
+
|
|
35
|
+
The round-1 P0s were the interesting ones, and each is now a real code path
|
|
36
|
+
with its own error code and tests:
|
|
37
|
+
|
|
38
|
+
- the confirmation gate and the `--send` opt-in were documented but not
|
|
39
|
+
actually enforced
|
|
40
|
+
- the send-once claim was a check-then-act race that two concurrent processes
|
|
41
|
+
could both pass
|
|
42
|
+
- an unreadable `amountReceived` was treated as "no money received" rather than
|
|
43
|
+
as money
|
|
44
|
+
- the post-create comparison ignored security-critical fields when they were
|
|
45
|
+
simply absent
|
|
46
|
+
- payability was not re-proved immediately before signing, and incomplete
|
|
47
|
+
upstream state read as payable
|
|
48
|
+
- deposit instructions were not validated for completeness before being shown
|
|
49
|
+
- provider errors could leak credential-bearing URLs
|
|
50
|
+
- the tracked-secret check failed open when it could not consult git
|
|
51
|
+
|
|
52
|
+
## First real payment
|
|
53
|
+
|
|
54
|
+
A live payment then settled in about a minute — and surfaced four more defects,
|
|
55
|
+
all fixed in 0.1.3:
|
|
56
|
+
|
|
57
|
+
- the built bundles crashed on newer Node because the bundler's CommonJS shim
|
|
58
|
+
was incomplete; it had never been caught because only `--help` was ever run
|
|
59
|
+
against a built bundle. The test suite now executes every bundle.
|
|
60
|
+
- the Stellar memo type was not stated anywhere, and sending that memo with the
|
|
61
|
+
wrong type loses the payment. It is `MEMO_TEXT`, and the deposit block now
|
|
62
|
+
says so.
|
|
63
|
+
- reusing an existing unpaid order, and asking for a coin that differs from it,
|
|
64
|
+
both read as errors rather than as the ordinary situations they are
|
|
65
|
+
- nothing showed how long an order had left, and a real payment nearly missed
|
|
66
|
+
its window
|
|
67
|
+
|
|
68
|
+
## What this means for a reader
|
|
69
|
+
|
|
70
|
+
Every finding above is closed, and the behaviours they produced are covered by
|
|
71
|
+
the test suite, which runs entirely offline against recorded fixtures. The full
|
|
72
|
+
list of what this tool refuses to do, and why, is in
|
|
73
|
+
[docs/safety.md](safety.md).
|
|
74
|
+
|
|
75
|
+
The detailed review transcripts are kept internally; they quote source from
|
|
76
|
+
private repositories and so are not published here. The findings themselves are
|
|
77
|
+
summarised above in full — nothing material is omitted.
|
package/llms.txt
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# rozo-checkout
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
>
|
|
3
|
+
> When your agent needs to pay OpenRouter (or any Coinbase invoice) with the crypto you
|
|
4
|
+
> already hold. Pays a Coinbase Payment Link (payments.coinbase.com/payment-links/pl_* or
|
|
5
|
+
> /payment-sessions/paymentSession_*) with BTC over Lightning, USDT/USDC on Solana,
|
|
6
|
+
> BNB Chain, Ethereum or Polygon, or USDC on Base or Stellar. No Coinbase account, public HTTP
|
|
7
|
+
> endpoints, no API key. Crypto payments to OpenRouter are never refundable.
|
|
6
8
|
> The payer funds a one-time deposit address; a bridge and a funder wallet settle the
|
|
7
9
|
> Coinbase link automatically. No discount: you pay the invoice amount, plus the
|
|
8
10
|
> deposit normally carries a small bridge/source-chain fee on top.
|
|
@@ -35,6 +37,22 @@ directory (or --env-file <path>): only ROZO_CHECKOUT_* keys are read from it, it
|
|
|
35
37
|
is parsed as text and never shell-evaluated, and the real environment wins.
|
|
36
38
|
Key files and .env must be chmod 600 and untracked by git.
|
|
37
39
|
|
|
40
|
+
## Bitrefill invoices
|
|
41
|
+
|
|
42
|
+
Also supported: a Bitrefill invoice created with "USDC on Base" (Stripe is not supported).
|
|
43
|
+
No quote step; mpprouter creates an exactOut order paying exactly that amount to the
|
|
44
|
+
Bitrefill address:
|
|
45
|
+
|
|
46
|
+
npx @rozoai/checkout pay --bitrefill-invoice <id> --to <0x…> --amount 7.90 --expires-at <ISO> --with usdc-stellar
|
|
47
|
+
|
|
48
|
+
Router call: POST {MPP}/create-invoice {"provider":"bitrefill","bitrefill":{"invoiceId","address",
|
|
49
|
+
"amount","expiresAt" (required, ≤30 min out)},"source":{"chainId","tokenSymbol"}}. Verify the response echoes the same
|
|
50
|
+
invoiceId/address/amount, and that GET payments/<rozoPaymentId> destination has the same
|
|
51
|
+
chain/token/address/amount (missing = mismatch), before showing the deposit or sending.
|
|
52
|
+
Expiry = the invoice expiry only; refuse to show/send under 2 min. 409 DUPLICATE_INVOICE returns
|
|
53
|
+
the existing rozoPaymentId: resume it. Settled = payment_payout_completed (or completed with a
|
|
54
|
+
payout tx hash). 503 BITREFILL_NOT_CONFIGURED / RETRY_LATER: nothing created, retry later.
|
|
55
|
+
|
|
38
56
|
## Local wallet setup for --send (not needed for the default keyless path)
|
|
39
57
|
|
|
40
58
|
.env keys (only ROZO_CHECKOUT_* are read; real env wins; chmod 600; gitignore):
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rozoai/checkout",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Pay
|
|
5
|
+
"description": "Pay OpenRouter, or any Coinbase invoice, with the crypto you already hold: USDT/USDC on Solana, BNB Chain, Ethereum or Polygon, USDC on Base or Stellar, or BTC over Lightning. No Coinbase account.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"author": "Rozo AI",
|
|
8
8
|
"homepage": "https://github.com/RozoAI/rozo-checkout-skill#readme",
|
|
@@ -15,13 +15,29 @@
|
|
|
15
15
|
},
|
|
16
16
|
"keywords": [
|
|
17
17
|
"openrouter",
|
|
18
|
+
"openrouter-credits",
|
|
18
19
|
"coinbase",
|
|
19
|
-
"
|
|
20
|
-
"lightning",
|
|
21
|
-
"solana",
|
|
22
|
-
"usdt",
|
|
20
|
+
"coinbase-payment-link",
|
|
23
21
|
"usdc",
|
|
24
|
-
"
|
|
22
|
+
"usdt",
|
|
23
|
+
"solana",
|
|
24
|
+
"bnb-chain",
|
|
25
|
+
"ethereum",
|
|
26
|
+
"polygon",
|
|
27
|
+
"base",
|
|
28
|
+
"stellar",
|
|
29
|
+
"lightning",
|
|
30
|
+
"bitcoin",
|
|
31
|
+
"crypto-payments",
|
|
32
|
+
"agent",
|
|
33
|
+
"ai-agent",
|
|
34
|
+
"agent-skill",
|
|
35
|
+
"claude-skill",
|
|
36
|
+
"claude-code",
|
|
37
|
+
"payments",
|
|
38
|
+
"cli",
|
|
39
|
+
"mcp-free",
|
|
40
|
+
"x402"
|
|
25
41
|
],
|
|
26
42
|
"bin": {
|
|
27
43
|
"rozo-checkout": "scripts/dist/cli.js"
|
|
@@ -35,7 +51,7 @@
|
|
|
35
51
|
"LICENSE"
|
|
36
52
|
],
|
|
37
53
|
"engines": {
|
|
38
|
-
"node": ">=18"
|
|
54
|
+
"node": ">=20.18.0"
|
|
39
55
|
},
|
|
40
56
|
"publishConfig": {
|
|
41
57
|
"access": "public"
|
|
@@ -47,9 +63,13 @@
|
|
|
47
63
|
"prepack": "npm run build"
|
|
48
64
|
},
|
|
49
65
|
"devDependencies": {
|
|
50
|
-
"@solana/spl-token": "^0.4.9",
|
|
51
66
|
"@solana/web3.js": "^1.95.0",
|
|
52
67
|
"esbuild": "^0.28.2",
|
|
53
68
|
"viem": "^2.21.0"
|
|
69
|
+
},
|
|
70
|
+
"overrides": {
|
|
71
|
+
"jayson": {
|
|
72
|
+
"uuid": "^11.1.1"
|
|
73
|
+
}
|
|
54
74
|
}
|
|
55
75
|
}
|