rail0-sdk 1.8.1 → 1.10.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.
- checksums.yaml +4 -4
- data/README.md +203 -3
- data/lib/rail0/client.rb +10 -1
- data/lib/rail0/error_hints.rb +24 -0
- data/lib/rail0/http_client.rb +2 -1
- data/lib/rail0/payout_verify.rb +211 -0
- data/lib/rail0/request.rb +19 -1
- data/lib/rail0/resources/chains.rb +51 -1
- data/lib/rail0/resources/payments.rb +8 -3
- data/lib/rail0/resources/payout_destinations.rb +234 -0
- data/lib/rail0/resources/payouts.rb +186 -0
- data/lib/rail0/resources/webhooks.rb +7 -0
- data/lib/rail0/signing.rb +46 -0
- data/lib/rail0/tx_verify.rb +3 -2
- data/lib/rail0/types.rb +185 -56
- data/lib/rail0/version.rb +1 -1
- metadata +5 -2
data/lib/rail0/types.rb
CHANGED
|
@@ -43,10 +43,24 @@ module Rail0
|
|
|
43
43
|
# A single balance line — the native gas token or one ERC-20.
|
|
44
44
|
AssetBalance = Struct.new(
|
|
45
45
|
:symbol, # String
|
|
46
|
-
:address, # Token contract address; null for the native balance.
|
|
46
|
+
:address, # String | nil — Token contract address; null for the native balance.
|
|
47
47
|
:decimals, # Integer
|
|
48
48
|
:raw, # String — Balance in base units (exact).
|
|
49
49
|
:amount, # String — Human-decimal balance.
|
|
50
|
+
:payout, # What a payout in this token keeps back for gas — on every ERC-20 line; null on the native balance.
|
|
51
|
+
keyword_init: true
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
# The gas figures of a payout in this token on this chain: whether the chain's gas IS this very
|
|
55
|
+
# token (`native_gas`; Arc's USDC) and, then, the allowance POST /payouts/prepare keeps back from
|
|
56
|
+
# `all`, from a typed amount's ceiling and from the proof (`gas_allowance` = gas_limit ×
|
|
57
|
+
# max_fee_per_gas in base units, the charge the EVM takes before a transfer runs; `0` on any other
|
|
58
|
+
# chain). Null allowance when the fee could not be read. The reserves a payout keeps back are
|
|
59
|
+
# decided at payout time: GET /payout_destinations/{id}/reserves.
|
|
60
|
+
BalancePayout = Struct.new(
|
|
61
|
+
:native_gas, # Boolean
|
|
62
|
+
:gas_allowance, # String | nil
|
|
63
|
+
:gas_allowance_formatted, # String | nil
|
|
50
64
|
keyword_init: true
|
|
51
65
|
)
|
|
52
66
|
|
|
@@ -57,6 +71,15 @@ module Rail0
|
|
|
57
71
|
keyword_init: true
|
|
58
72
|
)
|
|
59
73
|
|
|
74
|
+
# What an account still has in motion (GET /admin/accounts/{id}/exposure, and `exposure` on a 409
|
|
75
|
+
# account_has_open_exposure).
|
|
76
|
+
AccountExposure = Struct.new(
|
|
77
|
+
:payments, # Hash
|
|
78
|
+
:payouts, # Hash
|
|
79
|
+
:empty, # Boolean — true when every count is zero.
|
|
80
|
+
keyword_init: true
|
|
81
|
+
)
|
|
82
|
+
|
|
60
83
|
# The error envelope: exactly code (stable, the only field to branch on), title (short label) and
|
|
61
84
|
# detail (a sentence a UI can print verbatim). The legacy status/message/error aliases were removed
|
|
62
85
|
# in #252.
|
|
@@ -170,9 +193,11 @@ module Rail0
|
|
|
170
193
|
Blockchain = Struct.new(
|
|
171
194
|
:chain_id, # Integer
|
|
172
195
|
:name, # String
|
|
196
|
+
:slug, # String — The chain's short name, the same for its testnet and its mainnet (`arc` is Arc Testnet on a testnet gateway, Arc on production): a gateway serves one network class, so a client may name the chain by slug instead of chain_id. Lowercase, unique per network class.
|
|
173
197
|
:native_symbol, # String
|
|
174
198
|
:network_type, # String
|
|
175
199
|
:explorer_url, # String
|
|
200
|
+
:public_rpc_urls, # Array — Public, keyless RPC endpoints published for clients that read the chain directly (a balance, a receipt), in failover order: try them in turn. Not necessarily the endpoints the gateway itself uses.
|
|
176
201
|
:required_confirmations, # Integer — Confirmations this gateway waits for before treating a transaction as settled. The FALLBACK rule: where the chain serves a finality tag (see finality_tag) that tag governs instead, so a client showing this number on such a chain is describing a rule that is not in force.
|
|
177
202
|
:finality_tag, # String — The block tag the chain calls settled (`safe`, `finalized`), when it serves one — and what the gateway actually gates on. Null where the chain serves none, in which case required_confirmations is counted.
|
|
178
203
|
:contract, # ChainContract
|
|
@@ -211,9 +236,9 @@ module Rail0
|
|
|
211
236
|
Wallet = Struct.new(
|
|
212
237
|
:id, # String
|
|
213
238
|
:address, # String
|
|
214
|
-
:label,
|
|
239
|
+
:label, # String | nil
|
|
215
240
|
:active, # Boolean
|
|
216
|
-
:deactivated_by, # Who switched the wallet off: `owner` (a session signed in with this wallet) or `operator` (an admin session). Null while active, and on a switch-off that predates the record — treated as `operator`. A wallet an operator switched off can be switched back on only by an operator (403 `wallet_deactivated_by_operator`). Always null on GET /payment_methods, which serves active wallets only.
|
|
241
|
+
:deactivated_by, # String | nil — Who switched the wallet off: `owner` (a session signed in with this wallet) or `operator` (an admin session). Null while active, and on a switch-off that predates the record — treated as `operator`. A wallet an operator switched off can be switched back on only by an operator (403 `wallet_deactivated_by_operator`). Always null on GET /payment_methods, which serves active wallets only.
|
|
217
242
|
keyword_init: true
|
|
218
243
|
)
|
|
219
244
|
|
|
@@ -232,9 +257,9 @@ module Rail0
|
|
|
232
257
|
WalletWithTokens = Struct.new(
|
|
233
258
|
:id, # String
|
|
234
259
|
:address, # String
|
|
235
|
-
:label,
|
|
260
|
+
:label, # String | nil
|
|
236
261
|
:active, # Boolean
|
|
237
|
-
:deactivated_by, # Who switched the wallet off: `owner` (a session signed in with this wallet) or `operator` (an admin session). Null while active, and on a switch-off that predates the record — treated as `operator`. A wallet an operator switched off can be switched back on only by an operator (403 `wallet_deactivated_by_operator`). Always null on GET /payment_methods, which serves active wallets only.
|
|
262
|
+
:deactivated_by, # String | nil — Who switched the wallet off: `owner` (a session signed in with this wallet) or `operator` (an admin session). Null while active, and on a switch-off that predates the record — treated as `operator`. A wallet an operator switched off can be switched back on only by an operator (403 `wallet_deactivated_by_operator`). Always null on GET /payment_methods, which serves active wallets only.
|
|
238
263
|
:tokens, # Array
|
|
239
264
|
keyword_init: true
|
|
240
265
|
)
|
|
@@ -255,21 +280,21 @@ module Rail0
|
|
|
255
280
|
:payer, # String
|
|
256
281
|
:payee, # String
|
|
257
282
|
:token, # String
|
|
258
|
-
:decimals, # Decimals of the payment's token: divide `amount`, `capturable_amount` and `refundable_amount` (base units) by 10^decimals to render them, with no GET /tokens join on `token` + `chain_id`. Resolved from the gateway's in-memory chain catalogue, retired tokens and archived contract versions included. Null only when the gateway cannot resolve the token (a contract it has not loaded, a token deleted outright) — fall back to GET /tokens then.
|
|
283
|
+
:decimals, # Integer | nil — Decimals of the payment's token: divide `amount`, `capturable_amount` and `refundable_amount` (base units) by 10^decimals to render them, with no GET /tokens join on `token` + `chain_id`. Resolved from the gateway's in-memory chain catalogue, retired tokens and archived contract versions included. Null only when the gateway cannot resolve the token (a contract it has not loaded, a token deleted outright) — fall back to GET /tokens then.
|
|
259
284
|
:authorization_expiry, # Integer
|
|
260
285
|
:refund_expiry, # Integer
|
|
261
286
|
:escrow_stranded, # Boolean — True exactly inside the stranded-escrow window (#233): a partial capture has permanently ruled void out, and release only opens at authorization_expiry — so no verb can return the buyer's uncaptured escrow until then. Mirrors RAIL0.sol; the gateway names the window, it cannot shorten it.
|
|
262
287
|
:escrow_returnable_at, # String — When the stranded escrow becomes returnable (release opens) — the authorization expiry as ISO-8601. Null whenever nothing is stranded, so presence alone is the signal.
|
|
263
288
|
:disputed, # Boolean — True while an open dispute exists.
|
|
264
289
|
:in_flight, # Boolean — True while one of the payment's transactions is on its way to the chain and not yet settled: status `submitting`, `submitted`, or `pending` holding its signed transaction (the `redrivable` rows — signed and handed over, broadcast not yet sent). A `pending` row still awaiting its signature (an unfinished prepare) does not count, nor do `confirmed`/`failed`. While true the mirrored balances are about to move, so a client should disable further actions on the payment. Carried by list rows too, which embed no transactions; computed for a whole page in one query.
|
|
265
|
-
:last_error_code, # Decoded reason of the last failed on-chain attempt; null once the payment makes forward progress. Non-null means the latest attempt failed.
|
|
266
|
-
:last_error_message, # Human-readable form of last_error_code.
|
|
267
|
-
:description,
|
|
268
|
-
:reference, # This payment's identifier in the merchant's own system; set at create, correctable by the payee.
|
|
269
|
-
:reference_origin, # The system the reference comes from, a lowercase slug (e.g. commercelayer).
|
|
270
|
-
:merchant_note, # The payee's internal note (PATCH /payments/{id}). Present only when the session is the payment's PAYEE, and on the operator's Full view; absent for the payer.
|
|
271
|
-
:metadata,
|
|
272
|
-
:signed_at, # When the payer signature was stored (null while unsigned).
|
|
290
|
+
:last_error_code, # String | nil — Decoded reason of the last failed on-chain attempt; null once the payment makes forward progress. Non-null means the latest attempt failed.
|
|
291
|
+
:last_error_message, # String | nil — Human-readable form of last_error_code.
|
|
292
|
+
:description, # String | nil
|
|
293
|
+
:reference, # String | nil — This payment's identifier in the merchant's own system; set at create, correctable by the payee.
|
|
294
|
+
:reference_origin, # String | nil — The system the reference comes from, a lowercase slug (e.g. commercelayer).
|
|
295
|
+
:merchant_note, # String | nil — The payee's internal note (PATCH /payments/{id}). Present only when the session is the payment's PAYEE, and on the operator's Full view; absent for the payer.
|
|
296
|
+
:metadata, # Hash | nil
|
|
297
|
+
:signed_at, # String | nil — When the payer signature was stored (null while unsigned).
|
|
273
298
|
:created_at, # String
|
|
274
299
|
:updated_at, # String
|
|
275
300
|
keyword_init: true
|
|
@@ -283,23 +308,23 @@ module Rail0
|
|
|
283
308
|
:reason, # String — On-chain bytes32 reason the dispute was opened with (hex); the all-zero word when no reason was given; kept verbatim even when it is outside the dispute-reason dictionary.
|
|
284
309
|
:reason_code, # DisputeOpenReason | nil — The DisputeOpenReason code `reason` reads as; null when no reason was given (the zero bytes32) or when the bytes32 is not in the dictionary (a direct contract call).
|
|
285
310
|
:reason_description, # String — English description of `reason_code`; "No reason given" when `reason` is the zero bytes32; "Unrecognised reason" when it is a non-zero bytes32 outside the dictionary.
|
|
286
|
-
:opened_block,
|
|
311
|
+
:opened_block, # Integer | nil
|
|
287
312
|
:opened_at, # String
|
|
288
|
-
:closed_by,
|
|
289
|
-
:close_reason, # On-chain bytes32 close reason (hex); the all-zero word when closed with no reason; null while the dispute is open.
|
|
313
|
+
:closed_by, # String | nil
|
|
314
|
+
:close_reason, # String | nil — On-chain bytes32 close reason (hex); the all-zero word when closed with no reason; null while the dispute is open.
|
|
290
315
|
:close_reason_code, # DisputeCloseReason | DisputeSystemCloseReason | nil — The code `close_reason` reads as: a DisputeCloseReason, or the system DisputeSystemCloseReason `full_refund` when a full refund auto-closed the dispute. Null while open, when closed with no reason (the zero bytes32), or when the bytes32 is not in the dictionary.
|
|
291
|
-
:close_reason_description, # English description of `close_reason_code`; "No reason given" when `close_reason` is the zero bytes32; "Unrecognised reason" when it is a non-zero bytes32 outside the dictionary; null while open.
|
|
292
|
-
:closed_block,
|
|
293
|
-
:closed_at,
|
|
316
|
+
:close_reason_description, # String | nil — English description of `close_reason_code`; "No reason given" when `close_reason` is the zero bytes32; "Unrecognised reason" when it is a non-zero bytes32 outside the dictionary; null while open.
|
|
317
|
+
:closed_block, # Integer | nil
|
|
318
|
+
:closed_at, # String | nil
|
|
294
319
|
keyword_init: true
|
|
295
320
|
)
|
|
296
321
|
|
|
297
322
|
# What the callback did with a test event (POST /webhooks/{id}/test).
|
|
298
323
|
WebhookTestResult = Struct.new(
|
|
299
324
|
:delivered, # Boolean — The endpoint answered 2xx.
|
|
300
|
-
:response_code, # The HTTP status it answered; null when no response came (see error_reason).
|
|
301
|
-
:response_message, # Up to 1000 printable characters of its response body.
|
|
302
|
-
:error_reason, # Why no response came: a refused address, a TLS or connection error, the deadline.
|
|
325
|
+
:response_code, # String | nil — The HTTP status it answered; null when no response came (see error_reason).
|
|
326
|
+
:response_message, # String | nil — Up to 1000 printable characters of its response body.
|
|
327
|
+
:error_reason, # String | nil — Why no response came: a refused address, a TLS or connection error, the deadline.
|
|
303
328
|
:duration_ms, # Integer — How long the attempt took.
|
|
304
329
|
keyword_init: true
|
|
305
330
|
)
|
|
@@ -310,22 +335,22 @@ module Rail0
|
|
|
310
335
|
:operation, # String — Which on-chain call this row attempts. A SUPERSET of the `{operation}` path enum: `dispute` and `close_dispute` have their own hand-written routes rather than living under the generic namespace, but they mint transaction rows like any other operation, so a generated client must be able to represent them.
|
|
311
336
|
:status, # String
|
|
312
337
|
:redrivable, # Boolean — True when this transaction's broadcast can be re-enqueued: it is `pending` and the gateway holds its signed transaction, i.e. a send that was prepared and signed but never reached the chain. The same predicate `POST /payments/{id}/transactions/{transaction_id}/redrive` guards on, so a client can offer the action exactly when it will succeed instead of on a 422. False on a `pending` row that holds no signed transaction - there the next step is submitting the signature, not a redrive.
|
|
313
|
-
:error_code, # Decoded failure code, null unless `status` is "failed". Same catalogue as an error body's `code`: a RAIL0 custom error (`not_payee`), a token-level revert (`insufficient_token_balance`, `invalid_token_signature`, `authorization_already_used`), a Solidity panic, or a rejection that stopped the broadcast before the chain saw it (`insufficient_gas_funds`, `nonce_too_low`).
|
|
338
|
+
:error_code, # String | nil — Decoded failure code, null unless `status` is "failed". Same catalogue as an error body's `code`: a RAIL0 custom error (`not_payee`), a token-level revert (`insufficient_token_balance`, `invalid_token_signature`, `authorization_already_used`), a Solidity panic, or a rejection that stopped the broadcast before the chain saw it (`insufficient_gas_funds`, `nonce_too_low`).
|
|
314
339
|
:error_title, # String — Short label for `error_code`; null unless failed.
|
|
315
340
|
:error_detail, # String — Sentence explaining the failure; null unless failed. Carries the chain's own words when the revert was not one the gateway recognises.
|
|
316
|
-
:unsigned_transaction,
|
|
317
|
-
:transaction_hash,
|
|
318
|
-
:sender, # The address that SIGNED the submitted transaction, recovered from the signature by the gateway at submit — a fact, not a client claim. Null where the gateway held no signature to recover from (a report-by-hash submit, where the wallet broadcast it itself) or where nothing has been submitted yet. This is what makes `release` gas attributable: that operation is payer-OR-payee, so whose cost it is depends on who signed.
|
|
319
|
-
:amount, # Amount in token BASE units. On capture and refund it is the amount the caller asked for. On void and release it is PROVISIONAL — those operations carry no amount and move the whole uncaptured escrow, so this is the capturable residual as of prepare, re-sealed with the exact on-chain amount when the indexer confirms.
|
|
320
|
-
:block_number,
|
|
321
|
-
:gas_used, # Gas units used, mirrored from the indexer on confirm.
|
|
322
|
-
:gas_limit, # Gas limit, mirrored from the indexer on confirm.
|
|
323
|
-
:effective_gas_price, # Effective gas price in wei, mirrored from the indexer on confirm.
|
|
324
|
-
:base_fee_per_gas, # Block base fee per gas in wei, mirrored from the indexer on confirm.
|
|
325
|
-
:gas_cost, # Total gas cost in wei (gas_used * effective_gas_price); derived, null until confirmed.
|
|
326
|
-
:pending_at,
|
|
327
|
-
:submitted_at,
|
|
328
|
-
:confirmed_at,
|
|
341
|
+
:unsigned_transaction, # String | nil
|
|
342
|
+
:transaction_hash, # String | nil
|
|
343
|
+
:sender, # String | nil — The address that SIGNED the submitted transaction, recovered from the signature by the gateway at submit — a fact, not a client claim. Null where the gateway held no signature to recover from (a report-by-hash submit, where the wallet broadcast it itself) or where nothing has been submitted yet. This is what makes `release` gas attributable: that operation is payer-OR-payee, so whose cost it is depends on who signed.
|
|
344
|
+
:amount, # String | nil — Amount in token BASE units. On capture and refund it is the amount the caller asked for. On void and release it is PROVISIONAL — those operations carry no amount and move the whole uncaptured escrow, so this is the capturable residual as of prepare, re-sealed with the exact on-chain amount when the indexer confirms.
|
|
345
|
+
:block_number, # Integer | nil
|
|
346
|
+
:gas_used, # String | nil — Gas units used, mirrored from the indexer on confirm.
|
|
347
|
+
:gas_limit, # String | nil — Gas limit, mirrored from the indexer on confirm.
|
|
348
|
+
:effective_gas_price, # String | nil — Effective gas price in wei, mirrored from the indexer on confirm.
|
|
349
|
+
:base_fee_per_gas, # String | nil — Block base fee per gas in wei, mirrored from the indexer on confirm.
|
|
350
|
+
:gas_cost, # String | nil — Total gas cost in wei (gas_used * effective_gas_price); derived, null until confirmed.
|
|
351
|
+
:pending_at, # String | nil
|
|
352
|
+
:submitted_at, # String | nil
|
|
353
|
+
:confirmed_at, # String | nil
|
|
329
354
|
:created_at, # String
|
|
330
355
|
:updated_at, # String
|
|
331
356
|
keyword_init: true
|
|
@@ -339,10 +364,10 @@ module Rail0
|
|
|
339
364
|
:address, # String
|
|
340
365
|
:version, # String — Semver, and every ACTIVE deployment must agree on the one the code targets.
|
|
341
366
|
:deployed_at, # String
|
|
342
|
-
:start_block, # Where the indexer starts. Null means the deployment block.
|
|
367
|
+
:start_block, # Integer | nil — Where the indexer starts. Null means the deployment block.
|
|
343
368
|
:active, # Boolean — The single deployment new payments are opened against, at most one per chain.
|
|
344
369
|
:archived, # Boolean — Always false here: the listing excludes archived deployments.
|
|
345
|
-
:archived_at,
|
|
370
|
+
:archived_at, # String | nil
|
|
346
371
|
:created_at, # String
|
|
347
372
|
:updated_at, # String
|
|
348
373
|
keyword_init: true
|
|
@@ -356,7 +381,7 @@ module Rail0
|
|
|
356
381
|
Account = Struct.new(
|
|
357
382
|
:id, # String
|
|
358
383
|
:name, # String
|
|
359
|
-
:email,
|
|
384
|
+
:email, # String | nil
|
|
360
385
|
:priority_tip, # Boolean — Whether the merchant's own transactions tip the network's suggested priority fee (true, the default) or the chain's minimum tip (false: 0 on most chains, 25 gwei on Polygon PoS/Amoy). The buyer's dispute/close_dispute never read it.
|
|
361
386
|
:authorization_ttl, # Integer — Seconds an authorization of the account's new payments stays capturable after the payment is created: the account's own value, or the gateway default (AUTHORIZATION_TTL).
|
|
362
387
|
:refund_ttl, # Integer — Seconds the account's new payments stay refundable, and open to a dispute, after they are created: the account's own value, or the gateway default (REFUND_TTL).
|
|
@@ -402,15 +427,15 @@ module Rail0
|
|
|
402
427
|
:name, # String
|
|
403
428
|
:email, # String — Lowercase.
|
|
404
429
|
:address, # String — Lowercase 0x + 40 hex.
|
|
405
|
-
:created_by, # The operator account of an invite; null for a sign-up.
|
|
430
|
+
:created_by, # String | nil — The operator account of an invite; null for a sign-up.
|
|
406
431
|
:link_version, # Integer — The version of the last link minted; a link for any lower one answers onboarding_link_superseded.
|
|
407
432
|
:last_sent_at, # String — When the last send was queued.
|
|
408
433
|
:send_count, # Integer — Sends queued in all (0 for a request migrated from a pending account, which has no link in the current format yet).
|
|
409
|
-
:last_delivered_at, # When the provider accepted the last send.
|
|
410
|
-
:last_send_error, # A short fixed code for why the last send failed (provider_rejected, timeout, email_domain_not_allowed, …); null when it was delivered or is in flight.
|
|
434
|
+
:last_delivered_at, # String | nil — When the provider accepted the last send.
|
|
435
|
+
:last_send_error, # String | nil — A short fixed code for why the last send failed (provider_rejected, timeout, email_domain_not_allowed, …); null when it was delivered or is in flight.
|
|
411
436
|
:expires_at, # String — When the last link, and the open request, expire.
|
|
412
|
-
:completed_at, # When the claim created the account.
|
|
413
|
-
:terms_version, # The terms version accepted at the claim.
|
|
437
|
+
:completed_at, # String | nil — When the claim created the account.
|
|
438
|
+
:terms_version, # String | nil — The terms version accepted at the claim.
|
|
414
439
|
:created_at, # String
|
|
415
440
|
:updated_at, # String
|
|
416
441
|
:status, # String
|
|
@@ -541,17 +566,19 @@ module Rail0
|
|
|
541
566
|
)
|
|
542
567
|
|
|
543
568
|
EventCallback = Struct.new(
|
|
544
|
-
:id,
|
|
545
|
-
:webhook_id,
|
|
546
|
-
:payment_id,
|
|
547
|
-
:
|
|
548
|
-
:
|
|
549
|
-
:
|
|
550
|
-
:
|
|
551
|
-
:
|
|
552
|
-
:
|
|
553
|
-
:
|
|
554
|
-
:
|
|
569
|
+
:id, # String
|
|
570
|
+
:webhook_id, # String
|
|
571
|
+
:payment_id, # String | nil — The payment a payments.* delivery is about. Exactly one of payment_id, payout_id and payout_destination_id is set.
|
|
572
|
+
:payout_id, # String | nil — The payout a payouts.* delivery is about.
|
|
573
|
+
:payout_destination_id, # String | nil — The destination a payout_destinations.verified delivery is about.
|
|
574
|
+
:topic, # String
|
|
575
|
+
:callback_url, # String
|
|
576
|
+
:response_code, # String | nil
|
|
577
|
+
:response_message, # String | nil
|
|
578
|
+
:error_reason, # String | nil
|
|
579
|
+
:status, # String
|
|
580
|
+
:created_at, # String
|
|
581
|
+
:payload, # String | nil — The JSON request body POSTed to the callback URL (decompressed).
|
|
555
582
|
keyword_init: true
|
|
556
583
|
)
|
|
557
584
|
|
|
@@ -564,5 +591,107 @@ module Rail0
|
|
|
564
591
|
:contract_address, # String — Address (lowercase) of the RAIL0 deployment the payment is bound to, archived versions included. The sweeper accepts a receipt's event only when this contract emitted it.
|
|
565
592
|
keyword_init: true
|
|
566
593
|
)
|
|
594
|
+
|
|
595
|
+
# One entry of the payout audit trail, written in the same transaction as the change it records.
|
|
596
|
+
# Append-only.
|
|
597
|
+
PayoutEvent = Struct.new(
|
|
598
|
+
:id, # String
|
|
599
|
+
:action, # String
|
|
600
|
+
:actor, # String — Who did it: the lowercase 0x address of the session wallet; `system` for the gateway's own settlement (Recovery); `operator:<administrator id>` reserved for an operator (none today).
|
|
601
|
+
:changes, # Hash | nil — `{"before": {…}, "after": {…}}` of the fields the event changed, either side optional. Amounts in base units. Never a signature or a payload. `destination.created` and `destination.min_amount_changed` also carry `confirmed_details`: `{"version": "details_v1", "by": <session address>, "at": <ISO 8601 UTC>}`, the merchant's attestation that they checked the details at the venue.
|
|
602
|
+
:destination_id, # String | nil — The destination, also on every payout event.
|
|
603
|
+
:payout_id, # String | nil — Null for a destination event, and once Retention purged the payout (a never-signed prepare).
|
|
604
|
+
:wallet_id, # String — The destination's / payout's wallet (not necessarily the actor's).
|
|
605
|
+
:created_at, # String
|
|
606
|
+
keyword_init: true
|
|
607
|
+
)
|
|
608
|
+
|
|
609
|
+
# An account named and nothing more, embedded where an operator listing must say whose row each is.
|
|
610
|
+
AccountSummary = Struct.new(
|
|
611
|
+
:id, # String
|
|
612
|
+
:name, # String
|
|
613
|
+
keyword_init: true
|
|
614
|
+
)
|
|
615
|
+
|
|
616
|
+
PayoutDestination = Struct.new(
|
|
617
|
+
:id, # String
|
|
618
|
+
:wallet_id, # String
|
|
619
|
+
:chain_id, # Integer
|
|
620
|
+
:token, # String — ERC-20 address on that chain, lowercased.
|
|
621
|
+
:token_symbol, # String | nil
|
|
622
|
+
:address, # String — The deposit address, lowercased.
|
|
623
|
+
:label, # String — The merchant's name for it: never blank, unique (case-insensitive) among the account's live destinations.
|
|
624
|
+
:status, # String
|
|
625
|
+
:has_code, # Boolean | nil — Whether the address held code on this chain when registered (eth_getCode, best effort). An EOA and an undeployed contract look the same.
|
|
626
|
+
:min_amount, # String | nil — The venue's deposit minimum, base units; null = no minimum. A payout below it is refused (`payout_below_minimum`); the proof transfer is raised to it.
|
|
627
|
+
:no_minimum, # Boolean — true when the merchant stated the venue has no minimum deposit (`min_amount` is then null). false with a null `min_amount`: never stated (a destination registered before it was asked).
|
|
628
|
+
:min_amount_formatted, # String | nil — `min_amount` in human decimals (the token's decimals); null when there is no minimum, or when the token left the catalog.
|
|
629
|
+
:proof_payout_id, # String | nil
|
|
630
|
+
:verified_at, # String | nil
|
|
631
|
+
:disabled_at, # String | nil
|
|
632
|
+
:deleted_at, # String | nil — When the merchant deleted it (DELETE /payout_destinations/{id}); null for a live destination.
|
|
633
|
+
:created_at, # String
|
|
634
|
+
:updated_at, # String
|
|
635
|
+
keyword_init: true
|
|
636
|
+
)
|
|
637
|
+
|
|
638
|
+
# What a payout to the destination would keep back right now (GET
|
|
639
|
+
# /payout_destinations/{id}/reserves). Every amount is base units as a string, with its
|
|
640
|
+
# human-decimals twin (`*_formatted`, the token's decimals).
|
|
641
|
+
PayoutReserves = Struct.new(
|
|
642
|
+
:destination_id, # String
|
|
643
|
+
:chain_id, # Integer
|
|
644
|
+
:token, # String — ERC-20 address on that chain, lowercased.
|
|
645
|
+
:token_symbol, # String
|
|
646
|
+
:decimals, # Integer
|
|
647
|
+
:balance, # String — The wallet's balance of the token, read now.
|
|
648
|
+
:balance_formatted, # String
|
|
649
|
+
:refund_reserve, # String — The refundable balance of the wallet's payments in this token still inside their refund window.
|
|
650
|
+
:refund_reserve_formatted, # String
|
|
651
|
+
:refundable_payments, # Integer — How many payments `refund_reserve` covers: the refunds the wallet may still owe.
|
|
652
|
+
:native_gas, # Boolean — Whether the chain's gas is paid in this very token (Arc's USDC). The gas figures are `0` when it is not.
|
|
653
|
+
:gas_reserve, # String — Gas for `gas_refunds` refunds and for `open_authorizations` + `base_captures` captures, at their gas limits and the fee ceiling a prepare would set now; `0` off a native-gas chain. Counted over every token of the chain: on Arc a EURC payment's capture or refund is paid in USDC gas too.
|
|
654
|
+
:gas_reserve_formatted, # String
|
|
655
|
+
:gas_refunds, # Integer — The wallet's payments on this chain, in any token, still inside their refund window with something left to refund: the refunds the gas reserve pays for.
|
|
656
|
+
:open_authorizations, # Integer — The wallet's payments on this chain, in any token, still capturable (a capture's gas is the merchant wallet's).
|
|
657
|
+
:base_captures, # Integer — Captures the gas reserve pays for on top of the open authorizations, so the wallet can capture the payments it takes next.
|
|
658
|
+
:gas_allowance, # String — The payout transfer's own fee (gas_limit × max_fee_per_gas), always kept back on a native-gas chain; `0` elsewhere.
|
|
659
|
+
:gas_allowance_formatted, # String
|
|
660
|
+
:available, # String — balance − refund_reserve − gas_reserve − gas_allowance, floored at 0: what `amount: all` moves with both reserves kept (the default).
|
|
661
|
+
:available_formatted, # String
|
|
662
|
+
keyword_init: true
|
|
663
|
+
)
|
|
664
|
+
|
|
665
|
+
Payout = Struct.new(
|
|
666
|
+
:id, # String
|
|
667
|
+
:destination_id, # String
|
|
668
|
+
:wallet_id, # String
|
|
669
|
+
:chain_id, # Integer
|
|
670
|
+
:token, # String
|
|
671
|
+
:token_symbol, # String | nil
|
|
672
|
+
:address, # String — The recipient.
|
|
673
|
+
:amount, # String — Base units.
|
|
674
|
+
:amount_formatted, # String — Human decimals.
|
|
675
|
+
:refund_reserve, # String | nil — Base units this payout kept back in the wallet for refunds, decided at prepare; `0` when the merchant opted out (`keep_refund_reserve: false`); null for a proof.
|
|
676
|
+
:gas_reserve, # String | nil — Base units this payout kept back for the gas the wallet still owes (native-gas chains only, `0` elsewhere or when opted out with `keep_gas_reserve: false`); null for a proof.
|
|
677
|
+
:purpose, # String
|
|
678
|
+
:status, # String — `pending` (prepared, awaiting the signature) → `submitted` (hash known; still `submitted` once mined, until its block is final) → `confirmed` | `failed`. Both outcomes are decided only once the receipt's block is at or below the chain's finality bound (its `finality_tag` block, or head − `required_confirmations` for `depth` or a node that serves no tag) and still canonical; `payouts.confirmed` / `payouts.failed` fire then.
|
|
679
|
+
:unsigned_transaction, # String | nil — JSON of the EIP-1559 transaction to sign (`to` = the token, `data` = transfer(address,uint256)). Check it against the decoded fields beside it before signing.
|
|
680
|
+
:signed, # Boolean — Whether the gateway stores the wallet's signed transaction (the payload itself is never exposed). A `pending` payout with `signed: true` already has its `transaction_hash` and may be in a mempool: resend it (POST /payouts/{id}/resend); it cannot be re-prepared.
|
|
681
|
+
:transaction_hash, # String | nil — Keccak of the signed transaction, stored with it on submit (so a signed `pending` row has it too), or the hash the wallet reported.
|
|
682
|
+
:sender, # String | nil
|
|
683
|
+
:block_number, # Integer | nil — The receipt's block. Set when the gateway first sees the receipt (the payout stays `submitted` until that block is final) moved to the new block if a reorg re-includes the transaction elsewhere, and cleared only while no block holds it.
|
|
684
|
+
:mined_at, # String | nil — When the gateway first saw the receipt (its own clock, not the block's timestamp). Non-null on a `submitted` payout: mined, waiting for finality.
|
|
685
|
+
:gas_used, # String | nil
|
|
686
|
+
:error_code, # String | nil — When failed: `reverted` (mined, status 0), `foreign_transfer` (mined, but the receipt has no Transfer of this amount of this token from the wallet to this destination), `dropped` (not mined, and the wallet's confirmed nonce has passed the signed transaction's), `submission_timeout` (a reported hash no node has ever known, past SUBMITTED_TX_TTL), `cancelled` (unsigned, cancelled by the merchant with POST /payouts/{id}/cancel or by disabling its destination). `submission_timeout` and `dropped` are not final: POST /payouts/{id}/submitted with a late hash puts the payout back to `submitted`.
|
|
687
|
+
:error_title, # String | nil
|
|
688
|
+
:error_detail, # String | nil
|
|
689
|
+
:submitted_at, # String | nil
|
|
690
|
+
:confirmed_at, # String | nil
|
|
691
|
+
:failed_at, # String | nil
|
|
692
|
+
:created_at, # String
|
|
693
|
+
:updated_at, # String
|
|
694
|
+
keyword_init: true
|
|
695
|
+
)
|
|
567
696
|
end
|
|
568
697
|
end
|
data/lib/rail0/version.rb
CHANGED
|
@@ -5,5 +5,5 @@ module Rail0
|
|
|
5
5
|
# consumed by path from a sibling checkout, where the number bought nothing: no registry
|
|
6
6
|
# ever served a 1.x, no tag was ever cut, and the one consumer resolves the working tree.
|
|
7
7
|
# Publishing from 1.2.0 would have implied two releases nobody can install.
|
|
8
|
-
VERSION = "1.
|
|
8
|
+
VERSION = "1.10.0"
|
|
9
9
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rail0-sdk
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.10.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Commerce Layer
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-
|
|
11
|
+
date: 2026-11-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: logger
|
|
@@ -45,6 +45,7 @@ files:
|
|
|
45
45
|
- lib/rail0/error_hints.rb
|
|
46
46
|
- lib/rail0/http_client.rb
|
|
47
47
|
- lib/rail0/payload_verify.rb
|
|
48
|
+
- lib/rail0/payout_verify.rb
|
|
48
49
|
- lib/rail0/request.rb
|
|
49
50
|
- lib/rail0/resources/accounts.rb
|
|
50
51
|
- lib/rail0/resources/analytics.rb
|
|
@@ -54,6 +55,8 @@ files:
|
|
|
54
55
|
- lib/rail0/resources/health.rb
|
|
55
56
|
- lib/rail0/resources/payment_methods.rb
|
|
56
57
|
- lib/rail0/resources/payments.rb
|
|
58
|
+
- lib/rail0/resources/payout_destinations.rb
|
|
59
|
+
- lib/rail0/resources/payouts.rb
|
|
57
60
|
- lib/rail0/resources/query.rb
|
|
58
61
|
- lib/rail0/resources/tokens.rb
|
|
59
62
|
- lib/rail0/resources/wallets.rb
|