@rozoai/checkout 0.1.0 → 0.1.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.
@@ -0,0 +1,338 @@
1
+ # Inicio rápido
2
+
3
+ [English](QUICKSTART.md) | [简体中文](QUICKSTART.zh.md) | [日本語](QUICKSTART.ja.md) | **Español**
4
+
5
+ Pagar un enlace de pago de Coinbase (Coinbase Payment Link) de OpenRouter con
6
+ USDT/USDC en Solana, BNB Chain, Ethereum, Polygon, Base o Stellar, o con BTC por
7
+ Lightning. Cinco minutos. Para saber cómo funciona y por qué, ver
8
+ [README.md](../README.md).
9
+
10
+ ## El comando de una sola línea
11
+
12
+ ```bash
13
+ npx @rozoai/checkout pay https://payments.coinbase.com/payment-links/pl_01YOURLINKID
14
+ ```
15
+
16
+ Eso ejecuta por uno todos los pasos de abajo: elegir moneda, cotizar, crear,
17
+ revisar, confirmar, instrucciones de depósito y luego consultar hasta la
18
+ liquidación. En el paso de elegir moneda se puede pegar la dirección de la
19
+ billetera y el selector consultará los saldos y marcará cuáles se pueden pagar
20
+ —es opcional y nunca cambia lo que se firma—.
21
+
22
+ Si ya se sabe qué moneda usar, se puede indicar y omitir la pregunta:
23
+
24
+ ```bash
25
+ npx @rozoai/checkout pay https://payments.coinbase.com/payment-links/pl_01YOURLINKID --with usdt-solana
26
+ ```
27
+
28
+ Monedas para `--with`: `usdt-solana`, `usdc-solana`, `usdt-bnb`, `usdc-bnb`, `usdt-ethereum`,
29
+ `usdc-ethereum`, `usdt-polygon`, `usdc-polygon`, `usdc-base`, `usdc-stellar`,
30
+ `btc-lightning`. Los scripts y los agentes deben pasar siempre `--with`: el
31
+ selector solo aparece en una terminal y no hay moneda por defecto.
32
+
33
+ Por defecto solo imprime una dirección para pagar desde cualquier billetera: sin
34
+ clave privada y sin configuración. Añadir `--send` únicamente si se quiere que la
35
+ CLI firme desde una billetera caliente, y `--json` para obtener una salida
36
+ legible por máquina.
37
+
38
+ El resto de esta página es el mismo flujo ejecutado paso a paso, que es lo que
39
+ conviene si algo sale mal o si se quiere automatizar por cuenta propia.
40
+
41
+ ## Antes de empezar
42
+
43
+ - **Node 18 o posterior** (`node -v`). No hay nada más que instalar: `npx`
44
+ descarga la CLI, y los `scripts/dist/*.js` del repositorio clonado son
45
+ paquetes autocontenidos.
46
+ - **Una billetera** que tenga la moneda con la que se quiere pagar, en la cadena elegida.
47
+ - **El enlace de Coinbase**, por ejemplo
48
+ `https://payments.coinbase.com/payment-links/pl_01YOURLINKID`.
49
+ - Sin cuenta y sin clave de API. Todos los endpoints de aquí son públicos.
50
+
51
+ Definirlo una sola vez:
52
+
53
+ ```bash
54
+ LINK="https://payments.coinbase.com/payment-links/pl_01YOURLINKID"
55
+ ```
56
+
57
+ Ids de cadena: `1` Ethereum · `56` BNB Chain · `137` Polygon · `8453` Base ·
58
+ `900` Solana · `1500` Stellar · `lightning` Bitcoin Lightning.
59
+
60
+ ## ¿Qué wallet necesito?
61
+
62
+ **Una wallet, en una cadena: no hace falta una por cada cadena.** Elige la
63
+ moneda que ya tengas y paga desde donde ya esté.
64
+
65
+ Sirve cualquier wallet, y también un retiro desde un exchange: el Mode A de
66
+ abajo solo imprime un bloque de depósito, y envías exactamente ese `amount` de
67
+ ese `tokenSymbol`, en esa `chain`, a esa `receiverAddress`. Nada se conecta a
68
+ ningún sitio ni se aprueba en el navegador. En la práctica la gente usa
69
+ MetaMask o Rabby en las cadenas EVM, Phantom o Solflare en Solana, y una wallet
70
+ Lightning como Phoenix o Wallet of Satoshi para BTC.
71
+
72
+ Dos casos son distintos. **Stellar** se enruta mediante una dirección
73
+ compartida más `receiverMemo`, así que aquello desde lo que envíes debe
74
+ permitirte fijar un memo: si lo omites, el pago se pierde. **Lightning** paga
75
+ la factura BOLT11 de `deposit.lnInvoice`; no hay ninguna dirección a la que
76
+ enviar.
77
+
78
+ Solo `--send` (Mode B) necesita una clave, y cubre únicamente las cadenas EVM y
79
+ Solana: en Solana usa el `~/.config/solana/id.json` que `solana-keygen` ya creó,
80
+ y en EVM un keystore cifrado cuya frase de contraseña se solicita. Una clave en
81
+ bruto en el entorno queda para la automatización desatendida.
82
+
83
+ ## 1. Cotizarlo (solo lectura, gratis)
84
+
85
+ ```bash
86
+ node scripts/dist/quote.js --url "$LINK"
87
+ ```
88
+
89
+ ```json
90
+ {
91
+ "success": true,
92
+ "merchant": "OpenRouter, Inc.",
93
+ "invoice": { "amount": "1050.00", "fiat": { "amount": "1050.00", "currency": "USD" } },
94
+ "callerPays": "1050.00",
95
+ "coinbaseExpiryIso": "2026-08-09T10:00:00.000Z"
96
+ }
97
+ ```
98
+
99
+ Un `"success": false` con `LINK_NO_LONGER_PAYABLE` significa que el enlace ya
100
+ está usado o expirado: pedir uno nuevo y detenerse.
101
+
102
+ ## 2. Crear la orden
103
+
104
+ ```bash
105
+ node scripts/dist/create-order.js --url "$LINK" --chain 900 --token USDT
106
+ ```
107
+
108
+ No se mueve dinero, y una orden sin fondear simplemente expira. La dirección de
109
+ depósito (deposit address) completa se **retiene** en esta etapa: se obtiene un
110
+ resumen enmascarado para revisarlo primero.
111
+
112
+ ```json
113
+ {
114
+ "success": true,
115
+ "rozoPaymentId": "11111111-2222-4333-8444-555555555555",
116
+ "invoice": { "amount": "1050.000000", "currency": "USD" },
117
+ "deposit": null,
118
+ "depositWithheld": true,
119
+ "display": {
120
+ "chain": "Solana",
121
+ "amount": "1054.410000 USDT",
122
+ "payToMasked": "9WzDXw...AWWM"
123
+ },
124
+ "expiry": { "effectiveDeadlineIso": "2026-08-08T11:00:00.000Z", "minutesOfSlack": 55 }
125
+ }
126
+ ```
127
+
128
+ Este ejemplo es el caso insignia: una factura de **$1,050.00** por $1,000 de
129
+ créditos de OpenRouter. Cualquier factura de hasta **$1,100** se puede pagar así.
130
+
131
+ **Revisar `display.amount` antes de continuar.** Normalmente es mayor que la
132
+ factura: incluye las comisiones del puente (bridge) y de la red. Anotar el
133
+ `rozoPaymentId`; todos los comandos posteriores lo usan.
134
+
135
+ ## 3. Confirmar
136
+
137
+ Solo una vez que se ha decidido pagar, volver a ejecutar el mismo comando con `--confirm`:
138
+
139
+ ```bash
140
+ node scripts/dist/create-order.js --url "$LINK" --chain 900 --token USDT --confirm
141
+ ```
142
+
143
+ Esto libera el detalle completo del depósito y registra la confirmación que
144
+ exigen los scripts de envío.
145
+
146
+ ```json
147
+ {
148
+ "success": true,
149
+ "confirmed": true,
150
+ "deposit": {
151
+ "chain": "Solana",
152
+ "tokenSymbol": "USDT",
153
+ "receiverAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
154
+ "receiverMemo": "rozo-901",
155
+ "amount": "1054.410000",
156
+ "payTo": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
157
+ }
158
+ }
159
+ ```
160
+
161
+ Enviar exactamente los campos que entrega este bloque. Para Lightning,
162
+ `deposit.lnInvoice` contiene la cadena BOLT11 que hay que escanear, y
163
+ `deposit.amount` está en satoshis.
164
+
165
+ ## 4. Pagar
166
+
167
+ ### La forma sencilla: desde la propia billetera
168
+
169
+ **Sin clave privada, sin variables de entorno, sin configuración.** Abrir
170
+ cualquier billetera y enviar exactamente lo que indica el bloque `deposit` de
171
+ arriba:
172
+
173
+ - el `amount` del `tokenSymbol`,
174
+ - en la `chain`,
175
+ - a la `receiverAddress`, copiada del JSON, nunca tecleada de nuevo.
176
+
177
+ Si el bloque contiene algún otro campo, como `receiverMemo`, incluirlo tal cual;
178
+ forma parte del destino en esa cadena. Para Lightning, escanear o pegar
179
+ `deposit.lnInvoice` en su lugar.
180
+
181
+ Eso es todo el Modo A. Continuar en el paso 5.
182
+
183
+ ### La forma opcional: dejar que el script pague (Modo B)
184
+
185
+ Solo si se quiere que esta máquina firme, y únicamente en cadenas EVM y Solana.
186
+ Esta es la única parte que necesita una clave.
187
+
188
+ **Solana: usar el par de claves que ya se tiene.** Si alguna vez se ejecutó
189
+ `solana-keygen`, `~/.config/solana/id.json` ya existe y se usa automáticamente:
190
+
191
+ ```bash
192
+ node scripts/dist/send-sol.js --rozo-payment-id <rozoPaymentId> --send
193
+ ```
194
+
195
+ **EVM: usar un keystore cifrado.** Exportar un keystore JSON V3 desde la
196
+ billetera y apuntar a él. La frase de contraseña (passphrase) se solicita de
197
+ forma interactiva; nunca se pasa como bandera:
198
+
199
+ ```bash
200
+ ROZO_CHECKOUT_EVM_KEYSTORE=~/wallets/hot.json \
201
+ node scripts/dist/send-evm.js --rozo-payment-id <rozoPaymentId> --send
202
+ ```
203
+
204
+ Cualquiera de los dos archivos se puede indicar explícitamente con
205
+ `--keyfile <path>`, y `--dry-run` funciona con todas las fuentes: deriva la
206
+ dirección y ejecuta todas las comprobaciones sin firmar nada.
207
+
208
+ **Para automatización desatendida**, donde nadie puede escribir una frase de
209
+ contraseña, una clave en bruto en el entorno sigue funcionando igual que antes:
210
+ `ROZO_CHECKOUT_SOL_KEY` o `ROZO_CHECKOUT_EVM_KEY`, o bien
211
+ `ROZO_CHECKOUT_KEYSTORE_PASSPHRASE` junto a un keystore. En una máquina que usa
212
+ una persona, es preferible un archivo de claves.
213
+
214
+ Estos ajustes también pueden vivir en un `.env` en el directorio desde el que se
215
+ ejecuta (o `--env-file <path>`). Solo se leen de él las claves `ROZO_CHECKOUT_*`,
216
+ se analiza como texto plano y nunca se pasa por un shell, y lo que ya esté en el
217
+ entorno real tiene prioridad. **Añadir `.env` al `.gitignore`.**
218
+
219
+ Un archivo de claves o un `.env` no debe ser legible por otros usuarios
220
+ (`chmod 600`) ni estar bajo seguimiento de git. Ambos casos se rechazan, no se advierten.
221
+
222
+ <details>
223
+ <summary><b>Configurar una billetera local para <code>--send</code></b> — plantilla .env y pasos de exportación por billetera</summary>
224
+
225
+ **Nada de esto hace falta para la ruta por defecto.** Pagar desde la propia
226
+ billetera no necesita clave ni configuración, y funciona con billeteras que aquí
227
+ nunca se pueden usar, incluidas las de hardware y las cuentas de exchange.
228
+
229
+ Un `.env` en el directorio desde el que se ejecuta, con todas las variables que
230
+ esta herramienta lee:
231
+
232
+ ```bash
233
+ # Nada de esto hace falta para pagar desde la propia billetera. Solo se lee
234
+ # cuando se usa --send.
235
+
236
+ # Clave secreta de Solana: una cadena base58 o un arreglo JSON de bytes. Solo
237
+ # hace falta si NO se tiene ~/.config/solana/id.json, que se detecta solo.
238
+ ROZO_CHECKOUT_SOL_KEY=REPLACE_ME_base58_secret_key
239
+
240
+ # Clave privada EVM en bruto: 0x seguido de 64 caracteres hex. La opción menos
241
+ # segura: es preferible el keystore de abajo.
242
+ ROZO_CHECKOUT_EVM_KEY=0x0000000000000000000000000000000000000000000000000000000000000000
243
+
244
+ # Keystore V3 cifrado para EVM: ruta al archivo. Preferible a la clave en bruto.
245
+ ROZO_CHECKOUT_EVM_KEYSTORE=/replace/me/keystores/my-hot-wallet
246
+
247
+ # Frase de contraseña de ese keystore. Solo para ejecuciones desatendidas; en
248
+ # una terminal se solicita y no se guarda nada.
249
+ ROZO_CHECKOUT_KEYSTORE_PASSPHRASE=REPLACE_ME_not_a_real_passphrase
250
+
251
+ # Sobrescrituras de RPC opcionales, una por id de cadena. 8453 = Base,
252
+ # 900 = Solana.
253
+ ROZO_CHECKOUT_RPC_8453=https://mainnet.base.org
254
+ ROZO_CHECKOUT_RPC_900=https://api.mainnet-beta.solana.com
255
+ ```
256
+
257
+ Después, restringir permisos y mantenerlo fuera de git:
258
+
259
+ ```bash
260
+ chmod 600 .env
261
+ echo '.env' >> .gitignore
262
+ ```
263
+
264
+ **Solana**
265
+
266
+ - `solana-keygen new` escribe `~/.config/solana/id.json`. No hay nada que
267
+ configurar: se encuentra automáticamente. Es la ruta recomendada.
268
+ - **Phantom** → Settings → Export Private Key da una cadena **base58**. Va en
269
+ `ROZO_CHECKOUT_SOL_KEY`.
270
+ - **Solflare** exporta una cadena base58 en las versiones actuales y un arreglo
271
+ JSON de bytes en las antiguas. Ambos se aceptan tal cual.
272
+
273
+ **EVM**
274
+
275
+ - **MetaMask** y **Rabby** exportan la clave privada como 64 caracteres hex.
276
+ Pegarla tal cual en `ROZO_CHECKOUT_EVM_KEY`; el prefijo `0x` es opcional.
277
+ - **Keystore cifrado (más seguro).** Las billeteras de navegador exportan claves
278
+ en bruto, no keystores. Para convertir una en un keystore cifrado, usar
279
+ Foundry: `cast wallet import my-hot-wallet --interactive` pide la clave y
280
+ escribe un keystore V3 cifrado en `~/.foundry/keystores/my-hot-wallet`
281
+ (`--keystore-dir` cambia la ubicación). Apuntar `ROZO_CHECKOUT_EVM_KEYSTORE` a
282
+ ese archivo. `geth account import` también genera un keystore V3.
283
+
284
+ **Billeteras que no se pueden usar con `--send`:** billeteras de hardware
285
+ (Ledger, Trezor), billeteras móviles solo con WalletConnect y cuentas de
286
+ exchange. Por diseño, ninguna entrega una clave de firma. Esos casos usan la
287
+ ruta por defecto sin clave, que funciona con todas ellas.
288
+
289
+ </details>
290
+
291
+ Un solo pago no puede superar **$1,100**; por encima de eso, pagar desde la
292
+ propia billetera como arriba.
293
+
294
+ ```json
295
+ {
296
+ "success": true,
297
+ "submitted": true,
298
+ "confirmed": true,
299
+ "txHash": "3Bxs4h24hBjHziQ8UJqSjqjbjWQq2sQ3yV9Fq4HrVh5c"
300
+ }
301
+ ```
302
+
303
+ ## 5. Observar la liquidación
304
+
305
+ ```bash
306
+ node scripts/dist/status.js --rozo-payment-id <rozoPaymentId> --watch --timeout 600
307
+ ```
308
+
309
+ ```json
310
+ {
311
+ "success": true,
312
+ "state": "settled",
313
+ "terminal": true,
314
+ "payin": { "txHash": "3Bxs4h24...", "confirmedAt": "2026-08-08T10:05:00.000Z" }
315
+ }
316
+ ```
317
+
318
+ Los estados van `awaiting_deposit` → `payin_detected` → `payin_confirmed` →
319
+ `bridging` → `paying_coinbase` → `settled`. Que la transacción on-chain se
320
+ confirme no es el final: seguir consultando hasta `settled`.
321
+
322
+ ## Si algo sale mal
323
+
324
+ Leer `error.code`. Los tres con los que es más probable toparse:
325
+
326
+ | `error.code` | Qué ocurrió | Qué hacer |
327
+ |---|---|---|
328
+ | `LINK_NO_LONGER_PAYABLE` | alguien ya pagó el enlace, o expiró | pedir al comercio un enlace nuevo; no pagar nada |
329
+ | `EXPIRY_MARGIN` | queda muy poco tiempo para fondear, puentear y liquidar de forma segura | dejar que la orden expire y volver a empezar desde el paso 1 |
330
+ | `ALREADY_SENT` | ya hay un envío registrado para esta orden | **no** enviar de nuevo; ejecutar `status.js` y revisar primero la cadena |
331
+
332
+ **Si algo de dinero ya salió de la billetera, nunca pagar de nuevo.** Conservar
333
+ el `linkId`, el `rozoPaymentId` y todos los hashes de transacción, y pedir a una
334
+ persona que lo concilie. No hay garantía de que un segundo pago a una dirección
335
+ de depósito de un solo uso sea acreditado.
336
+
337
+ La tabla completa de errores está en [README.md](../README.md), y las instrucciones
338
+ dirigidas al agente están en [SKILL.md](../SKILL.md).
@@ -0,0 +1,315 @@
1
+ # クイックスタート
2
+
3
+ [English](QUICKSTART.md) | [简体中文](QUICKSTART.zh.md) | **日本語** | [Español](QUICKSTART.es.md)
4
+
5
+ OpenRouter の Coinbase 決済リンク (Payment Link) を、Solana、BNB Chain、
6
+ Ethereum、Polygon、Base、Stellar 上の USDT/USDC、または Lightning 経由の BTC で支払います。所要 5 分。
7
+ 仕組みと設計意図については [README.md](../README.md) を参照してください。
8
+
9
+ ## ワンライナー
10
+
11
+ ```bash
12
+ npx @rozoai/checkout pay https://payments.coinbase.com/payment-links/pl_01YOURLINKID
13
+ ```
14
+
15
+ これ 1 つで、以下の全ステップを実行します。通貨の選択、見積もり、注文作成、確認、承認、
16
+ 入金手順の表示、そして決済完了までのポーリングです。通貨を選ぶ場面でウォレットアドレスを
17
+ 貼り付けると、残高を調べてどの通貨なら支払えるかを表示します。これは任意で、実際に署名
18
+ される内容は一切変わりません。
19
+
20
+ 使う通貨が決まっている場合は、指定すればこの質問を省略できます:
21
+
22
+ ```bash
23
+ npx @rozoai/checkout pay https://payments.coinbase.com/payment-links/pl_01YOURLINKID --with usdt-solana
24
+ ```
25
+
26
+ `--with` に指定できる通貨: `usdt-solana`、
27
+ `usdc-solana`、`usdt-bnb`、`usdc-bnb`、`usdt-ethereum`、`usdc-ethereum`、
28
+ `usdt-polygon`、`usdc-polygon`、`usdc-base`、`usdc-stellar`、`btc-lightning`。
29
+ スクリプトやエージェントでは必ず `--with` を渡してください。対話式の選択は端末でのみ
30
+ 表示され、既定の通貨はありません。
31
+
32
+ 既定では、任意のウォレットから支払うためのアドレスを表示するだけです — 鍵も設定も
33
+ 不要です。CLI にホットウォレットから署名させたい場合にだけ `--send` を、機械可読な
34
+ 出力が必要な場合は `--json` を追加してください。
35
+
36
+ このページの残りは、同じフローを 1 ステップずつ実行するものです。うまくいかないときや、
37
+ 自分でスクリプトを書くときは、こちらが必要になります。
38
+
39
+ ## 始める前に
40
+
41
+ - **Node 18 以降**(`node -v`)。ほかにインストールするものはありません — `npx` が CLI を
42
+ 取得しますし、クローンした `scripts/dist/*.js` は自己完結型のバンドルです。
43
+ - 選んだチェーン上で、支払いたい通貨を保有している**ウォレット**。
44
+ - **Coinbase のリンク**。例:
45
+ `https://payments.coinbase.com/payment-links/pl_01YOURLINKID`。
46
+ - アカウントも API キーも不要です。ここで使うエンドポイントはすべて公開です。
47
+
48
+ 最初に一度だけ設定します:
49
+
50
+ ```bash
51
+ LINK="https://payments.coinbase.com/payment-links/pl_01YOURLINKID"
52
+ ```
53
+
54
+ チェーン id: `1` Ethereum · `56` BNB Chain · `137` Polygon · `8453` Base ·
55
+ `900` Solana · `1500` Stellar · `lightning` Bitcoin Lightning。
56
+
57
+ ## どのウォレットが必要ですか?
58
+
59
+ **ウォレットは 1 つ、チェーンも 1 つで足ります — チェーンごとに用意する必要はありません。**すでに持っている通貨を選び、それが今ある場所から支払ってください。
60
+
61
+ どのウォレットでも構いませんし、取引所からの出金でも構いません。下記の Mode A は入金情報を表示するだけで、示された `amount` の `tokenSymbol` を、その `chain` 上で `receiverAddress` へ送るだけです。どのサイトに接続することも、ブラウザで承認することもありません。実際には、EVM チェーンでは MetaMask や Rabby、Solana では Phantom や Solflare、BTC では Phoenix や Wallet of Satoshi といった Lightning ウォレットがよく使われています。
62
+
63
+ 異なるケースが 2 つあります。**Stellar** は共有アドレスと `receiverMemo` の組み合わせで振り分けられるため、送信元で memo を設定できる必要があります。memo を省くと、その支払いは失われます。**Lightning** は `deposit.lnInvoice` にある BOLT11 インボイスに支払います。送金先アドレスというものはありません。
64
+
65
+ 鍵が必要なのは `--send`(Mode B)だけで、対象は EVM チェーンと Solana のみです。Solana では `solana-keygen` が既に作成した `~/.config/solana/id.json` を、EVM では暗号化された keystore(パスフレーズは対話的に入力)を使います。環境変数の生の鍵は無人自動化向けに残されています。
66
+
67
+ ## 1. 見積もりを取得する(読み取り専用、無料)
68
+
69
+ ```bash
70
+ node scripts/dist/quote.js --url "$LINK"
71
+ ```
72
+
73
+ ```json
74
+ {
75
+ "success": true,
76
+ "merchant": "OpenRouter, Inc.",
77
+ "invoice": { "amount": "1050.00", "fiat": { "amount": "1050.00", "currency": "USD" } },
78
+ "callerPays": "1050.00",
79
+ "coinbaseExpiryIso": "2026-08-09T10:00:00.000Z"
80
+ }
81
+ ```
82
+
83
+ `"success": false` かつ `LINK_NO_LONGER_PAYABLE` の場合、そのリンクは使用済みか
84
+ 期限切れです — 新しいリンクを依頼し、そこで中止してください。
85
+
86
+ ## 2. 注文を作成する
87
+
88
+ ```bash
89
+ node scripts/dist/create-order.js --url "$LINK" --chain 900 --token USDT
90
+ ```
91
+
92
+ 資金は動かず、入金のない注文はそのまま期限切れになります。この段階では完全な
93
+ 入金アドレス (deposit address) は**伏せられます** — まず確認用にマスクされたサマリーが返ります。
94
+
95
+ ```json
96
+ {
97
+ "success": true,
98
+ "rozoPaymentId": "11111111-2222-4333-8444-555555555555",
99
+ "invoice": { "amount": "1050.000000", "currency": "USD" },
100
+ "deposit": null,
101
+ "depositWithheld": true,
102
+ "display": {
103
+ "chain": "Solana",
104
+ "amount": "1054.410000 USDT",
105
+ "payToMasked": "9WzDXw...AWWM"
106
+ },
107
+ "expiry": { "effectiveDeadlineIso": "2026-08-08T11:00:00.000Z", "minutesOfSlack": 55 }
108
+ }
109
+ ```
110
+
111
+ この例は代表的なケースです。$1,000 分の OpenRouter クレジットに対する **$1,050.00**
112
+ のインボイスです。**$1,100** までのインボイスであれば同じ方法で支払えます。
113
+
114
+ **先へ進む前に必ず `display.amount` を確認してください。** 通常はインボイス金額より
115
+ 大きくなります — ブリッジ (bridge) 手数料とネットワーク手数料が含まれるためです。`rozoPaymentId` を
116
+ 控えておいてください。以降のコマンドはすべてこれを使います。
117
+
118
+ ## 3. 確認する
119
+
120
+ 支払うと決めたときにだけ、同じコマンドを `--confirm` 付きで実行し直してください:
121
+
122
+ ```bash
123
+ node scripts/dist/create-order.js --url "$LINK" --chain 900 --token USDT --confirm
124
+ ```
125
+
126
+ これで完全な入金詳細が開示され、送金スクリプトが要求する確認記録が残ります。
127
+
128
+ ```json
129
+ {
130
+ "success": true,
131
+ "confirmed": true,
132
+ "deposit": {
133
+ "chain": "Solana",
134
+ "tokenSymbol": "USDT",
135
+ "receiverAddress": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
136
+ "receiverMemo": "rozo-901",
137
+ "amount": "1054.410000",
138
+ "payTo": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
139
+ }
140
+ }
141
+ ```
142
+
143
+ このブロックが示すフィールドを、そのとおりに送金してください。Lightning の場合、
144
+ `deposit.lnInvoice` にスキャン用の BOLT11 文字列が入り、`deposit.amount` は
145
+ satoshi 単位になります。
146
+
147
+ ## 4. 支払う
148
+
149
+ ### 簡単な方法: 自分のウォレットから
150
+
151
+ **秘密鍵も環境変数も設定も一切不要です。** 好きなウォレットを開き、上の `deposit`
152
+ ブロックが示すとおりに送金してください:
153
+
154
+ - `tokenSymbol` を `amount` だけ、
155
+ - `chain` の上で、
156
+ - `receiverAddress` へ — JSON からコピーし、決して手入力し直さないでください。
157
+
158
+ ブロックに `receiverMemo` などそれ以外のフィールドが含まれている場合は、示されたとおりに
159
+ そのまま付けてください。それはそのチェーンにおけるアドレスの一部です。Lightning の場合は
160
+ 代わりに `deposit.lnInvoice` をスキャンするか貼り付けてください。
161
+
162
+ モード A はこれで全部です。ステップ 5 へ進んでください。
163
+
164
+ ### 任意の方法: スクリプトに支払わせる(モード B)
165
+
166
+ このマシンに署名させたい場合のみで、対象は EVM チェーンと Solana だけです。鍵が
167
+ 必要なのはこの部分だけです。
168
+
169
+ **Solana — すでにある鍵ペアをそのまま使います。** `solana-keygen` を一度でも実行して
170
+ いれば `~/.config/solana/id.json` が既に存在し、自動的に使われます:
171
+
172
+ ```bash
173
+ node scripts/dist/send-sol.js --rozo-payment-id <rozoPaymentId> --send
174
+ ```
175
+
176
+ **EVM — 暗号化された keystore を使います。** ウォレットから V3 形式の JSON keystore を
177
+ 書き出し、それを指定してください。パスフレーズは対話的に尋ねられ、フラグとして渡す
178
+ ことは決してありません:
179
+
180
+ ```bash
181
+ ROZO_CHECKOUT_EVM_KEYSTORE=~/wallets/hot.json \
182
+ node scripts/dist/send-evm.js --rozo-payment-id <rozoPaymentId> --send
183
+ ```
184
+
185
+ どちらのファイルも `--keyfile <path>` で明示的に指定できます。`--dry-run` はすべての
186
+ 取得元で機能し、アドレスを導出してすべてのチェックを実行しますが、署名は行いません。
187
+
188
+ **無人自動化の場合**(パスフレーズを入力できる人がいない場合)は、環境変数の生の鍵が
189
+ これまでどおり使えます — `ROZO_CHECKOUT_SOL_KEY` または `ROZO_CHECKOUT_EVM_KEY`、
190
+ あるいは keystore と併せて `ROZO_CHECKOUT_KEYSTORE_PASSPHRASE` です。人が使うマシンでは
191
+ 鍵ファイルを優先してください。
192
+
193
+ これらの設定は、実行するディレクトリの `.env` に置くこともできます(`--env-file <path>`
194
+ でも指定できます)。読み込まれるのは `ROZO_CHECKOUT_*` のキーだけで、ファイルはテキスト
195
+ として解析され、シェルで評価されることは決してありません。実際の環境変数のほうが優先
196
+ されます。**`.env` は `.gitignore` に追加してください。**
197
+
198
+ 鍵ファイルと `.env` は他のユーザーから読めてはならず(`chmod 600`)、git で追跡されて
199
+ いてもいけません。どちらの場合も警告ではなく拒否されます。
200
+
201
+ <details>
202
+ <summary><b><code>--send</code> 用のローカルウォレット設定</b> — .env テンプレートとウォレット別の書き出し手順</summary>
203
+
204
+ **既定の経路ではここに書かれたものは一切不要です。** 自分のウォレットから支払う場合、
205
+ 鍵も設定も要りません。しかもここでは決して使えないウォレット — ハードウェアウォレットや
206
+ 取引所アカウントを含む — でも支払えます。
207
+
208
+ コマンドを実行するディレクトリに `.env` を置きます。本ツールが読み取る変数の全一覧です:
209
+
210
+ ```bash
211
+ # 自分のウォレットから支払う場合、以下はどれも不要です。--send を使うときだけ
212
+ # 読み込まれます。
213
+
214
+ # Solana の秘密鍵: base58 文字列、または JSON のバイト配列。
215
+ # ~/.config/solana/id.json (自動的に使われます) が無い場合にのみ必要です。
216
+ ROZO_CHECKOUT_SOL_KEY=REPLACE_ME_base58_secret_key
217
+
218
+ # EVM の生の秘密鍵: 0x + 16 進 64 文字。最も安全でない選択肢です。
219
+ # 下の keystore を優先してください。
220
+ ROZO_CHECKOUT_EVM_KEY=0x0000000000000000000000000000000000000000000000000000000000000000
221
+
222
+ # EVM の暗号化 V3 keystore: そのファイルへのパス。上の生の鍵より推奨されます。
223
+ ROZO_CHECKOUT_EVM_KEYSTORE=/replace/me/keystores/my-hot-wallet
224
+
225
+ # その keystore のパスフレーズ。無人実行のときだけ必要で、端末では対話的に
226
+ # 尋ねられ、保存もされません。
227
+ ROZO_CHECKOUT_KEYSTORE_PASSPHRASE=REPLACE_ME_not_a_real_passphrase
228
+
229
+ # 任意の RPC 上書き。チェーン id ごとに 1 行。8453 = Base、900 = Solana。
230
+ ROZO_CHECKOUT_RPC_8453=https://mainnet.base.org
231
+ ROZO_CHECKOUT_RPC_900=https://api.mainnet-beta.solana.com
232
+ ```
233
+
234
+ そのうえで権限を絞り、git に入らないようにします:
235
+
236
+ ```bash
237
+ chmod 600 .env
238
+ echo '.env' >> .gitignore
239
+ ```
240
+
241
+ **Solana**
242
+
243
+ - `solana-keygen new` は `~/.config/solana/id.json` を書き出します。設定は不要で、
244
+ 自動的に見つかります。これが推奨の経路です。
245
+ - **Phantom** → Settings → Export Private Key で得られるのは **base58** 文字列です。
246
+ `ROZO_CHECKOUT_SOL_KEY` に設定してください。
247
+ - **Solflare** は現行バージョンでは base58 文字列、古いバージョンでは JSON のバイト配列を
248
+ 書き出します。どちらもそのまま使えます。
249
+
250
+ **EVM**
251
+
252
+ - **MetaMask** と **Rabby** の秘密鍵の書き出しは 16 進 64 文字です。そのまま
253
+ `ROZO_CHECKOUT_EVM_KEY` に貼り付けてください。`0x` 接頭辞は付けても付けなくても
254
+ 構いません。
255
+ - **暗号化 keystore (より安全)。** ブラウザーウォレットが書き出せるのは生の鍵だけで、
256
+ keystore ではありません。生の鍵を暗号化 keystore に変えるには Foundry を使います:
257
+ `cast wallet import my-hot-wallet --interactive` が鍵の入力を促し、暗号化された
258
+ V3 keystore を `~/.foundry/keystores/my-hot-wallet` に書き出します
259
+ (`--keystore-dir` で場所を変更できます)。`ROZO_CHECKOUT_EVM_KEYSTORE` をその
260
+ ファイルに向けてください。`geth account import` も V3 keystore を生成します。
261
+
262
+ **`--send` に使えないウォレット:** ハードウェアウォレット (Ledger、Trezor)、
263
+ WalletConnect 専用のモバイルウォレット、取引所アカウント。いずれも設計上、署名鍵を
264
+ 渡しません。これらの場合は既定の鍵なしの経路を使ってください — すべてで動作します。
265
+
266
+ </details>
267
+
268
+ 1 回の支払いは **$1,100** を超えられません。それ以上は上記のとおり自分のウォレットから
269
+ 支払ってください。
270
+
271
+ ```json
272
+ {
273
+ "success": true,
274
+ "submitted": true,
275
+ "confirmed": true,
276
+ "txHash": "3Bxs4h24hBjHziQ8UJqSjqjbjWQq2sQ3yV9Fq4HrVh5c"
277
+ }
278
+ ```
279
+
280
+ ## 5. 決済完了を監視する
281
+
282
+ ```bash
283
+ node scripts/dist/status.js --rozo-payment-id <rozoPaymentId> --watch --timeout 600
284
+ ```
285
+
286
+ ```json
287
+ {
288
+ "success": true,
289
+ "state": "settled",
290
+ "terminal": true,
291
+ "payin": { "txHash": "3Bxs4h24...", "confirmedAt": "2026-08-08T10:05:00.000Z" }
292
+ }
293
+ ```
294
+
295
+ 状態は `awaiting_deposit` → `payin_detected` → `payin_confirmed` →
296
+ `bridging` → `paying_coinbase` → `settled` と遷移します。オンチェーンの
297
+ トランザクションが確認されても終わりではありません: `settled` になるまでポーリングを続けてください。
298
+
299
+ ## うまくいかないとき
300
+
301
+ `error.code` を読んでください。遭遇しやすいのは次の 3 つです:
302
+
303
+ | `error.code` | 何が起きたか | どうするか |
304
+ |---|---|---|
305
+ | `LINK_NO_LONGER_PAYABLE` | そのリンクは既に誰かが支払ったか、期限切れです | 加盟店に新しいリンクを依頼してください。何も支払わないこと |
306
+ | `EXPIRY_MARGIN` | 入金・ブリッジ・決済完了を安全に行うには残り時間が足りません | その注文は期限切れにさせ、ステップ 1 からやり直してください |
307
+ | `ALREADY_SENT` | この注文に対する送金が既に記録されています | 再送信しては**いけません**。まず `status.js` を実行し、チェーンを確認してください |
308
+
309
+ **ウォレットから既に資金が出ている場合は、決して二重に支払わないでください。**
310
+ `linkId`、`rozoPaymentId`、すべてのトランザクションハッシュを保管し、人間に照合を
311
+ 依頼してください。使い捨ての入金アドレスへの 2 回目の支払いは、入金として反映される
312
+ 保証がありません。
313
+
314
+ エラーコードの完全な一覧は [README.md](../README.md) に、エージェント向けの指示は
315
+ [SKILL.md](../SKILL.md) にあります。