@atumlabs/payment-gateway-client 2.2.0 → 3.0.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/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { AxiosRequestConfig, AxiosResponse } from 'axios';
2
+ import { Signer } from 'ethers';
2
3
 
3
4
  type ApiRequestOptions = {
4
5
  readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH';
@@ -103,7 +104,7 @@ type AuthorizationResult = {
103
104
  * Machine-readable error code (present when status is error or timeout).
104
105
  * Counterparty-sourced codes are derived from the error code the
105
106
  * Counterparty Gateway publishes. GATEWAY_TIMEOUT, PROOF_INVALID, and
106
- * PROOF_STALE are payment-gw-specific (no counterparty envelope corresponds).
107
+ * PROOF_STALE are raised by this gateway itself (no counterparty envelope corresponds).
107
108
  *
108
109
  */
109
110
  error_code?: 'COUNTERPARTY_NOT_FOUND' | 'COUNTERPARTY_TIMEOUT' | 'WEBHOOK_ERROR' | 'WEBHOOK_CONNECTION_ERROR' | 'INTERNAL_ERROR' | 'GATEWAY_TIMEOUT' | 'PROOF_INVALID' | 'PROOF_STALE';
@@ -126,7 +127,7 @@ type status = 'authorized' | 'declined' | 'error' | 'timeout';
126
127
  * Machine-readable error code (present when status is error or timeout).
127
128
  * Counterparty-sourced codes are derived from the error code the
128
129
  * Counterparty Gateway publishes. GATEWAY_TIMEOUT, PROOF_INVALID, and
129
- * PROOF_STALE are payment-gw-specific (no counterparty envelope corresponds).
130
+ * PROOF_STALE are raised by this gateway itself (no counterparty envelope corresponds).
130
131
  *
131
132
  */
132
133
  type error_code = 'COUNTERPARTY_NOT_FOUND' | 'COUNTERPARTY_TIMEOUT' | 'WEBHOOK_ERROR' | 'WEBHOOK_CONNECTION_ERROR' | 'INTERNAL_ERROR' | 'GATEWAY_TIMEOUT' | 'PROOF_INVALID' | 'PROOF_STALE';
@@ -135,10 +136,7 @@ type error_code = 'COUNTERPARTY_NOT_FOUND' | 'COUNTERPARTY_TIMEOUT' | 'WEBHOOK_E
135
136
  */
136
137
  type PaymentRequest = {
137
138
  /**
138
- * Semver-shaped declaration version (MAJOR.MINOR). The major component is locked to this schema's
139
- * parent directory (v1 → major must be 1). Producers MUST emit the canonical value exported by the
140
- * bindings' Version constant; the canonical bumps on each additive minor evolution.
141
- *
139
+ * Semver-shaped declaration version (MAJOR.MINOR). The major component is locked to this schema's parent directory (v1 → major must be 1). Producers MUST emit the canonical value exported by the bindings' Version constant; the canonical bumps on each additive minor evolution.
142
140
  */
143
141
  version: string;
144
142
  /**
@@ -147,17 +145,16 @@ type PaymentRequest = {
147
145
  request_id: string;
148
146
  source: OwnedAsset;
149
147
  /**
150
- * Array of destination assets for the settlement agent to choose from (at least one required)
148
+ * Array of destination assets for the settlement agent to choose from (at least one required, at most 16).
149
+ * The ceiling bounds the fan-out one request can buy: every consumer iterates this list.
151
150
  */
152
151
  destination: Array<OwnedAsset>;
153
152
  /**
154
153
  * The exact amount to be received at the destination (in the smallest unit, e.g., wei for ETH, cents for USD).
155
- *
156
154
  */
157
155
  fulfillment_amount: string;
158
156
  /**
159
157
  * The maximum amount willing to be spent from the source (in the smallest unit).
160
- *
161
158
  */
162
159
  max_source_amount?: string;
163
160
  /**
@@ -165,7 +162,6 @@ type PaymentRequest = {
165
162
  * point no new quotes are accepted. The gateway injects no default and validates the value
166
163
  * is in the future. The originator must supply it, and a request that omits it or supplies
167
164
  * a past value is rejected with 400.
168
- *
169
165
  */
170
166
  quote_deadline: string;
171
167
  /**
@@ -173,12 +169,10 @@ type PaymentRequest = {
173
169
  * payment is cancelled and eligible for a refund. The gateway injects no default and validates
174
170
  * the value is in the future. The originator must supply it, and a request that omits it or
175
171
  * supplies a past value is rejected with 400.
176
- *
177
172
  */
178
173
  fulfillment_deadline: string;
179
174
  /**
180
175
  * Policy requirements for settler authentication. Keys are policy names, values indicate if the policy is required.
181
- *
182
176
  */
183
177
  settler_auth_required?: {
184
178
  [key: string]: (boolean);
@@ -188,13 +182,11 @@ type PaymentRequest = {
188
182
  /**
189
183
  * Wallet address or public key of a trusted service that will automatically select
190
184
  * the best exchange rate for your payment. Leave empty to use the default selector.
191
- *
192
185
  */
193
186
  quote_selector?: string;
194
187
  /**
195
188
  * Third-party service that will independently verify your payment was delivered.
196
189
  * Leave empty to use the default verifier.
197
- *
198
190
  */
199
191
  fulfillment_verifier?: {
200
192
  /**
@@ -203,42 +195,29 @@ type PaymentRequest = {
203
195
  account: string;
204
196
  /**
205
197
  * Origin of the fulfillment verifier service, with no path — the caller
206
- * appends the verifier's own API paths. The gateway's `/defaults` response
198
+ * appends the verifier's own API paths. The gateway's `/v1/defaults` response
207
199
  * supplies the default fulfillment verifier for each chain.
208
- *
209
200
  */
210
201
  endpoint: string;
211
202
  };
212
203
  /**
213
204
  * Escrow contract address, used to protect source funds until proof of fulfillment has been verified. Leave empty to use the default.
214
- *
215
205
  */
216
206
  escrow_contract_address?: string;
217
207
  /**
218
208
  * Fulfillment Proxy contract address, used to emit proof of fulfillment on the destination chain. Leave empty to use the default.
219
- *
220
209
  */
221
210
  fulfillment_proxy?: string;
222
211
  /**
223
- * Optional settler filtering requirements.
224
- * If whitelist is present, only whitelisted settlers may win.
225
- * If blacklist is present, blacklisted settlers are excluded.
226
- * Both can be specified together; blacklist takes precedence
227
- * (a settler in both lists is rejected).
228
- *
212
+ * Optional settler filtering requirements. If whitelist is present, only whitelisted settlers may win. If blacklist is present, blacklisted settlers are excluded. Both can be specified; blacklist takes precedence (a settler in both lists is rejected).
229
213
  */
230
214
  settler_requirements?: {
231
215
  /**
232
- * List of settler DIDs permitted to fulfill this request.
233
- * If present, only these settlers may win.
234
- * Use W3C DID format.
235
- *
216
+ * List of settler DIDs permitted to fulfill this request. If present and non-empty, only these settlers may win. Use W3C DID format (e.g., did:pkh:eip155:1:0xABC...).
236
217
  */
237
218
  whitelist?: Array<(string)>;
238
219
  /**
239
- * List of settler DIDs excluded from fulfilling this request.
240
- * Use W3C DID format.
241
- *
220
+ * List of settler DIDs excluded from fulfilling this request. If present and non-empty, these settlers are rejected. Use W3C DID format (e.g., did:pkh:eip155:1:0xABC...).
242
221
  */
243
222
  blacklist?: Array<(string)>;
244
223
  };
@@ -305,9 +284,7 @@ type FulfillmentConfirmation = {
305
284
  destination_block_number?: number;
306
285
  };
307
286
  /**
308
- * Represents a cryptocurrency or token in a specific wallet.
309
- * This tells the system what asset you're sending/receiving and which wallet to use.
310
- *
287
+ * Represents a cryptocurrency or token in a specific wallet. This tells the system what asset you're sending/receiving and which wallet to use.
311
288
  */
312
289
  type OwnedAsset = {
313
290
  /**
@@ -318,7 +295,6 @@ type OwnedAsset = {
318
295
  * - Arbitrum USDC: "eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
319
296
  * - Solana USDC: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
320
297
  * - Tron USDT: "tron:mainnet/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t"
321
- *
322
298
  */
323
299
  asset_identifier: string;
324
300
  /**
@@ -328,15 +304,21 @@ type OwnedAsset = {
328
304
  * - Solana: Base58 encoded address
329
305
  * - Tron: T-prefixed Base58 address
330
306
  *
307
+ * A destination account is checked at ingress and must be payable on the chain named by
308
+ * its `asset_identifier`: it parses for that chain, carries a valid EIP-55 checksum when
309
+ * mixed-case, has no surrounding whitespace, and is not the zero address. A receiver that
310
+ * fails any of these is refused with `INVALID_DESTINATION_ACCOUNT`, before any funds move.
331
311
  */
332
312
  account: string;
333
313
  };
334
314
  /**
335
- * Authorization from the asset owner to execute the payment. The exact format depends on
336
- * the source blockchain's authorization mechanism.
337
- *
315
+ * Authorization from the asset owner to execute the payment. The exact format depends on the source blockchain's authorization mechanism.
338
316
  */
339
317
  type SenderAuth = {
318
+ /**
319
+ * DEPRECATED: inner-document credential carrier. Credentials MUST ride ONLY in the holder-signed PaymentRequestEnvelope (PRE); the inner PaymentRequest carries no credential and its Data Integrity signature EXCLUDES this field (stripped before canonicalization on both producer and verifier). Populated only for one back-compat rollout cycle, then removed.
320
+ * @deprecated
321
+ */
340
322
  verifiable_credential?: VerifiableCredentialAuth;
341
323
  message_scheme: SenderAuthMessageScheme;
342
324
  /**
@@ -347,42 +329,44 @@ type SenderAuth = {
347
329
  /**
348
330
  * The signature method used for authorizing this payment:
349
331
  * - `EVM_PERMIT2`: Gasless token approvals for Ethereum/EVM chains
332
+ * - `EVM_PERMIT2_ESCROW`: Gasless approvals with escrow support
350
333
  * - `SOLANA`: Standard Solana transaction signatures
351
334
  * - `TRON`: Tron transaction signatures
352
- *
353
335
  */
354
336
  type SenderAuthMessageScheme = 'EVM_PERMIT2' | 'EVM_PERMIT2_ESCROW' | 'SOLANA' | 'TRON';
355
337
  /**
356
- * A message that has been cryptographically signed to prove authorization.
357
- * The signature proves you control the wallet that's sending funds.
358
- *
338
+ * A message that has been cryptographically signed to prove authorization. The signature proves you control the wallet that's sending funds.
359
339
  */
360
340
  type SignedMessage = {
361
341
  /**
362
342
  * The data that was signed. Format depends on the blockchain:
363
343
  * - EVM: Hex-encoded message hash (with 0x prefix)
364
- * - Solana: Base64 encoded message
344
+ * - Solana: Hex-encoded message hash (with 0x prefix)
365
345
  * - Tron: Hex-encoded message hash (possibly without 0x prefix)
366
- *
367
346
  */
368
347
  message: string;
369
348
  /**
370
- * Optional: If 'message' contains a hash, this field contains the original data
371
- * before it was hashed. Useful for verification and debugging.
372
- *
349
+ * Optional: If 'message' contains a hash, this field contains the original data before it was hashed. Useful for verification and debugging.
373
350
  */
374
351
  message_prehash?: string;
375
352
  /**
376
- * The cryptographic signature proving you authorized this message.
377
- * Format varies by blockchain (hex for EVM/Tron, base58 for Solana).
378
- *
353
+ * The cryptographic signature proving you authorized this message. Hex-encoded with a 0x prefix on every supported chain. The signer's own public key is base58 on Solana, but the signature itself is not.
379
354
  */
380
355
  signature: string;
356
+ /**
357
+ * Optional chain-specific payload containing additional signing context (e.g., delegate_signer for Solana). Preserved through the pipeline for downstream consumers.
358
+ */
359
+ payload?: {
360
+ [key: string]: unknown;
361
+ };
381
362
  };
382
363
  /**
383
364
  * Optional identity verification using cryptographic credentials.
384
- * Required when regulatory compliance or KYC verification is needed for the payment.
385
365
  *
366
+ * DEPRECATED. Credentials are moving to a holder-signed W3C VerifiablePresentation that
367
+ * travels alongside a request rather than inside it. That envelope is not part of this
368
+ * HTTP contract, so there is nothing here to move them to yet: treat this as a legacy
369
+ * carrier, and do not build a new integration on it.
386
370
  */
387
371
  type VerifiableCredentialAuth = {
388
372
  verifiable_credential: VerifiableCredential;
@@ -432,7 +416,7 @@ type VerifiableCredential = {
432
416
  [key: string]: unknown;
433
417
  };
434
418
  /**
435
- * Information for credential revocation checking
419
+ * Information for credential revocation checking. Not consulted by the verifier today.
436
420
  */
437
421
  credentialStatus?: {
438
422
  [key: string]: unknown;
@@ -456,6 +440,13 @@ type VerifiableCredential = {
456
440
  * request_id resolves to the same terminal payment, so a genuine re-attempt needs a
457
441
  * new request_id.
458
442
  *
443
+ * **A synchronously-completed payment carries proof of QUOTE as well as of delivery.** When
444
+ * settlement lands inside the window you get `status: completed`, a full
445
+ * `fulfillment_confirmation`, and — since a quote necessarily was awarded to get there —
446
+ * `quote_id` and `fulfillment_quote`. The fast path therefore needs no follow-up call to
447
+ * verify: recompute `quote_hash` over the returned quote and compare it against the on-chain
448
+ * commitment from this response alone.
449
+ *
459
450
  */
460
451
  type PaymentResponse = {
461
452
  /**
@@ -510,6 +501,29 @@ type PaymentResponse = {
510
501
  *
511
502
  */
512
503
  idempotent_replay: boolean;
504
+ /**
505
+ * The winning quote's ID. Present when `status` is `completed` — a payment cannot settle
506
+ * without an award — and absent on a `pending` response, where no quote has been selected
507
+ * yet. Same value and meaning as on GET /v1/payments/{paymentId}/status.
508
+ *
509
+ */
510
+ quote_id?: string;
511
+ /**
512
+ * The settler-signed FulfillmentQuote for the winning quote, returned verbatim as an
513
+ * opaque signed document — the PREIMAGE of the `quote_hash` committed on-chain. Same
514
+ * value, semantics and canonicalization caveats as on
515
+ * GET /v1/payments/{paymentId}/status; see that field for how to verify it.
516
+ *
517
+ * Present when `status` is `completed`. It may be absent even then, if the stored quote
518
+ * is unreadable: the award is reported through `quote_id` regardless, so a present
519
+ * `quote_id` with no `fulfillment_quote` means "verification preimage unavailable" and
520
+ * never "no quote was awarded". A consumer that requires the preimage should fall back to
521
+ * the status endpoint rather than treat the payment as unverified.
522
+ *
523
+ */
524
+ fulfillment_quote?: {
525
+ [key: string]: unknown;
526
+ };
513
527
  fulfillment_confirmation?: FulfillmentConfirmation;
514
528
  error?: PaymentError;
515
529
  };
@@ -546,8 +560,59 @@ type GetPaymentStatusResponse = {
546
560
  * When the status was last updated
547
561
  */
548
562
  updated_at?: string;
563
+ /**
564
+ * The winning quote's ID. Present once a quote has been awarded for this payment;
565
+ * absent while the payment is still collecting or awarding. Cross-references the
566
+ * `quote_id` returned by GET /v1/payments/quote-requests/{quoteRequestId}.
567
+ *
568
+ */
569
+ quote_id?: string;
570
+ /**
571
+ * The settler-signed FulfillmentQuote for the winning quote, returned verbatim as an
572
+ * opaque signed document (structurally the canonical FulfillmentQuote/v1 declaration at
573
+ * https://schemas.atum.xyz/declarations/FulfillmentQuote/v1). Present once a quote has
574
+ * been awarded — including after the payment completes and `fulfillment_confirmation` is
575
+ * populated, since that is precisely when a consumer verifies.
576
+ *
577
+ * This is the PREIMAGE of the `quote_hash` committed on-chain in the escrow deposit and
578
+ * reserve witnesses. On-chain we commit only the hash, so a quote-selector consumer
579
+ * recomputes quote_hash over these bytes and compares it against the on-chain commitment
580
+ * to confirm the payment settled against the quote it selected ("trust but verify"), and
581
+ * verifies the settler signature over the same bytes.
582
+ *
583
+ * quote_hash is canonicalization-based (URDNA2015), so it is stable across JSON
584
+ * key-order/whitespace normalization and across JSON string-escaping differences. The
585
+ * returned bytes are hash-equivalent to, but not necessarily byte-identical with, what
586
+ * the settler emitted (quotes are stored as JSONB, which normalizes on write). The
587
+ * gateway still never re-serializes the quote through a typed struct (that renormalizes
588
+ * timestamp values and WOULD change quote_hash), so the Go binding exposes it as a raw
589
+ * JSON passthrough.
590
+ *
591
+ */
592
+ fulfillment_quote?: {
593
+ [key: string]: unknown;
594
+ };
549
595
  fulfillment_confirmation?: FulfillmentConfirmation;
550
596
  error?: PaymentError;
597
+ /**
598
+ * How many settler agents this payment's auction was broadcast to. Absent means
599
+ * unknown, never zero.
600
+ *
601
+ */
602
+ requested_count?: number;
603
+ /**
604
+ * Why the payment drew few or no quotes. Read from the same settler reports as the
605
+ * quote-request endpoints, keyed by this payment, so a payment that failed on an expired
606
+ * quote deadline can say WHY nobody funded it instead of only that nobody did.
607
+ *
608
+ * Every declining agent is counted exactly once under its most recent reason. Empty means
609
+ * no agent declined against this payment, absent means the breakdown could not be read. A
610
+ * payment awarded out of a quote-request batch was bid on at quote time, so its declines
611
+ * are keyed to that batch and are read from the batch's status endpoint rather than here.
612
+ * As on the quote-request endpoints, the free-form decline detail is never relayed.
613
+ *
614
+ */
615
+ decline_summary?: Array<DeclineSummaryEntry>;
551
616
  };
552
617
  /**
553
618
  * Error details when payment status is "failed".
@@ -560,7 +625,7 @@ type PaymentError = {
560
625
  * Public error category in SCREAMING_SNAKE_CASE.
561
626
  * Common codes:
562
627
  * - `SETTLEMENT_FAILED`: The settlement could not be completed
563
- * - `NO_ROUTE_AVAILABLE`: No settlement route was available
628
+ * - `NO_QUOTES_RECEIVED`: No quotes arrived within the auction window
564
629
  * - `INTERNAL_ERROR`: An unexpected error occurred
565
630
  *
566
631
  */
@@ -574,14 +639,14 @@ type PaymentError = {
574
639
  * Service domain where the error originated.
575
640
  *
576
641
  */
577
- domain?: 'PAYMENT_GATEWAY' | 'SOLVER_GATEWAY' | 'SETTLER_AGENT' | 'WALLET_ORCHESTRATION' | 'VERIFICATION_SERVICE' | 'BLOCKCHAIN' | 'EXTERNAL_SERVICE';
642
+ domain?: 'PAYMENT_GATEWAY' | 'SETTLER_GATEWAY' | 'SETTLER_AGENT' | 'WALLET_ORCHESTRATION' | 'VERIFICATION_SERVICE' | 'BLOCKCHAIN' | 'EXTERNAL_SERVICE';
578
643
  blockchain_context?: PaymentBlockchainContext;
579
644
  };
580
645
  /**
581
646
  * Service domain where the error originated.
582
647
  *
583
648
  */
584
- type domain = 'PAYMENT_GATEWAY' | 'SOLVER_GATEWAY' | 'SETTLER_AGENT' | 'WALLET_ORCHESTRATION' | 'VERIFICATION_SERVICE' | 'BLOCKCHAIN' | 'EXTERNAL_SERVICE';
649
+ type domain = 'PAYMENT_GATEWAY' | 'SETTLER_GATEWAY' | 'SETTLER_AGENT' | 'WALLET_ORCHESTRATION' | 'VERIFICATION_SERVICE' | 'BLOCKCHAIN' | 'EXTERNAL_SERVICE';
585
650
  /**
586
651
  * Blockchain-specific error context. Only present when the error
587
652
  * originated from an on-chain operation (e.g., escrow revert,
@@ -859,6 +924,8 @@ type TimelineStep = {
859
924
  type status4 = 'completed' | 'in_progress' | 'pending' | 'failed' | 'skipped';
860
925
  /**
861
926
  * Safe, outward-facing error. Derived from an internal error through the shared error catalog. The public code identifies the category and the message is a curated, safe description.
927
+ *
928
+ * A panic is caught by shared middleware that responds `{"error": "Internal server error occurred"}` instead, so a 500 is not guaranteed to carry this shape.
862
929
  */
863
930
  type ErrorResponse = {
864
931
  /**
@@ -873,6 +940,10 @@ type ErrorResponse = {
873
940
  * Correlation id to quote to support to locate the internal error record.
874
941
  */
875
942
  request_id?: string;
943
+ /**
944
+ * The payment this error was raised against. Absent when the error is not about a specific payment.
945
+ */
946
+ payment_id?: string;
876
947
  /**
877
948
  * Link to the documentation page for this public code.
878
949
  */
@@ -881,6 +952,11 @@ type ErrorResponse = {
881
952
  * Originating service domain.
882
953
  */
883
954
  domain?: string;
955
+ /**
956
+ * What the caller should do next. Absent means the condition has not been classified, which is not the same as safe to retry.
957
+ * Re-sending the same `request_id` is an idempotent replay and always safe. This value is about submitting a new one, which starts a new operation. See https://docs.atum.xyz/errors for the value set.
958
+ */
959
+ retry_classification?: string;
884
960
  };
885
961
  /**
886
962
  * Request body for opening a quote-request batch. Structurally the existing PaymentRequest
@@ -903,7 +979,9 @@ type CreateQuoteRequest = {
903
979
  request_id: string;
904
980
  source: OwnedAsset;
905
981
  /**
906
- * Array of destination assets for the settlement agent to choose from (at least one required).
982
+ * Array of destination assets for the settlement agent to choose from (at least one required, at most 16).
983
+ * The ceiling bounds the fan-out one request can buy: every consumer iterates this list.
984
+ *
907
985
  */
908
986
  destination: Array<OwnedAsset>;
909
987
  /**
@@ -955,7 +1033,7 @@ type CreateQuoteRequest = {
955
1033
  account: string;
956
1034
  /**
957
1035
  * Origin of the fulfillment verifier service, with no path — the caller
958
- * appends the verifier's own API paths. The gateway's `/defaults` response
1036
+ * appends the verifier's own API paths. The gateway's `/v1/defaults` response
959
1037
  * supplies the default fulfillment verifier for each chain.
960
1038
  *
961
1039
  */
@@ -998,31 +1076,31 @@ type CreateQuoteRequest = {
998
1076
  verifiableCredential?: Array<VerifiableCredential>;
999
1077
  };
1000
1078
  /**
1001
- * W3C Data Integrity proof conforming to the Data Integrity 1.0 specification.
1079
+ * W3C Data Integrity proof conforming to the Data Integrity 1.0 specification. Which of jws or proofValue is required depends on the cryptosuite named in type, and that pairing is checked where the proof is verified rather than by this schema, so a document can satisfy the schema and still be refused at verification.
1002
1080
  */
1003
1081
  type DataIntegrityProof = {
1004
1082
  /**
1005
- * Proof type identifier (e.g. EcdsaSecp256k1RecoverySignature2020).
1083
+ * Proof type identifier. ECDSA-secp256k1 (recoverable, EVM-compatible) for did:pkh:eip155:* signers; Ed25519 for did:pkh:solana:* signers.
1006
1084
  */
1007
1085
  type: string;
1008
1086
  /**
1009
- * ISO 8601 timestamp when the proof was created.
1087
+ * ISO 8601 timestamp when the proof was created. Canonicalize the value exactly as it appears in the raw JSON: parsing it into a date-time and re-serializing can change the spelling (Z versus +00:00), and a different spelling canonicalizes to different bytes, so the signature no longer verifies.
1010
1088
  */
1011
1089
  created: string;
1012
1090
  /**
1013
- * DID URL identifying the verification method.
1091
+ * DID URL identifying the verification method, e.g., 'did:pkh:eip155:1:0x...#blockchainAccountId' for ECDSA or 'did:pkh:solana:<chain>:<addr>#SolanaMethod2021' for Ed25519.
1014
1092
  */
1015
1093
  verificationMethod: string;
1016
1094
  /**
1017
- * Purpose of the proof (e.g. assertionMethod, authentication).
1095
+ * Purpose of the proof (e.g., assertionMethod, authentication).
1018
1096
  */
1019
1097
  proofPurpose: string;
1020
1098
  /**
1021
- * Detached JWS signature (header..signature format for ES256K-R).
1099
+ * Detached JWS signature in <base64url(header)>..<base64url(sig)> form, header {alg:ES256K-R, b64:false, crit:[b64]}. Required at runtime for EcdsaSecp256k1RecoverySignature2020.
1022
1100
  */
1023
1101
  jws?: string;
1024
1102
  /**
1025
- * Alternative to jws: base-encoded proof value.
1103
+ * Multibase-encoded raw signature bytes. Required at runtime for Ed25519Signature2020; mutually exclusive with jws in practice.
1026
1104
  */
1027
1105
  proofValue?: string;
1028
1106
  };
@@ -1094,6 +1172,10 @@ type AwardedPayment = {
1094
1172
  * fields are echoed at the response root so a drop-recovery client can build the award call
1095
1173
  * without retaining the original request body.
1096
1174
  *
1175
+ * The corridor echoed here describes the batch you actually receive. On an idempotent
1176
+ * replay that is the ORIGINAL batch's corridor and window, which may differ from what you
1177
+ * just sent in the ways a retry is allowed to differ (the deadlines, and address casing).
1178
+ *
1097
1179
  */
1098
1180
  type QuoteRequestResponse = {
1099
1181
  /**
@@ -1110,6 +1192,33 @@ type QuoteRequestResponse = {
1110
1192
  *
1111
1193
  */
1112
1194
  status: 'collecting' | 'ready';
1195
+ /**
1196
+ * Whether this response describes a batch that already existed, rather than one opened
1197
+ * by this request. `true` means the `request_id` had been used before and you are being
1198
+ * handed the ORIGINAL batch — no second batch was opened and no second broadcast went
1199
+ * out to settlement agents.
1200
+ *
1201
+ * **Re-attempting a quote-request.** Re-submit the same request and you get the same
1202
+ * batch back. You may re-send the original bytes unchanged: `quote_deadline` bounds the
1203
+ * collection window and is short, so it will usually have expired by the time you
1204
+ * retry, and an expired deadline on a re-submission is not an error — the request is
1205
+ * resolved onto the batch that already exists rather than used to open one.
1206
+ * Re-signing with fresh deadlines is equally fine and returns the same batch.
1207
+ *
1208
+ * The window is NOT extended either way: it belongs to the batch, and `quote_deadline`
1209
+ * in this response is the batch's own. Read `status` to see whether collection is
1210
+ * still running.
1211
+ *
1212
+ * What you must not change under one `request_id` is the corridor's economics —
1213
+ * accounts, assets, or amounts — which are rejected with 409
1214
+ * IDEMPOTENCY_TERMS_MISMATCH rather than resolved onto the first batch. A genuinely
1215
+ * different corridor needs a new `request_id`.
1216
+ *
1217
+ * Present on every response, `false` for a newly opened batch. A response without the
1218
+ * field is from a gateway predating it, not a newly opened batch.
1219
+ *
1220
+ */
1221
+ idempotent_replay: boolean;
1113
1222
  source?: OwnedAsset;
1114
1223
  destination?: Array<OwnedAsset>;
1115
1224
  fulfillment_amount?: string;
@@ -1120,6 +1229,23 @@ type QuoteRequestResponse = {
1120
1229
  * Collected quotes. Present when status is `ready` — an empty array if no settler bid.
1121
1230
  */
1122
1231
  quotes?: Array<Quote>;
1232
+ /**
1233
+ * How many agents the request was broadcast to, so silence is distinguishable from a
1234
+ * decline without a second call. Same meaning and same absence rule as on the status
1235
+ * endpoint: absent means unknown, never zero.
1236
+ *
1237
+ */
1238
+ requested_count?: number;
1239
+ /**
1240
+ * Why the request drew few or no quotes, carried here so that a `ready` response with an
1241
+ * empty `quotes` array explains itself rather than requiring a follow-up read.
1242
+ *
1243
+ * Same counting rules as the status endpoint: every declining agent counted exactly once
1244
+ * under its most recent reason, empty when nobody declined, absent when the detail could not
1245
+ * be read. Provisional while `status` is `collecting`, because agents are still responding.
1246
+ *
1247
+ */
1248
+ decline_summary?: Array<DeclineSummaryEntry>;
1123
1249
  };
1124
1250
  /**
1125
1251
  * Collection-phase outcome of the create call:
@@ -1135,13 +1261,37 @@ type status5 = 'collecting' | 'ready';
1135
1261
  * Asynchronous (202) response to POST /v1/payments/quote-requests. Returns the batch handle
1136
1262
  * plus the echoed corridor; quotes are retrieved via the status endpoint.
1137
1263
  *
1264
+ * The corridor echoed here describes the batch you actually receive. On an idempotent
1265
+ * replay that is the ORIGINAL batch's corridor and window, which may differ from what you
1266
+ * just sent in the ways a retry is allowed to differ (the deadlines, and address casing).
1267
+ *
1138
1268
  */
1139
1269
  type QuoteRequestAccepted = {
1140
1270
  quote_request_id: string;
1141
1271
  /**
1142
- * Always `collecting` — collection is in progress server-side.
1272
+ * Always `collecting` — a constant on this response, not a report of the batch's state.
1273
+ * On an idempotent replay the batch's window may already have closed; read
1274
+ * GET /v1/payments/quote-requests/{quoteRequestId} for its actual state.
1275
+ *
1143
1276
  */
1144
1277
  status: 'collecting';
1278
+ /**
1279
+ * Whether this response describes a batch that already existed, rather than one opened
1280
+ * by this request. `true` means the `request_id` had been used before and you are being
1281
+ * handed the ORIGINAL batch — no second batch was opened and no second broadcast went
1282
+ * out to settlement agents.
1283
+ *
1284
+ * The idempotency contract is the same as on the synchronous (200) response: a
1285
+ * re-submission may carry expired deadlines and is resolved onto the existing batch
1286
+ * rather than rejected, the collection window is the batch's own and is not extended,
1287
+ * and differing economics are rejected with 409 IDEMPOTENCY_TERMS_MISMATCH rather than
1288
+ * collapsed onto the first batch.
1289
+ *
1290
+ * Present on every response, `false` for a newly opened batch. A response without the
1291
+ * field is from a gateway predating it, not a newly opened batch.
1292
+ *
1293
+ */
1294
+ idempotent_replay: boolean;
1145
1295
  source?: OwnedAsset;
1146
1296
  destination?: Array<OwnedAsset>;
1147
1297
  fulfillment_amount?: string;
@@ -1150,7 +1300,10 @@ type QuoteRequestAccepted = {
1150
1300
  quote_deadline?: string;
1151
1301
  };
1152
1302
  /**
1153
- * Always `collecting` — collection is in progress server-side.
1303
+ * Always `collecting` — a constant on this response, not a report of the batch's state.
1304
+ * On an idempotent replay the batch's window may already have closed; read
1305
+ * GET /v1/payments/quote-requests/{quoteRequestId} for its actual state.
1306
+ *
1154
1307
  */
1155
1308
  type status6 = 'collecting';
1156
1309
  /**
@@ -1184,6 +1337,42 @@ type QuoteRequestStatusResponse = {
1184
1337
  * Flat list of awarded (quote_id, payment_id) pairs. At most one entry under MVP single-award.
1185
1338
  */
1186
1339
  payments?: Array<AwardedPayment>;
1340
+ /**
1341
+ * How many agents the request was broadcast to. The only auction count that is not
1342
+ * derivable from the rest of this response:
1343
+ *
1344
+ * - quoted = `quotes` length
1345
+ * - declined = sum of `decline_summary[].count`
1346
+ * - participated = quoted + declined
1347
+ * - silent = `requested_count` - participated
1348
+ *
1349
+ * Silence and a decline are different signals, which is why the denominator is surfaced
1350
+ * rather than left implicit.
1351
+ *
1352
+ * ABSENT when the number is unknown, which happens when the broadcast count was never
1353
+ * recorded or when the auction detail could not be read. Absence means unknown, never zero,
1354
+ * so `silent` is derivable only when this field is present.
1355
+ *
1356
+ */
1357
+ requested_count?: number;
1358
+ /**
1359
+ * Why the request drew few or no quotes, so a caller can tell "nobody can fund this right
1360
+ * now" from "my request was malformed".
1361
+ *
1362
+ * EXHAUSTIVE over agents: every agent that declined is counted exactly once, under its most
1363
+ * recent reason, so the counts sum to the number of agents that declined. An agent that
1364
+ * declined more than once with different reasons is counted once, not once per reason.
1365
+ *
1366
+ * Empty means nobody declined. ABSENT means the auction detail could not be read, so the
1367
+ * breakdown is unknown. While `status` is `collecting` it is provisional, because agents are
1368
+ * still responding.
1369
+ *
1370
+ * The free-form decline detail is never relayed, because that detail carries an agent's
1371
+ * balances and would let a caller map inventory by polling cheap quote-requests across
1372
+ * corridors.
1373
+ *
1374
+ */
1375
+ decline_summary?: Array<DeclineSummaryEntry>;
1187
1376
  };
1188
1377
  /**
1189
1378
  * Derived batch lifecycle, computed at read time (not a stored state machine). Disjoint
@@ -1201,6 +1390,45 @@ type QuoteRequestStatusResponse = {
1201
1390
  *
1202
1391
  */
1203
1392
  type status7 = 'collecting' | 'ready' | 'awarded' | 'expired';
1393
+ type DeclineSummaryEntry = {
1394
+ reason: DeclineReason;
1395
+ /**
1396
+ * Agents whose most recent decline reason was this one. Counts agents, never rows, and an
1397
+ * agent appears under one reason only.
1398
+ *
1399
+ */
1400
+ count: number;
1401
+ /**
1402
+ * What would have to change for a settler giving this reason to bid, drawn from the same
1403
+ * closed set as the `retry_classification` on an error response so a caller reads one
1404
+ * vocabulary.
1405
+ *
1406
+ * It describes the decline only. The authoritative instruction for the payment is the
1407
+ * `retry_classification` on its own error response: a payment can fail for a reason no
1408
+ * settler named, and it can succeed while some settlers declined.
1409
+ *
1410
+ * Optional, and a pattern-constrained string for the same reason `DeclineReason` is.
1411
+ *
1412
+ */
1413
+ retry_classification?: string;
1414
+ };
1415
+ /**
1416
+ * A settler's reason for not bidding, projected from its internal reason code through
1417
+ * the shared decline catalog (`apis/decline/v1/catalog.json`), which is the single
1418
+ * source of truth for the reason set. Several internal codes may map to one public
1419
+ * reason.
1420
+ *
1421
+ * Deliberately a pattern-constrained string rather than a closed enum. The set grows
1422
+ * whenever a settler gains a cause worth naming, and a consumer whose generated client
1423
+ * closes the set rejects the whole response on a value it has not seen. Treat an
1424
+ * unrecognised value as `OTHER`.
1425
+ *
1426
+ * `OTHER` covers a reason whose detail is settler-authored free text, and any reason
1427
+ * this gateway does not recognise. Both are counted so the summary stays exhaustive,
1428
+ * without relaying text we neither author nor validate.
1429
+ *
1430
+ */
1431
+ type DeclineReason = string;
1204
1432
  /**
1205
1433
  * Request body for POST /v1/payments/awards. Carries the two originator-signed artifacts:
1206
1434
  * `sender_auth` (Permit2 deposit authorization) and a fully-formed `bid_award` declaration.
@@ -1306,6 +1534,82 @@ type AwardAccepted = {
1306
1534
  * Always `awarding` — settlement is in progress server-side.
1307
1535
  */
1308
1536
  type status9 = 'awarding';
1537
+ /**
1538
+ * The addresses for one chain. Optional fields appear only where they apply to that
1539
+ * chain; an absent optional field is not an error.
1540
+ *
1541
+ */
1542
+ type ChainDefaults$1 = {
1543
+ /**
1544
+ * CAIP-2 identifier of the chain these defaults describe, normalised to lower case.
1545
+ */
1546
+ chain_id: string;
1547
+ /**
1548
+ * The account named as the reserver in the deposit authorization. Sign against this exact value; a deposit reserved by anyone else is rejected.
1549
+ */
1550
+ quote_selector: string;
1551
+ /**
1552
+ * The escrow the deposit is made into, and the spender of the token approval. Empty when the chain is not fully configured.
1553
+ */
1554
+ escrow_contract: string;
1555
+ /**
1556
+ * The contract that pays the receiver. Read this from the DESTINATION chain's defaults, not the source chain's. Empty when the chain is not fully configured.
1557
+ */
1558
+ fulfillment_proxy: string;
1559
+ /**
1560
+ * The service that attests settlement, and the account it signs with.
1561
+ */
1562
+ fulfillment_verifier: {
1563
+ /**
1564
+ * The account named as the releaser in the deposit authorization. Sign against this exact value.
1565
+ */
1566
+ account: string;
1567
+ /**
1568
+ * Base URL of the fulfillment verifier serving this chain.
1569
+ */
1570
+ endpoint: string;
1571
+ };
1572
+ /**
1573
+ * The Permit2 this chain's escrow verifies against, sent only when it is not the canonical deployment. When absent, use the canonical Permit2 address for the chain. EVM and Tron only.
1574
+ */
1575
+ permit2_contract?: string;
1576
+ /**
1577
+ * Which deposit witness this chain's escrow expects. `4` and above select the four-member witness, `3` the two-member one; absent means four. EVM and Tron only - on Solana this is carried by `svm_signature_domain_version`.
1578
+ */
1579
+ deposit_witness_version?: number;
1580
+ /**
1581
+ * Tokens this chain's escrow accepts for deposit. Absent when the gateway has no listing for the chain, which does not mean no token is accepted.
1582
+ */
1583
+ tokens?: Array<{
1584
+ symbol: string;
1585
+ /**
1586
+ * Token contract address, in the chain's native address format.
1587
+ */
1588
+ address: string;
1589
+ /**
1590
+ * Decimal places, for converting a human amount to base units.
1591
+ */
1592
+ decimals: number;
1593
+ }>;
1594
+ /**
1595
+ * Solana only. The cluster the escrow's signing domain is bound to, needed to build the deposit hash. Absent for EVM and Tron.
1596
+ */
1597
+ svm_signature_cluster_id?: string;
1598
+ /**
1599
+ * Solana only. Version of the escrow's signing domain. Absent for EVM and Tron.
1600
+ */
1601
+ svm_signature_domain_version?: number;
1602
+ };
1603
+ /**
1604
+ * Either one chain's defaults or every chain keyed by CAIP-2 chain id, depending on whether `chain_id` was supplied. A top-level `chain_id` identifies the first.
1605
+ */
1606
+ type GetDefaultsResult = ChainDefaults$1 | ChainDefaultsByChain;
1607
+ /**
1608
+ * Defaults for every chain the gateway serves, keyed by CAIP-2 chain id. Each key repeats the `chain_id` of the value it maps to.
1609
+ */
1610
+ type ChainDefaultsByChain = {
1611
+ [key: string]: ChainDefaults$1;
1612
+ };
1309
1613
  type SubmitPaymentData = {
1310
1614
  requestBody: PaymentRequest;
1311
1615
  };
@@ -1362,6 +1666,13 @@ type AwardQuoteData = {
1362
1666
  wait?: boolean;
1363
1667
  };
1364
1668
  type AwardQuoteResponse = AwardResponse | AwardAccepted;
1669
+ type GetDefaultsData = {
1670
+ /**
1671
+ * CAIP-2 chain identifier. Omit it, or send it empty, to receive every chain the gateway serves, keyed by chain id.
1672
+ */
1673
+ chainId?: string;
1674
+ };
1675
+ type GetDefaultsResponse = GetDefaultsResult;
1365
1676
  type HealthCheckResponse = {
1366
1677
  status?: string;
1367
1678
  };
@@ -1403,7 +1714,7 @@ type $OpenApiTs = {
1403
1714
  */
1404
1715
  500: ErrorResponse;
1405
1716
  /**
1406
- * A dependency is temporarily unavailable
1717
+ * The request was not accepted: a dependency is temporarily unavailable, or this operation is paused (`SERVICE_PAUSED`). Nothing was submitted, so the request is safe to retry.
1407
1718
  */
1408
1719
  503: ErrorResponse;
1409
1720
  };
@@ -1498,25 +1809,47 @@ type $OpenApiTs = {
1498
1809
  */
1499
1810
  200: AuthorizationResult;
1500
1811
  /**
1501
- * Invalid payment request
1812
+ * The request was rejected before authorization was attempted, so no
1813
+ * authorization outcome exists.
1814
+ *
1502
1815
  */
1503
1816
  400: ErrorResponse;
1504
1817
  /**
1505
- * Counterparty not found (no registration for the resolved DID)
1818
+ * The counterparty's proof was rejected (`PROOF_INVALID` or `PROOF_STALE`).
1819
+ * This is an authorization outcome, so the body is an `AuthorizationResult`
1820
+ * with `status: error`.
1821
+ *
1506
1822
  */
1507
- 404: ErrorResponse;
1823
+ 401: AuthorizationResult;
1508
1824
  /**
1509
- * Internal server error
1825
+ * Counterparty not found (no registration for the resolved DID). An
1826
+ * authorization outcome, so the body is an `AuthorizationResult` with
1827
+ * `status: error` and `error_code: COUNTERPARTY_NOT_FOUND`.
1828
+ *
1510
1829
  */
1511
- 500: ErrorResponse;
1830
+ 404: AuthorizationResult;
1512
1831
  /**
1513
- * Counterparty webhook error (HTTP error or connection failure)
1832
+ * Either shape, depending on where the failure happened. A failure before
1833
+ * authorization was attempted returns `ErrorResponse`. A failure carrying an
1834
+ * authorization outcome returns `AuthorizationResult` with `status: error`.
1835
+ *
1514
1836
  */
1515
- 502: ErrorResponse;
1837
+ 500: ErrorResponse | AuthorizationResult;
1516
1838
  /**
1517
- * Authorization timed out (counterparty did not respond)
1839
+ * Counterparty webhook error (HTTP error or connection failure). An
1840
+ * authorization outcome, so the body is an `AuthorizationResult` with
1841
+ * `status: error` and `error_code: WEBHOOK_ERROR` or
1842
+ * `WEBHOOK_CONNECTION_ERROR`.
1843
+ *
1518
1844
  */
1519
- 504: ErrorResponse;
1845
+ 502: AuthorizationResult;
1846
+ /**
1847
+ * Authorization timed out (the counterparty did not respond). An
1848
+ * authorization outcome, so the body is an `AuthorizationResult` with
1849
+ * `status: timeout`.
1850
+ *
1851
+ */
1852
+ 504: AuthorizationResult;
1520
1853
  };
1521
1854
  };
1522
1855
  };
@@ -1535,13 +1868,30 @@ type $OpenApiTs = {
1535
1868
  */
1536
1869
  202: QuoteRequestAccepted;
1537
1870
  /**
1538
- * Invalid request
1871
+ * Invalid request. `QUOTE_DEADLINE_NOT_FUTURE` is the one worth planning for: a NEW
1872
+ * quote-request whose `quote_deadline` has already passed is refused, because there is
1873
+ * no window left to collect quotes in. It does not apply to a re-submission — an
1874
+ * already-used `request_id` resolves onto the batch that exists and its expired
1875
+ * deadline is ignored, which is what makes a retry recoverable.
1876
+ *
1539
1877
  */
1540
1878
  400: ErrorResponse;
1879
+ /**
1880
+ * The `request_id` has already been used for a quote-request with different
1881
+ * economics (`IDEMPOTENCY_TERMS_MISMATCH`). Re-submitting one `request_id` is how a
1882
+ * retry is made safe, so it must identify one batch; use a distinct `request_id`
1883
+ * per quote-request.
1884
+ *
1885
+ */
1886
+ 409: ErrorResponse;
1541
1887
  /**
1542
1888
  * Internal server error
1543
1889
  */
1544
1890
  500: ErrorResponse;
1891
+ /**
1892
+ * The request was not accepted: a dependency is temporarily unavailable, or this operation is paused (`SERVICE_PAUSED`). Nothing was submitted, so the request is safe to retry.
1893
+ */
1894
+ 503: ErrorResponse;
1545
1895
  };
1546
1896
  };
1547
1897
  };
@@ -1596,6 +1946,29 @@ type $OpenApiTs = {
1596
1946
  };
1597
1947
  };
1598
1948
  };
1949
+ '/v1/defaults': {
1950
+ get: {
1951
+ req: GetDefaultsData;
1952
+ res: {
1953
+ /**
1954
+ * Chain defaults. A single object when `chain_id` was supplied, otherwise an object keyed by CAIP-2 chain id.
1955
+ */
1956
+ 200: GetDefaultsResult;
1957
+ /**
1958
+ * The `chain_id` is not a valid CAIP-2 chain identifier
1959
+ */
1960
+ 400: ErrorResponse;
1961
+ /**
1962
+ * The requested chain is not served by this gateway, or - when `chain_id` was omitted - no chain could be resolved at all
1963
+ */
1964
+ 404: ErrorResponse;
1965
+ /**
1966
+ * A dependency is temporarily unavailable
1967
+ */
1968
+ 503: ErrorResponse;
1969
+ };
1970
+ };
1971
+ };
1599
1972
  '/health': {
1600
1973
  get: {
1601
1974
  res: {
@@ -1693,6 +2066,9 @@ declare class PaymentsService {
1693
2066
  *
1694
2067
  * The response includes everything needed to sign and submit a payment, except the signature itself.
1695
2068
  *
2069
+ * Not available on every gateway or every source chain; where it is not, this
2070
+ * returns `501`. Sign the returned request and submit it to `POST /v1/payments`.
2071
+ *
1696
2072
  * @param data The data for the request.
1697
2073
  * @param data.requestBody
1698
2074
  * @returns PreparePaymentResponse Payment request prepared successfully
@@ -1743,6 +2119,31 @@ declare class QuoteRequestsService {
1743
2119
  * Collection continues server-side until the quote deadline regardless of the HTTP
1744
2120
  * connection, so quotes remain retrievable via the status endpoint in either mode.
1745
2121
  *
2122
+ * **Idempotency.** `request_id` is the idempotency key, scoped to the source account
2123
+ * and originator — the same key, and the same contract, as POST /v1/payments.
2124
+ * Submitting the same `request_id` again returns the ORIGINAL batch instead of opening
2125
+ * a second one, so a client whose request timed out or failed in transit can safely
2126
+ * re-submit and recover its `quote_request_id`.
2127
+ *
2128
+ * Because a re-submission must be admissible on its own, some fields legitimately
2129
+ * differ between attempts and are excluded from the comparison: `quote_deadline` and
2130
+ * `fulfillment_deadline` (both must be in the future, so a later attempt has to move
2131
+ * them) and the `proof` that covers them. An expired `quote_deadline` on a
2132
+ * re-submission is NOT an error — the request is resolved onto the batch that already
2133
+ * exists rather than used to open one. There is no `sender_auth` to re-sign here: this
2134
+ * endpoint rejects it, because the spend authorization belongs to the award call.
2135
+ *
2136
+ * The collection window belongs to the BATCH, not to the request. Asking again with a
2137
+ * later `quote_deadline` does not extend a window already open; `quote_deadline` in the
2138
+ * response is the batch's own, and `status` says whether collection is still running.
2139
+ *
2140
+ * What must NOT differ is the corridor's economics — source account and asset,
2141
+ * destination accounts and assets, `fulfillment_amount`, and `max_source_amount`.
2142
+ * Re-using one `request_id` for a genuinely different corridor is a client bug that
2143
+ * would otherwise be silently collapsed onto the first batch, returning quotes for a
2144
+ * corridor that was never requested. It is rejected with `409` and
2145
+ * `IDEMPOTENCY_TERMS_MISMATCH`. Use a distinct `request_id` per quote-request.
2146
+ *
1746
2147
  * @param data The data for the request.
1747
2148
  * @param data.requestBody
1748
2149
  * @param data.wait Return a handle immediately (`false`, default) or hold the connection for collected quotes (`true`).
@@ -1803,6 +2204,29 @@ declare class QuoteRequestsService {
1803
2204
  */
1804
2205
  awardQuote(data: AwardQuoteData): CancelablePromise<AwardQuoteResponse>;
1805
2206
  }
2207
+ declare class ChainDefaultsService {
2208
+ readonly httpRequest: BaseHttpRequest;
2209
+ constructor(httpRequest: BaseHttpRequest);
2210
+ /**
2211
+ * Get chain defaults
2212
+ * The addresses needed to build a payment on a chain: the escrow, the accounts named
2213
+ * in the deposit authorization, and the fulfillment verifier. Fetch these rather than
2214
+ * hardcoding them - they change when a chain's contracts are redeployed.
2215
+ *
2216
+ * With `chain_id`, returns that chain. Without it, or with an empty value, returns
2217
+ * every chain the gateway serves, keyed by CAIP-2 chain id.
2218
+ *
2219
+ * A chain that is not fully configured is still returned when asked for by
2220
+ * `chain_id`, with the missing address empty, but is left out of the full listing.
2221
+ * Treat an empty address as a chain you cannot pay on.
2222
+ *
2223
+ * @param data The data for the request.
2224
+ * @param data.chainId CAIP-2 chain identifier. Omit it, or send it empty, to receive every chain the gateway serves, keyed by chain id.
2225
+ * @returns GetDefaultsResult Chain defaults. A single object when `chain_id` was supplied, otherwise an object keyed by CAIP-2 chain id.
2226
+ * @throws ApiError
2227
+ */
2228
+ getDefaults(data?: GetDefaultsData): CancelablePromise<GetDefaultsResponse>;
2229
+ }
1806
2230
  declare class HealthService {
1807
2231
  readonly httpRequest: BaseHttpRequest;
1808
2232
  constructor(httpRequest: BaseHttpRequest);
@@ -1818,6 +2242,7 @@ declare class HealthService {
1818
2242
  type HttpRequestConstructor$1 = new (config: OpenAPIConfig) => BaseHttpRequest;
1819
2243
  declare class PaymentGatewayClient$1 {
1820
2244
  readonly authorizations: AuthorizationsService;
2245
+ readonly chainDefaults: ChainDefaultsService;
1821
2246
  readonly health: HealthService;
1822
2247
  readonly payments: PaymentsService;
1823
2248
  readonly quoteRequests: QuoteRequestsService;
@@ -1826,7 +2251,30 @@ declare class PaymentGatewayClient$1 {
1826
2251
  }
1827
2252
 
1828
2253
  /**
1829
- * Chain defaults returned by the payment gateway /defaults endpoint.
2254
+ * Budget for a request the gateway answers as soon as it can. Generous on
2255
+ * purpose: aborting a live submit loses track of a payment, while waiting only
2256
+ * costs patience. Bounds socket inactivity, not total time, so a large healthy
2257
+ * response is never cut off partway.
2258
+ */
2259
+ declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
2260
+ /**
2261
+ * Budget for a request the gateway holds open while it collects quotes or
2262
+ * settles. Must clear the server's own cap (`payment_sync_wait_seconds` 30s,
2263
+ * `quote_sync_wait_seconds` 5s, both deployment-configurable) with margin: the
2264
+ * client's timer starts at connect, before the server arms its own, so an equal
2265
+ * budget loses the race every time.
2266
+ */
2267
+ declare const DEFAULT_SYNC_WAIT_TIMEOUT_MS = 120000;
2268
+ /** Per-client overrides for the two budgets above. */
2269
+ type RequestTimeouts = {
2270
+ /** Requests answered as soon as possible. Defaults to {@link DEFAULT_REQUEST_TIMEOUT_MS}. */
2271
+ timeoutMs?: number;
2272
+ /** Requests the gateway holds open. Defaults to {@link DEFAULT_SYNC_WAIT_TIMEOUT_MS}. */
2273
+ syncWaitTimeoutMs?: number;
2274
+ };
2275
+
2276
+ /**
2277
+ * Chain defaults returned by the payment gateway /v1/defaults endpoint.
1830
2278
  */
1831
2279
  interface ChainDefaults {
1832
2280
  escrowContract: string;
@@ -1835,9 +2283,22 @@ interface ChainDefaults {
1835
2283
  fulfillmentVerifierEndpoint: string;
1836
2284
  fulfillmentProxy: string;
1837
2285
  permit2Contract?: string;
2286
+ /**
2287
+ * Which deposit witness the escrow deployed on this chain pins, surfaced by payment-gw
2288
+ * `/v1/defaults` as `deposit_witness_version` (CORE-2033). EVM/Tron only — Solana carries the
2289
+ * same fact in `svmSignatureDomainVersion` below.
2290
+ *
2291
+ * `4` and above select the CORE-2120 four-member witness
2292
+ * (`depositRequestHash`, `destination`, `reserver`, `releaser`); `3` selects the two-member
2293
+ * witness a not-yet-redeployed escrow pins. ABSENT means four — see the sender-auth package's
2294
+ * `ChainDefaults.depositWitnessVersion` for why absence is the permissive default.
2295
+ *
2296
+ * Passed through to the sender_auth adapter verbatim; this type only has to carry it.
2297
+ */
2298
+ depositWitnessVersion?: number;
1838
2299
  /**
1839
2300
  * V3 Solana escrow domain-separation fields, surfaced by payment-gw
1840
- * `/defaults` for Solana source chains. Used to build the EscrowDomain that the
2301
+ * `/v1/defaults` for Solana source chains. Used to build the EscrowDomain that the
1841
2302
  * V3 deposit hash binds to. Absent for EVM/Tron.
1842
2303
  */
1843
2304
  svmSignatureClusterId?: string;
@@ -1910,7 +2371,8 @@ interface TurnkeyConfig {
1910
2371
  /**
1911
2372
  * Chain-native address the signer is expected to resolve to. Verified against
1912
2373
  * the address Turnkey returns at initialize(); a mismatch fails fast rather
1913
- * than signing as the wrong depositor.
2374
+ * than signing as the wrong depositor. Omit it to skip the check; an empty
2375
+ * value is rejected rather than treated as omitted.
1914
2376
  */
1915
2377
  pinnedAddress?: string;
1916
2378
  /**
@@ -1920,7 +2382,10 @@ interface TurnkeyConfig {
1920
2382
  logger?: Logger;
1921
2383
  meter?: Meter;
1922
2384
  }
1923
- /** Options selecting a sender-signing provider. Defaults to the private-key provider. */
2385
+ /**
2386
+ * Options selecting a sender-signing provider. Defaults to the private-key provider.
2387
+ * `pinnedAddress` behaves the same on both: omitted skips the sender check, empty is rejected.
2388
+ */
1924
2389
  type SenderSignerOptions = {
1925
2390
  provider?: 'raw';
1926
2391
  privateKey: string;
@@ -1946,6 +2411,11 @@ declare class TurnkeySenderSigner implements SenderSigner {
1946
2411
  private readonly chainPrefix;
1947
2412
  private readonly cfg;
1948
2413
  private readonly loader;
2414
+ /**
2415
+ * Validated at construction and read from here rather than from `cfg`, so a caller that
2416
+ * later blanks the config object it passed cannot erase the pin before it is forwarded.
2417
+ */
2418
+ private readonly pinnedAddress;
1949
2419
  constructor(chainPrefix: string, cfg: TurnkeyConfig, loader?: () => Promise<TurnkeyImplModule>);
1950
2420
  sign(signedMessage: SignedMessage): Promise<SenderSignature>;
1951
2421
  }
@@ -1962,7 +2432,88 @@ declare function createSenderSigner(sourceChainId: string, opts: SenderSignerOpt
1962
2432
  * query. The Turnkey impl is loaded lazily so a plain SDK import stays free of
1963
2433
  * @solana/web3.js.
1964
2434
  */
1965
- declare function resolveTurnkeyAddresses(cfg: TurnkeyConfig): Promise<Record<string, string>>;
2435
+ declare function resolveTurnkeyAddresses(cfg: Omit<TurnkeyConfig, 'pinnedAddress'>): Promise<Record<string, string>>;
2436
+
2437
+ /**
2438
+ * CAIP-19 asset identifier parsing, backing the caller-facing entry points.
2439
+ *
2440
+ * Every caller-facing entry point parses here first. Downstream, the deposit builders read an
2441
+ * identifier as raw string slicing (`asset.split('/')[1]!.split(':')[1]!`) and hand the result to
2442
+ * `ethers`, which can only report a bad value as a TypeError or as `invalid address`, so the value
2443
+ * has to be named and explained before it gets there. Parsing also canonicalizes the segments CAIP
2444
+ * requires lowercase.
2445
+ */
2446
+ /** An asset identifier split into its parts, canonicalized. */
2447
+ interface ParsedAssetIdentifier {
2448
+ /** CAIP-2 chain id, namespace lowercased: `eip155:421614`. */
2449
+ chainId: string;
2450
+ /** Lowercased CAIP-2 namespace: `eip155`, `tron`, `solana`. */
2451
+ namespace: string;
2452
+ /**
2453
+ * CAIP-2 chain reference, canonicalized per namespace, mirroring `manifest.CanonicalizeCAIP2`.
2454
+ * A tron reference is an ASCII cluster name and folds to lowercase, so `TRON:MAINNET` routes
2455
+ * instead of dying at a Permit2 lookup that resolves by exact chain id. A solana reference is
2456
+ * preserved: it is base58, and its cluster name is UTF-8 encoded into the escrow's on-chain
2457
+ * `cluster_id`, so folding it would change the signing domain.
2458
+ */
2459
+ reference: string;
2460
+ /** Lowercased asset namespace: `erc20`, `trc20`, `token`, … */
2461
+ assetNamespace: string;
2462
+ /** Token address, exactly as the caller wrote it. */
2463
+ tokenAddress: string;
2464
+ /** CAIP-19 token id, for the asset types that carry one. */
2465
+ tokenId?: string;
2466
+ /**
2467
+ * The identifier with the namespaces lowercased and a tron reference folded with them. The
2468
+ * PaymentRequest schema pins `asset_identifier` to lowercase namespaces, so this is the spelling
2469
+ * that goes on the wire and into the deposit builders.
2470
+ *
2471
+ * Aligned with `manifest.CanonicalizeCAIP2`, not with `blockchain.AssetIdentifier.String()`,
2472
+ * which preserves the asset namespace this lowercases. Aligning to `String()` is not an option:
2473
+ * the schema pattern rejects an uppercase asset namespace, so Go's own `ComputeRequestHash`
2474
+ * refuses to hash one.
2475
+ *
2476
+ * Not a commitment preimage. `ComputeRequestHash` covers this string verbatim, so the spelling is
2477
+ * the request's identity, but anything that hashes a CAIP-19 across independent producers has to
2478
+ * derive it from one shared implementation rather than from here, since the escrow's destination
2479
+ * commitment composes and folds the string on different rules.
2480
+ */
2481
+ normalized: string;
2482
+ }
2483
+ /**
2484
+ * Parse and validate a CAIP-19 asset identifier.
2485
+ *
2486
+ * The two namespaces are lowercased, and a tron chain reference with them. A solana reference, the
2487
+ * token address and the token id are returned as written, so a case-sensitive base58 value
2488
+ * survives. Their case still matters:
2489
+ * `ComputeRequestHash` covers the spelling verbatim, so two spellings of one asset give two
2490
+ * different `request_hash` values while leaving the deposit digest identical.
2491
+ */
2492
+ declare function parseAssetIdentifier(value: unknown): ParsedAssetIdentifier;
2493
+ /**
2494
+ * The CAIP-2 chain id with its namespace lowercased, for callers that only need to route on the
2495
+ * chain. Applies the same validation, so a malformed identifier fails with the same message.
2496
+ */
2497
+ declare function assetChainId(value: unknown): string;
2498
+
2499
+ /**
2500
+ * The frozen rejection taxonomy. These strings are part of the cross-language contract: Go must
2501
+ * reject the same input with the same reason.
2502
+ *
2503
+ * The union is derived from this array rather than declared beside it, so a reason cannot be added
2504
+ * to the type without appearing here, and the coverage test that demands a vector per reason reads
2505
+ * the same source. An array declared separately from the union would not be checked against it: a
2506
+ * `Reason[]` may omit members freely.
2507
+ */
2508
+ declare const REASONS: readonly ["EMPTY", "SURROUNDING_WHITESPACE", "UNSUPPORTED_NAMESPACE", "UNPARSEABLE", "ZERO"];
2509
+ type Reason = (typeof REASONS)[number];
2510
+ declare class InvalidAccountError extends Error {
2511
+ readonly reason: Reason;
2512
+ readonly network: string;
2513
+ readonly account: string;
2514
+ readonly detail: string;
2515
+ constructor(reason: Reason, network: string, account: string, detail?: string);
2516
+ }
1966
2517
 
1967
2518
  declare const $AuthorizationResult: {
1968
2519
  readonly type: "object";
@@ -1972,7 +2523,7 @@ declare const $AuthorizationResult: {
1972
2523
  readonly payment_id: {
1973
2524
  readonly type: "string";
1974
2525
  readonly description: "Correlation key for this authorization";
1975
- readonly example: "0x1234abcd";
2526
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
1976
2527
  };
1977
2528
  readonly counterparty_did: {
1978
2529
  readonly type: "string";
@@ -1992,9 +2543,9 @@ declare const $AuthorizationResult: {
1992
2543
  };
1993
2544
  readonly error_code: {
1994
2545
  readonly type: "string";
1995
- readonly description: "Machine-readable error code (present when status is error or timeout).\nCounterparty-sourced codes are derived from the error code the\nCounterparty Gateway publishes. GATEWAY_TIMEOUT, PROOF_INVALID, and\nPROOF_STALE are payment-gw-specific (no counterparty envelope corresponds).\n";
2546
+ readonly description: "Machine-readable error code (present when status is error or timeout).\nCounterparty-sourced codes are derived from the error code the\nCounterparty Gateway publishes. GATEWAY_TIMEOUT, PROOF_INVALID, and\nPROOF_STALE are raised by this gateway itself (no counterparty envelope corresponds).\n";
1996
2547
  readonly enum: readonly ["COUNTERPARTY_NOT_FOUND", "COUNTERPARTY_TIMEOUT", "WEBHOOK_ERROR", "WEBHOOK_CONNECTION_ERROR", "INTERNAL_ERROR", "GATEWAY_TIMEOUT", "PROOF_INVALID", "PROOF_STALE"];
1997
- readonly 'x-enum-description': "COUNTERPARTY_NOT_FOUND, COUNTERPARTY_TIMEOUT, WEBHOOK_ERROR,\nWEBHOOK_CONNECTION_ERROR, and INTERNAL_ERROR are derived from the\nerror code the Counterparty Gateway publishes.\nGATEWAY_TIMEOUT is emitted by payment-gw when no authorization\nresponse is received within the system-wide timeout — source unknown\n(counterparty delay, transport failure, or gateway unavailability).\nOriginator should retry; counterparty-side idempotency prevents PSP re-charge\nif the original was already processed.\n\nPROOF_INVALID is emitted when the W3C Data Integrity proof on the\nbeneficiary PSP's AuthorizationResponse fails verification: signature\nrecovery failed, recovered DID does not match the destination DID,\nresponse shape is malformed (missing @context / payment_id /\ncounterparty_did / proof), or the suite type is unsupported. The\nunderlying reason cardinality is collapsed so originators see one\nactionable category.\n\nPROOF_STALE is emitted when proof.created falls outside the\nconfigured freshness window. Originators should retry with a fresh\nrequest — the freshness window closes a replay attack vector where a\ncaptured-but-cryptographically-valid proof could otherwise be replayed\nindefinitely.\n";
2548
+ readonly 'x-enum-description': "COUNTERPARTY_NOT_FOUND, COUNTERPARTY_TIMEOUT, WEBHOOK_ERROR,\nWEBHOOK_CONNECTION_ERROR, and INTERNAL_ERROR are derived from the\nerror code the Counterparty Gateway publishes.\nGATEWAY_TIMEOUT is emitted by the gateway when no authorization\nresponse is received within the system-wide timeout — source unknown\n(counterparty delay, transport failure, or gateway unavailability).\nOriginator should retry; counterparty-side idempotency prevents PSP re-charge\nif the original was already processed.\n\nPROOF_INVALID is emitted when the W3C Data Integrity proof on the\nbeneficiary PSP's AuthorizationResponse fails verification: signature\nrecovery failed, recovered DID does not match the destination DID,\nresponse shape is malformed (missing @context / payment_id /\ncounterparty_did / proof), or the suite type is unsupported. The\nunderlying reason cardinality is collapsed so originators see one\nactionable category.\n\nPROOF_STALE is emitted when proof.created falls outside the\nconfigured freshness window. Originators should retry with a fresh\nrequest — the freshness window closes a replay attack vector where a\ncaptured-but-cryptographically-valid proof could otherwise be replayed\nindefinitely.\n";
1998
2549
  };
1999
2550
  readonly error_message: {
2000
2551
  readonly type: "string";
@@ -2007,13 +2558,13 @@ declare const $AuthorizationResult: {
2007
2558
  };
2008
2559
  };
2009
2560
  declare const $PaymentRequest: {
2010
- readonly type: "object";
2011
2561
  readonly description: "Structured payment request with sender authorization and optional W3C Verifiable Credentials";
2562
+ readonly type: "object";
2012
2563
  readonly required: readonly ["version", "request_id", "source", "destination", "fulfillment_amount", "sender_auth", "quote_deadline", "fulfillment_deadline"];
2013
2564
  readonly properties: {
2014
2565
  readonly version: {
2015
2566
  readonly type: "string";
2016
- readonly description: "Semver-shaped declaration version (MAJOR.MINOR). The major component is locked to this schema's\nparent directory (v1 → major must be 1). Producers MUST emit the canonical value exported by the\nbindings' Version constant; the canonical bumps on each additive minor evolution.\n";
2567
+ readonly description: "Semver-shaped declaration version (MAJOR.MINOR). The major component is locked to this schema's parent directory (v1 → major must be 1). Producers MUST emit the canonical value exported by the bindings' Version constant; the canonical bumps on each additive minor evolution.";
2017
2568
  readonly pattern: "^1\\.[0-9]+$";
2018
2569
  readonly example: "1.0";
2019
2570
  };
@@ -2027,37 +2578,38 @@ declare const $PaymentRequest: {
2027
2578
  };
2028
2579
  readonly destination: {
2029
2580
  readonly type: "array";
2030
- readonly description: "Array of destination assets for the settlement agent to choose from (at least one required)";
2581
+ readonly description: "Array of destination assets for the settlement agent to choose from (at least one required, at most 16).\nThe ceiling bounds the fan-out one request can buy: every consumer iterates this list.";
2031
2582
  readonly minItems: 1;
2583
+ readonly maxItems: 16;
2032
2584
  readonly items: {
2033
2585
  readonly $ref: "#/components/schemas/OwnedAsset";
2034
2586
  };
2035
2587
  };
2036
2588
  readonly fulfillment_amount: {
2037
2589
  readonly type: "string";
2038
- readonly description: "The exact amount to be received at the destination (in the smallest unit, e.g., wei for ETH, cents for USD).\n";
2590
+ readonly description: "The exact amount to be received at the destination (in the smallest unit, e.g., wei for ETH, cents for USD).";
2039
2591
  readonly example: "1000000";
2040
2592
  };
2041
2593
  readonly max_source_amount: {
2042
2594
  readonly type: "string";
2043
- readonly description: "The maximum amount willing to be spent from the source (in the smallest unit).\n";
2595
+ readonly description: "The maximum amount willing to be spent from the source (in the smallest unit).";
2044
2596
  readonly example: "1000000";
2045
2597
  };
2046
2598
  readonly quote_deadline: {
2047
2599
  readonly type: "string";
2048
2600
  readonly format: "date-time";
2049
- readonly description: "Required. The deadline for receiving price quotes from settlement providers. After this\npoint no new quotes are accepted. The gateway injects no default and validates the value\nis in the future. The originator must supply it, and a request that omits it or supplies\na past value is rejected with 400.\n";
2601
+ readonly description: "Required. The deadline for receiving price quotes from settlement providers. After this\npoint no new quotes are accepted. The gateway injects no default and validates the value\nis in the future. The originator must supply it, and a request that omits it or supplies\na past value is rejected with 400.";
2050
2602
  readonly example: "2024-12-25T10:30:00Z";
2051
2603
  };
2052
2604
  readonly fulfillment_deadline: {
2053
2605
  readonly type: "string";
2054
2606
  readonly format: "date-time";
2055
- readonly description: "Required. The final deadline for completing the payment. If not completed by this time the\npayment is cancelled and eligible for a refund. The gateway injects no default and validates\nthe value is in the future. The originator must supply it, and a request that omits it or\nsupplies a past value is rejected with 400.\n";
2607
+ readonly description: "Required. The final deadline for completing the payment. If not completed by this time the\npayment is cancelled and eligible for a refund. The gateway injects no default and validates\nthe value is in the future. The originator must supply it, and a request that omits it or\nsupplies a past value is rejected with 400.";
2056
2608
  readonly example: "2024-12-25T11:00:00Z";
2057
2609
  };
2058
2610
  readonly settler_auth_required: {
2059
2611
  readonly type: "object";
2060
- readonly description: "Policy requirements for settler authentication. Keys are policy names, values indicate if the policy is required.\n";
2612
+ readonly description: "Policy requirements for settler authentication. Keys are policy names, values indicate if the policy is required.";
2061
2613
  readonly additionalProperties: {
2062
2614
  readonly type: "boolean";
2063
2615
  };
@@ -2070,12 +2622,12 @@ declare const $PaymentRequest: {
2070
2622
  };
2071
2623
  readonly quote_selector: {
2072
2624
  readonly type: "string";
2073
- readonly description: "Wallet address or public key of a trusted service that will automatically select \nthe best exchange rate for your payment. Leave empty to use the default selector.\n";
2074
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
2625
+ readonly description: "Wallet address or public key of a trusted service that will automatically select\nthe best exchange rate for your payment. Leave empty to use the default selector.";
2626
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2075
2627
  };
2076
2628
  readonly fulfillment_verifier: {
2077
2629
  readonly type: "object";
2078
- readonly description: "Third-party service that will independently verify your payment was delivered.\nLeave empty to use the default verifier.\n";
2630
+ readonly description: "Third-party service that will independently verify your payment was delivered.\nLeave empty to use the default verifier.";
2079
2631
  readonly required: readonly ["account", "endpoint"];
2080
2632
  readonly properties: {
2081
2633
  readonly account: {
@@ -2086,48 +2638,48 @@ declare const $PaymentRequest: {
2086
2638
  readonly endpoint: {
2087
2639
  readonly type: "string";
2088
2640
  readonly format: "uri";
2089
- readonly description: "Origin of the fulfillment verifier service, with no path — the caller\nappends the verifier's own API paths. The gateway's `/defaults` response\nsupplies the default fulfillment verifier for each chain.\n";
2641
+ readonly description: "Origin of the fulfillment verifier service, with no path — the caller\nappends the verifier's own API paths. The gateway's `/v1/defaults` response\nsupplies the default fulfillment verifier for each chain.";
2090
2642
  readonly example: "https://veri-fill.production-testnet.atum.xyz";
2091
2643
  };
2092
2644
  };
2093
2645
  };
2094
2646
  readonly escrow_contract_address: {
2095
2647
  readonly type: "string";
2096
- readonly description: "Escrow contract address, used to protect source funds until proof of fulfillment has been verified. Leave empty to use the default.\n";
2097
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
2648
+ readonly description: "Escrow contract address, used to protect source funds until proof of fulfillment has been verified. Leave empty to use the default.";
2649
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2098
2650
  };
2099
2651
  readonly fulfillment_proxy: {
2100
2652
  readonly type: "string";
2101
- readonly description: "Fulfillment Proxy contract address, used to emit proof of fulfillment on the destination chain. Leave empty to use the default.\n";
2653
+ readonly description: "Fulfillment Proxy contract address, used to emit proof of fulfillment on the destination chain. Leave empty to use the default.";
2102
2654
  readonly example: "0x892BB2e4F6b14a2B5b82Ba8d33E5925D42D4431F";
2103
2655
  };
2104
2656
  readonly settler_requirements: {
2105
2657
  readonly type: "object";
2106
- readonly description: "Optional settler filtering requirements.\nIf whitelist is present, only whitelisted settlers may win.\nIf blacklist is present, blacklisted settlers are excluded.\nBoth can be specified together; blacklist takes precedence\n(a settler in both lists is rejected).\n";
2658
+ readonly description: "Optional settler filtering requirements. If whitelist is present, only whitelisted settlers may win. If blacklist is present, blacklisted settlers are excluded. Both can be specified; blacklist takes precedence (a settler in both lists is rejected).";
2107
2659
  readonly properties: {
2108
2660
  readonly whitelist: {
2109
2661
  readonly type: "array";
2110
- readonly description: "List of settler DIDs permitted to fulfill this request.\nIf present, only these settlers may win.\nUse W3C DID format.\n";
2662
+ readonly uniqueItems: true;
2111
2663
  readonly minItems: 1;
2112
2664
  readonly maxItems: 100;
2113
- readonly uniqueItems: true;
2665
+ readonly description: "List of settler DIDs permitted to fulfill this request. If present and non-empty, only these settlers may win. Use W3C DID format (e.g., did:pkh:eip155:1:0xABC...).";
2114
2666
  readonly items: {
2115
2667
  readonly type: "string";
2116
2668
  readonly pattern: "^did:[a-z][a-z0-9]*:[a-zA-Z0-9._:%-]+$";
2117
2669
  };
2118
- readonly example: readonly ["did:pkh:eip155:1:0x742d35Cc6634C0532925a3b844Bc9e7595f4136"];
2670
+ readonly example: readonly ["did:pkh:eip155:1:0x742D35cC6634c0532925a3b844Bc9e7595F41360"];
2119
2671
  };
2120
2672
  readonly blacklist: {
2121
2673
  readonly type: "array";
2122
- readonly description: "List of settler DIDs excluded from fulfilling this request.\nUse W3C DID format.\n";
2674
+ readonly uniqueItems: true;
2123
2675
  readonly minItems: 1;
2124
2676
  readonly maxItems: 100;
2125
- readonly uniqueItems: true;
2677
+ readonly description: "List of settler DIDs excluded from fulfilling this request. If present and non-empty, these settlers are rejected. Use W3C DID format (e.g., did:pkh:eip155:1:0xABC...).";
2126
2678
  readonly items: {
2127
2679
  readonly type: "string";
2128
2680
  readonly pattern: "^did:[a-z][a-z0-9]*:[a-zA-Z0-9._:%-]+$";
2129
2681
  };
2130
- readonly example: readonly ["did:pkh:eip155:1:0x892BB2e4F6b14a2B5b82Ba8d33E5925D42D4432F"];
2682
+ readonly example: readonly ["did:pkh:eip155:1:0x892bb2E4F6b14a2B5b82bA8D33e5925d42d4432f"];
2131
2683
  };
2132
2684
  };
2133
2685
  };
@@ -2190,31 +2742,33 @@ declare const $FulfillmentConfirmation: {
2190
2742
  };
2191
2743
  declare const $OwnedAsset: {
2192
2744
  readonly type: "object";
2193
- readonly description: "Represents a cryptocurrency or token in a specific wallet.\nThis tells the system what asset you're sending/receiving and which wallet to use.\n";
2745
+ readonly description: "Represents a cryptocurrency or token in a specific wallet. This tells the system what asset you're sending/receiving and which wallet to use.";
2194
2746
  readonly required: readonly ["asset_identifier", "account"];
2195
2747
  readonly properties: {
2196
2748
  readonly asset_identifier: {
2197
2749
  readonly type: "string";
2198
- readonly description: "A unique identifier for the asset using CAIP-19 format.\nCAIP-19 is a standard way to identify blockchain assets: {chain_id}/{asset_namespace}:{asset_reference}\nExamples:\n- Ethereum USDC: \"eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"\n- Arbitrum USDC: \"eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831\"\n- Solana USDC: \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"\n- Tron USDT: \"tron:mainnet/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t\"\n";
2750
+ readonly description: "A unique identifier for the asset using CAIP-19 format.\nCAIP-19 is a standard way to identify blockchain assets: {chain_id}/{asset_namespace}:{asset_reference}\nExamples:\n- Ethereum USDC: \"eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\"\n- Arbitrum USDC: \"eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831\"\n- Solana USDC: \"solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\"\n- Tron USDT: \"tron:mainnet/trc20:TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t\"";
2199
2751
  readonly pattern: "^[a-z0-9]+:[a-zA-Z0-9_-]+/[a-z0-9-]{3,8}:[-.%a-zA-Z0-9]{1,128}(/[-.%a-zA-Z0-9]{1,78})?$";
2200
2752
  readonly example: "eip155:1/erc20:0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48";
2201
2753
  };
2202
2754
  readonly account: {
2203
2755
  readonly type: "string";
2204
- readonly description: "The wallet address that owns this asset.\nFormat depends on the blockchain:\n- Ethereum/EVM: 0x-prefixed hex address (42 characters)\n- Solana: Base58 encoded address\n- Tron: T-prefixed Base58 address\n";
2756
+ readonly description: "The wallet address that owns this asset.\nFormat depends on the blockchain:\n- Ethereum/EVM: 0x-prefixed hex address (42 characters)\n- Solana: Base58 encoded address\n- Tron: T-prefixed Base58 address\n\nA destination account is checked at ingress and must be payable on the chain named by\nits `asset_identifier`: it parses for that chain, carries a valid EIP-55 checksum when\nmixed-case, has no surrounding whitespace, and is not the zero address. A receiver that\nfails any of these is refused with `INVALID_DESTINATION_ACCOUNT`, before any funds move.";
2205
2757
  readonly minLength: 1;
2206
2758
  readonly maxLength: 128;
2207
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
2759
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2208
2760
  };
2209
2761
  };
2210
2762
  };
2211
2763
  declare const $SenderAuth: {
2212
2764
  readonly type: "object";
2213
- readonly description: "Authorization from the asset owner to execute the payment. The exact format depends on \nthe source blockchain's authorization mechanism.\n";
2765
+ readonly description: "Authorization from the asset owner to execute the payment. The exact format depends on the source blockchain's authorization mechanism.";
2214
2766
  readonly required: readonly ["message_scheme", "signed_messages"];
2215
2767
  readonly properties: {
2216
2768
  readonly verifiable_credential: {
2217
2769
  readonly $ref: "#/components/schemas/VerifiableCredentialAuth";
2770
+ readonly deprecated: true;
2771
+ readonly description: "DEPRECATED: inner-document credential carrier. Credentials MUST ride ONLY in the holder-signed PaymentRequestEnvelope (PRE); the inner PaymentRequest carries no credential and its Data Integrity signature EXCLUDES this field (stripped before canonicalization on both producer and verifier). Populated only for one back-compat rollout cycle, then removed.";
2218
2772
  };
2219
2773
  readonly message_scheme: {
2220
2774
  readonly $ref: "#/components/schemas/SenderAuthMessageScheme";
@@ -2231,34 +2785,42 @@ declare const $SenderAuth: {
2231
2785
  };
2232
2786
  declare const $SenderAuthMessageScheme: {
2233
2787
  readonly type: "string";
2234
- readonly description: "The signature method used for authorizing this payment:\n- `EVM_PERMIT2`: Gasless token approvals for Ethereum/EVM chains\n- `SOLANA`: Standard Solana transaction signatures\n- `TRON`: Tron transaction signatures\n";
2788
+ readonly description: "The signature method used for authorizing this payment:\n- `EVM_PERMIT2`: Gasless token approvals for Ethereum/EVM chains\n- `EVM_PERMIT2_ESCROW`: Gasless approvals with escrow support\n- `SOLANA`: Standard Solana transaction signatures\n- `TRON`: Tron transaction signatures";
2235
2789
  readonly enum: readonly ["EVM_PERMIT2", "EVM_PERMIT2_ESCROW", "SOLANA", "TRON"];
2236
2790
  };
2237
2791
  declare const $SignedMessage: {
2238
2792
  readonly type: "object";
2239
- readonly description: "A message that has been cryptographically signed to prove authorization.\nThe signature proves you control the wallet that's sending funds.\n";
2793
+ readonly description: "A message that has been cryptographically signed to prove authorization. The signature proves you control the wallet that's sending funds.";
2240
2794
  readonly required: readonly ["message", "signature"];
2241
2795
  readonly properties: {
2242
2796
  readonly message: {
2243
2797
  readonly type: "string";
2244
- readonly description: "The data that was signed. Format depends on the blockchain:\n- EVM: Hex-encoded message hash (with 0x prefix)\n- Solana: Base64 encoded message\n- Tron: Hex-encoded message hash (possibly without 0x prefix)\n";
2798
+ readonly description: "The data that was signed. Format depends on the blockchain:\n- EVM: Hex-encoded message hash (with 0x prefix)\n- Solana: Hex-encoded message hash (with 0x prefix)\n- Tron: Hex-encoded message hash (possibly without 0x prefix)";
2245
2799
  readonly example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
2246
2800
  };
2247
2801
  readonly message_prehash: {
2248
2802
  readonly type: "string";
2249
- readonly description: "Optional: If 'message' contains a hash, this field contains the original data\nbefore it was hashed. Useful for verification and debugging.\n";
2803
+ readonly description: "Optional: If 'message' contains a hash, this field contains the original data before it was hashed. Useful for verification and debugging.";
2250
2804
  readonly example: "{\"permit\":{\"token\":\"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\",\"amount\":\"1000000\"}}";
2251
2805
  };
2252
2806
  readonly signature: {
2253
2807
  readonly type: "string";
2254
- readonly description: "The cryptographic signature proving you authorized this message.\nFormat varies by blockchain (hex for EVM/Tron, base58 for Solana).\n";
2808
+ readonly description: "The cryptographic signature proving you authorized this message. Hex-encoded with a 0x prefix on every supported chain. The signer's own public key is base58 on Solana, but the signature itself is not.";
2255
2809
  readonly example: "0xabcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890ab1c";
2256
2810
  };
2811
+ readonly payload: {
2812
+ readonly type: "object";
2813
+ readonly description: "Optional chain-specific payload containing additional signing context (e.g., delegate_signer for Solana). Preserved through the pipeline for downstream consumers.";
2814
+ readonly additionalProperties: true;
2815
+ readonly example: {
2816
+ readonly delegate_signer: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin";
2817
+ };
2818
+ };
2257
2819
  };
2258
2820
  };
2259
2821
  declare const $VerifiableCredentialAuth: {
2260
2822
  readonly type: "object";
2261
- readonly description: "Optional identity verification using cryptographic credentials.\nRequired when regulatory compliance or KYC verification is needed for the payment.\n";
2823
+ readonly description: "Optional identity verification using cryptographic credentials.\n\nDEPRECATED. Credentials are moving to a holder-signed W3C VerifiablePresentation that\ntravels alongside a request rather than inside it. That envelope is not part of this\nHTTP contract, so there is nothing here to move them to yet: treat this as a legacy\ncarrier, and do not build a new integration on it.";
2262
2824
  readonly required: readonly ["verifiable_credential", "verification_method_id", "signature"];
2263
2825
  readonly properties: {
2264
2826
  readonly verifiable_credential: {
@@ -2324,7 +2886,7 @@ declare const $VerifiableCredential: {
2324
2886
  };
2325
2887
  readonly credentialStatus: {
2326
2888
  readonly type: "object";
2327
- readonly description: "Information for credential revocation checking";
2889
+ readonly description: "Information for credential revocation checking. Not consulted by the verifier today.";
2328
2890
  readonly additionalProperties: true;
2329
2891
  };
2330
2892
  readonly proof: {
@@ -2336,13 +2898,13 @@ declare const $VerifiableCredential: {
2336
2898
  };
2337
2899
  declare const $PaymentResponse: {
2338
2900
  readonly type: "object";
2339
- readonly description: "Response from submitting a payment request. If settlement completes inside the\ngateway's synchronous window, the response includes a fulfillment_confirmation with\nfull settlement details. Otherwise you receive a payment_id plus the payment's\ncurrent `status`, and can poll /v1/payments/{paymentId}/status for updates.\n\nRead `status` before deciding what to do next: a `pending` payment is in flight and\nmust NOT be re-submitted under a new request_id (that would be a second payment),\nwhereas a `failed` or `cancelled` one is terminal — re-submitting it under the SAME\nrequest_id resolves to the same terminal payment, so a genuine re-attempt needs a\nnew request_id.\n";
2901
+ readonly description: "Response from submitting a payment request. If settlement completes inside the\ngateway's synchronous window, the response includes a fulfillment_confirmation with\nfull settlement details. Otherwise you receive a payment_id plus the payment's\ncurrent `status`, and can poll /v1/payments/{paymentId}/status for updates.\n\nRead `status` before deciding what to do next: a `pending` payment is in flight and\nmust NOT be re-submitted under a new request_id (that would be a second payment),\nwhereas a `failed` or `cancelled` one is terminal — re-submitting it under the SAME\nrequest_id resolves to the same terminal payment, so a genuine re-attempt needs a\nnew request_id.\n\n**A synchronously-completed payment carries proof of QUOTE as well as of delivery.** When\nsettlement lands inside the window you get `status: completed`, a full\n`fulfillment_confirmation`, and — since a quote necessarily was awarded to get there —\n`quote_id` and `fulfillment_quote`. The fast path therefore needs no follow-up call to\nverify: recompute `quote_hash` over the returned quote and compare it against the on-chain\ncommitment from this response alone.\n";
2340
2902
  readonly required: readonly ["payment_id", "status", "idempotent_replay"];
2341
2903
  readonly properties: {
2342
2904
  readonly payment_id: {
2343
2905
  readonly type: "string";
2344
2906
  readonly description: "Unique ID for tracking this payment. Save this to check status later.\n";
2345
- readonly example: "550e8400-e29b-41d4-a716-446655440000";
2907
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
2346
2908
  };
2347
2909
  readonly status: {
2348
2910
  readonly type: "string";
@@ -2354,6 +2916,16 @@ declare const $PaymentResponse: {
2354
2916
  readonly description: "Whether this response describes a payment that already existed, rather than one\ncreated by this request. `true` means the request_id had been used before and you\nare being handed the ORIGINAL payment — no second payment was created and nothing\nadditional was charged.\n\n**Re-attempting a payment.** Re-submit the same request and you get the same payment\nback. You may re-send the original bytes unchanged: the deadlines will have expired by\nthen — `quote_deadline` bounds the auction and is short, while this endpoint may hold a\nsubmission for up to 30 seconds — and an expired deadline on a re-submission is not an\nerror, because the request is resolved onto the payment that already exists rather than\nused to create one.\n\nRe-signing with fresh deadlines is equally fine and returns the same payment. What you\nmust NOT change is the request_id, and what you must not change under it is the\npayment's economics — source, destination, fulfillment_amount, max_source_amount — which\nare rejected with 409 IDEMPOTENCY_TERMS_MISMATCH. Deadlines and the signature are\nexempt precisely so that a re-attempt is possible.\n\nA genuinely new payment needs a NEW request_id. In particular a `failed` payment is\nterminal: re-submitting its request_id keeps returning that dead payment, so recovering\nmeans starting a new one under a new key.\n\nPresent on every response, `false` for a newly created payment. A response without\nthe field is from a gateway predating it, not a newly created payment.\n\nThis is the field to read when reconciling a suspected double charge: two\nsubmissions where the second reports `true` are one payment, whereas two both\nreporting `false` are two. It says nothing about how far the payment has got —\nread `status` for that.\n";
2355
2917
  readonly example: false;
2356
2918
  };
2919
+ readonly quote_id: {
2920
+ readonly type: "string";
2921
+ readonly description: "The winning quote's ID. Present when `status` is `completed` — a payment cannot settle\nwithout an award — and absent on a `pending` response, where no quote has been selected\nyet. Same value and meaning as on GET /v1/payments/{paymentId}/status.\n";
2922
+ readonly example: "0x9a3b...e8d4";
2923
+ };
2924
+ readonly fulfillment_quote: {
2925
+ readonly type: "object";
2926
+ readonly description: "The settler-signed FulfillmentQuote for the winning quote, returned verbatim as an\nopaque signed document — the PREIMAGE of the `quote_hash` committed on-chain. Same\nvalue, semantics and canonicalization caveats as on\nGET /v1/payments/{paymentId}/status; see that field for how to verify it.\n\nPresent when `status` is `completed`. It may be absent even then, if the stored quote\nis unreadable: the award is reported through `quote_id` regardless, so a present\n`quote_id` with no `fulfillment_quote` means \"verification preimage unavailable\" and\nnever \"no quote was awarded\". A consumer that requires the preimage should fall back to\nthe status endpoint rather than treat the payment as unverified.\n";
2927
+ readonly 'x-go-type': "json.RawMessage";
2928
+ };
2357
2929
  readonly fulfillment_confirmation: {
2358
2930
  readonly $ref: "#/components/schemas/FulfillmentConfirmation";
2359
2931
  };
@@ -2368,7 +2940,7 @@ declare const $GetPaymentStatusResponse: {
2368
2940
  readonly payment_id: {
2369
2941
  readonly type: "string";
2370
2942
  readonly description: "The payment ID you're checking status for.\n";
2371
- readonly example: "550e8400-e29b-41d4-a716-446655440000";
2943
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
2372
2944
  };
2373
2945
  readonly status: {
2374
2946
  readonly type: "string";
@@ -2380,12 +2952,34 @@ declare const $GetPaymentStatusResponse: {
2380
2952
  readonly format: "date-time";
2381
2953
  readonly description: "When the status was last updated";
2382
2954
  };
2955
+ readonly quote_id: {
2956
+ readonly type: "string";
2957
+ readonly description: "The winning quote's ID. Present once a quote has been awarded for this payment;\nabsent while the payment is still collecting or awarding. Cross-references the\n`quote_id` returned by GET /v1/payments/quote-requests/{quoteRequestId}.\n";
2958
+ readonly example: "0x9a3b...e8d4";
2959
+ };
2960
+ readonly fulfillment_quote: {
2961
+ readonly type: "object";
2962
+ readonly description: "The settler-signed FulfillmentQuote for the winning quote, returned verbatim as an\nopaque signed document (structurally the canonical FulfillmentQuote/v1 declaration at\nhttps://schemas.atum.xyz/declarations/FulfillmentQuote/v1). Present once a quote has\nbeen awarded — including after the payment completes and `fulfillment_confirmation` is\npopulated, since that is precisely when a consumer verifies.\n\nThis is the PREIMAGE of the `quote_hash` committed on-chain in the escrow deposit and\nreserve witnesses. On-chain we commit only the hash, so a quote-selector consumer\nrecomputes quote_hash over these bytes and compares it against the on-chain commitment\nto confirm the payment settled against the quote it selected (\"trust but verify\"), and\nverifies the settler signature over the same bytes.\n\nquote_hash is canonicalization-based (URDNA2015), so it is stable across JSON\nkey-order/whitespace normalization and across JSON string-escaping differences. The\nreturned bytes are hash-equivalent to, but not necessarily byte-identical with, what\nthe settler emitted (quotes are stored as JSONB, which normalizes on write). The\ngateway still never re-serializes the quote through a typed struct (that renormalizes\ntimestamp values and WOULD change quote_hash), so the Go binding exposes it as a raw\nJSON passthrough.\n";
2963
+ readonly 'x-go-type': "json.RawMessage";
2964
+ };
2383
2965
  readonly fulfillment_confirmation: {
2384
2966
  readonly $ref: "#/components/schemas/FulfillmentConfirmation";
2385
2967
  };
2386
2968
  readonly error: {
2387
2969
  readonly $ref: "#/components/schemas/PaymentError";
2388
2970
  };
2971
+ readonly requested_count: {
2972
+ readonly type: "integer";
2973
+ readonly description: "How many settler agents this payment's auction was broadcast to. Absent means\nunknown, never zero.\n";
2974
+ readonly example: 8;
2975
+ };
2976
+ readonly decline_summary: {
2977
+ readonly type: "array";
2978
+ readonly description: "Why the payment drew few or no quotes. Read from the same settler reports as the\nquote-request endpoints, keyed by this payment, so a payment that failed on an expired\nquote deadline can say WHY nobody funded it instead of only that nobody did.\n\nEvery declining agent is counted exactly once under its most recent reason. Empty means\nno agent declined against this payment, absent means the breakdown could not be read. A\npayment awarded out of a quote-request batch was bid on at quote time, so its declines\nare keyed to that batch and are read from the batch's status endpoint rather than here.\nAs on the quote-request endpoints, the free-form decline detail is never relayed.\n";
2979
+ readonly items: {
2980
+ readonly $ref: "#/components/schemas/DeclineSummaryEntry";
2981
+ };
2982
+ };
2389
2983
  };
2390
2984
  };
2391
2985
  declare const $PaymentError: {
@@ -2395,7 +2989,7 @@ declare const $PaymentError: {
2395
2989
  readonly properties: {
2396
2990
  readonly code: {
2397
2991
  readonly type: "string";
2398
- readonly description: "Public error category in SCREAMING_SNAKE_CASE.\nCommon codes:\n- `SETTLEMENT_FAILED`: The settlement could not be completed\n- `NO_ROUTE_AVAILABLE`: No settlement route was available\n- `INTERNAL_ERROR`: An unexpected error occurred\n";
2992
+ readonly description: "Public error category in SCREAMING_SNAKE_CASE.\nCommon codes:\n- `SETTLEMENT_FAILED`: The settlement could not be completed\n- `NO_QUOTES_RECEIVED`: No quotes arrived within the auction window\n- `INTERNAL_ERROR`: An unexpected error occurred\n";
2399
2993
  readonly example: "SETTLEMENT_FAILED";
2400
2994
  };
2401
2995
  readonly message: {
@@ -2406,7 +3000,7 @@ declare const $PaymentError: {
2406
3000
  readonly domain: {
2407
3001
  readonly type: "string";
2408
3002
  readonly description: "Service domain where the error originated.\n";
2409
- readonly enum: readonly ["PAYMENT_GATEWAY", "SOLVER_GATEWAY", "SETTLER_AGENT", "WALLET_ORCHESTRATION", "VERIFICATION_SERVICE", "BLOCKCHAIN", "EXTERNAL_SERVICE"];
3003
+ readonly enum: readonly ["PAYMENT_GATEWAY", "SETTLER_GATEWAY", "SETTLER_AGENT", "WALLET_ORCHESTRATION", "VERIFICATION_SERVICE", "BLOCKCHAIN", "EXTERNAL_SERVICE"];
2410
3004
  readonly example: "PAYMENT_GATEWAY";
2411
3005
  };
2412
3006
  readonly blockchain_context: {
@@ -2473,7 +3067,7 @@ declare const $PreparePaymentRequest: {
2473
3067
  readonly source_account: {
2474
3068
  readonly type: "string";
2475
3069
  readonly description: "Wallet address that will send the payment";
2476
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
3070
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2477
3071
  };
2478
3072
  readonly destination_asset: {
2479
3073
  readonly type: "string";
@@ -2588,7 +3182,7 @@ declare const $PaymentSummary: {
2588
3182
  };
2589
3183
  readonly source_account: {
2590
3184
  readonly type: "string";
2591
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
3185
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2592
3186
  };
2593
3187
  readonly dest_asset: {
2594
3188
  readonly type: "string";
@@ -2700,7 +3294,7 @@ declare const $TimelineStep: {
2700
3294
  };
2701
3295
  declare const $ErrorResponse: {
2702
3296
  readonly type: "object";
2703
- readonly description: "Safe, outward-facing error. Derived from an internal error through the shared error catalog. The public code identifies the category and the message is a curated, safe description.";
3297
+ readonly description: "Safe, outward-facing error. Derived from an internal error through the shared error catalog. The public code identifies the category and the message is a curated, safe description.\n\nA panic is caught by shared middleware that responds `{\"error\": \"Internal server error occurred\"}` instead, so a 500 is not guaranteed to carry this shape.";
2704
3298
  readonly required: readonly ["code", "message"];
2705
3299
  readonly properties: {
2706
3300
  readonly code: {
@@ -2720,6 +3314,11 @@ declare const $ErrorResponse: {
2720
3314
  readonly description: "Correlation id to quote to support to locate the internal error record.";
2721
3315
  readonly example: "req_123456789";
2722
3316
  };
3317
+ readonly payment_id: {
3318
+ readonly type: "string";
3319
+ readonly description: "The payment this error was raised against. Absent when the error is not about a specific payment.";
3320
+ readonly example: "0xc7108e200d11580e7e75185991084b42a535af588ba8267cd0d1e7df089e5c9c";
3321
+ };
2723
3322
  readonly docs_url: {
2724
3323
  readonly type: "string";
2725
3324
  readonly format: "uri";
@@ -2730,6 +3329,11 @@ declare const $ErrorResponse: {
2730
3329
  readonly description: "Originating service domain.";
2731
3330
  readonly example: "PAYMENT_GATEWAY";
2732
3331
  };
3332
+ readonly retry_classification: {
3333
+ readonly type: "string";
3334
+ readonly description: "What the caller should do next. Absent means the condition has not been classified, which is not the same as safe to retry.\nRe-sending the same `request_id` is an idempotent replay and always safe. This value is about submitting a new one, which starts a new operation. See https://docs.atum.xyz/errors for the value set.";
3335
+ readonly example: "RECONCILE_THEN_DECIDE";
3336
+ };
2733
3337
  };
2734
3338
  };
2735
3339
  declare const $CreateQuoteRequest: {
@@ -2753,8 +3357,9 @@ declare const $CreateQuoteRequest: {
2753
3357
  };
2754
3358
  readonly destination: {
2755
3359
  readonly type: "array";
2756
- readonly description: "Array of destination assets for the settlement agent to choose from (at least one required).";
3360
+ readonly description: "Array of destination assets for the settlement agent to choose from (at least one required, at most 16).\nThe ceiling bounds the fan-out one request can buy: every consumer iterates this list.\n";
2757
3361
  readonly minItems: 1;
3362
+ readonly maxItems: 16;
2758
3363
  readonly items: {
2759
3364
  readonly $ref: "#/components/schemas/OwnedAsset";
2760
3365
  };
@@ -2794,7 +3399,7 @@ declare const $CreateQuoteRequest: {
2794
3399
  readonly quote_selector: {
2795
3400
  readonly type: "string";
2796
3401
  readonly description: "Wallet address or public key of a trusted service that auto-selects the best rate.\nLeave empty to use the default selector.\n";
2797
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
3402
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2798
3403
  };
2799
3404
  readonly fulfillment_verifier: {
2800
3405
  readonly type: "object";
@@ -2809,7 +3414,7 @@ declare const $CreateQuoteRequest: {
2809
3414
  readonly endpoint: {
2810
3415
  readonly type: "string";
2811
3416
  readonly format: "uri";
2812
- readonly description: "Origin of the fulfillment verifier service, with no path — the caller\nappends the verifier's own API paths. The gateway's `/defaults` response\nsupplies the default fulfillment verifier for each chain.\n";
3417
+ readonly description: "Origin of the fulfillment verifier service, with no path — the caller\nappends the verifier's own API paths. The gateway's `/v1/defaults` response\nsupplies the default fulfillment verifier for each chain.\n";
2813
3418
  readonly example: "https://veri-fill.production-testnet.atum.xyz";
2814
3419
  };
2815
3420
  };
@@ -2817,7 +3422,7 @@ declare const $CreateQuoteRequest: {
2817
3422
  readonly escrow_contract_address: {
2818
3423
  readonly type: "string";
2819
3424
  readonly description: "Optional escrow contract address. Leave empty to use the default.";
2820
- readonly example: "0x742d35Cc6634C0532925a3b844Bc9e7595f4136";
3425
+ readonly example: "0x742D35cC6634c0532925a3b844Bc9e7595F41360";
2821
3426
  };
2822
3427
  readonly fulfillment_proxy: {
2823
3428
  readonly type: "string";
@@ -2838,7 +3443,7 @@ declare const $CreateQuoteRequest: {
2838
3443
  readonly type: "string";
2839
3444
  readonly pattern: "^did:[a-z][a-z0-9]*:[a-zA-Z0-9._:%-]+$";
2840
3445
  };
2841
- readonly example: readonly ["did:pkh:eip155:1:0x742d35Cc6634C0532925a3b844Bc9e7595f4136"];
3446
+ readonly example: readonly ["did:pkh:eip155:1:0x742D35cC6634c0532925a3b844Bc9e7595F41360"];
2842
3447
  };
2843
3448
  readonly blacklist: {
2844
3449
  readonly type: "array";
@@ -2850,7 +3455,7 @@ declare const $CreateQuoteRequest: {
2850
3455
  readonly type: "string";
2851
3456
  readonly pattern: "^did:[a-z][a-z0-9]*:[a-zA-Z0-9._:%-]+$";
2852
3457
  };
2853
- readonly example: readonly ["did:pkh:eip155:1:0x892BB2e4F6b14a2B5b82Ba8d33E5925D42D4432F"];
3458
+ readonly example: readonly ["did:pkh:eip155:1:0x892bb2E4F6b14a2B5b82bA8D33e5925d42d4432f"];
2854
3459
  };
2855
3460
  };
2856
3461
  };
@@ -2875,37 +3480,37 @@ declare const $CreateQuoteRequest: {
2875
3480
  };
2876
3481
  declare const $DataIntegrityProof: {
2877
3482
  readonly type: "object";
2878
- readonly description: "W3C Data Integrity proof conforming to the Data Integrity 1.0 specification.";
3483
+ readonly description: "W3C Data Integrity proof conforming to the Data Integrity 1.0 specification. Which of jws or proofValue is required depends on the cryptosuite named in type, and that pairing is checked where the proof is verified rather than by this schema, so a document can satisfy the schema and still be refused at verification.";
2879
3484
  readonly required: readonly ["type", "created", "verificationMethod", "proofPurpose"];
2880
3485
  readonly properties: {
2881
3486
  readonly type: {
2882
3487
  readonly type: "string";
2883
- readonly description: "Proof type identifier (e.g. EcdsaSecp256k1RecoverySignature2020).";
3488
+ readonly description: "Proof type identifier. ECDSA-secp256k1 (recoverable, EVM-compatible) for did:pkh:eip155:* signers; Ed25519 for did:pkh:solana:* signers.";
2884
3489
  readonly example: "EcdsaSecp256k1RecoverySignature2020";
2885
3490
  };
2886
3491
  readonly created: {
2887
3492
  readonly type: "string";
2888
3493
  readonly format: "date-time";
2889
- readonly description: "ISO 8601 timestamp when the proof was created.";
3494
+ readonly description: "ISO 8601 timestamp when the proof was created. Canonicalize the value exactly as it appears in the raw JSON: parsing it into a date-time and re-serializing can change the spelling (Z versus +00:00), and a different spelling canonicalizes to different bytes, so the signature no longer verifies.";
2890
3495
  readonly example: "2026-04-29T12:00:00Z";
2891
3496
  };
2892
3497
  readonly verificationMethod: {
2893
3498
  readonly type: "string";
2894
- readonly description: "DID URL identifying the verification method.";
3499
+ readonly description: "DID URL identifying the verification method, e.g., 'did:pkh:eip155:1:0x...#blockchainAccountId' for ECDSA or 'did:pkh:solana:<chain>:<addr>#SolanaMethod2021' for Ed25519.";
2895
3500
  readonly example: "did:pkh:eip155:42161:0xabc...#blockchainAccountId";
2896
3501
  };
2897
3502
  readonly proofPurpose: {
2898
3503
  readonly type: "string";
2899
- readonly description: "Purpose of the proof (e.g. assertionMethod, authentication).";
3504
+ readonly description: "Purpose of the proof (e.g., assertionMethod, authentication).";
2900
3505
  readonly example: "assertionMethod";
2901
3506
  };
2902
3507
  readonly jws: {
2903
3508
  readonly type: "string";
2904
- readonly description: "Detached JWS signature (header..signature format for ES256K-R).";
3509
+ readonly description: "Detached JWS signature in <base64url(header)>..<base64url(sig)> form, header {alg:ES256K-R, b64:false, crit:[b64]}. Required at runtime for EcdsaSecp256k1RecoverySignature2020.";
2905
3510
  };
2906
3511
  readonly proofValue: {
2907
3512
  readonly type: "string";
2908
- readonly description: "Alternative to jws: base-encoded proof value.";
3513
+ readonly description: "Multibase-encoded raw signature bytes. Required at runtime for Ed25519Signature2020; mutually exclusive with jws in practice.";
2909
3514
  };
2910
3515
  };
2911
3516
  };
@@ -2944,7 +3549,7 @@ declare const $AwardedQuote: {
2944
3549
  readonly type: "string";
2945
3550
  readonly nullable: true;
2946
3551
  readonly description: "payment_id if this quote was awarded; null otherwise. Under MVP single-award, at most\none quote per batch carries a non-null value.\n";
2947
- readonly example: "py_9876fedc-ba98-7654-3210-fedcba987654";
3552
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
2948
3553
  };
2949
3554
  };
2950
3555
  };
@@ -2959,14 +3564,14 @@ declare const $AwardedPayment: {
2959
3564
  };
2960
3565
  readonly payment_id: {
2961
3566
  readonly type: "string";
2962
- readonly example: "py_9876fedc-ba98-7654-3210-fedcba987654";
3567
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
2963
3568
  };
2964
3569
  };
2965
3570
  };
2966
3571
  declare const $QuoteRequestResponse: {
2967
3572
  readonly type: "object";
2968
- readonly description: "Synchronous response to POST /v1/payments/quote-requests. Self-contained — the corridor\nfields are echoed at the response root so a drop-recovery client can build the award call\nwithout retaining the original request body.\n";
2969
- readonly required: readonly ["quote_request_id", "status"];
3573
+ readonly description: "Synchronous response to POST /v1/payments/quote-requests. Self-contained — the corridor\nfields are echoed at the response root so a drop-recovery client can build the award call\nwithout retaining the original request body.\n\nThe corridor echoed here describes the batch you actually receive. On an idempotent\nreplay that is the ORIGINAL batch's corridor and window, which may differ from what you\njust sent in the ways a retry is allowed to differ (the deadlines, and address casing).\n";
3574
+ readonly required: readonly ["quote_request_id", "status", "idempotent_replay"];
2970
3575
  readonly properties: {
2971
3576
  readonly quote_request_id: {
2972
3577
  readonly type: "string";
@@ -2979,6 +3584,10 @@ declare const $QuoteRequestResponse: {
2979
3584
  readonly description: "Collection-phase outcome of the create call:\n- `ready` — collection complete; `quotes` populated. If no settler bid, this is still\n `ready` with an empty `quotes` array (a successful \"no quotes available\" result —\n distinct from `expired`, which only applies to collected quotes that later lapse).\n- `collecting` — the sync wait cap fired before the quote deadline; poll the status endpoint for quotes.\nThe `awarded` and `expired` lifecycle states are observed only via the status endpoint, not here.\n";
2980
3585
  readonly example: "ready";
2981
3586
  };
3587
+ readonly idempotent_replay: {
3588
+ readonly type: "boolean";
3589
+ readonly description: "Whether this response describes a batch that already existed, rather than one opened\nby this request. `true` means the `request_id` had been used before and you are being\nhanded the ORIGINAL batch — no second batch was opened and no second broadcast went\nout to settlement agents.\n\n**Re-attempting a quote-request.** Re-submit the same request and you get the same\nbatch back. You may re-send the original bytes unchanged: `quote_deadline` bounds the\ncollection window and is short, so it will usually have expired by the time you\nretry, and an expired deadline on a re-submission is not an error — the request is\nresolved onto the batch that already exists rather than used to open one.\nRe-signing with fresh deadlines is equally fine and returns the same batch.\n\nThe window is NOT extended either way: it belongs to the batch, and `quote_deadline`\nin this response is the batch's own. Read `status` to see whether collection is\nstill running.\n\nWhat you must not change under one `request_id` is the corridor's economics —\naccounts, assets, or amounts — which are rejected with 409\nIDEMPOTENCY_TERMS_MISMATCH rather than resolved onto the first batch. A genuinely\ndifferent corridor needs a new `request_id`.\n\nPresent on every response, `false` for a newly opened batch. A response without the\nfield is from a gateway predating it, not a newly opened batch.\n";
3590
+ };
2982
3591
  readonly source: {
2983
3592
  readonly $ref: "#/components/schemas/OwnedAsset";
2984
3593
  };
@@ -3013,12 +3622,24 @@ declare const $QuoteRequestResponse: {
3013
3622
  readonly $ref: "#/components/schemas/Quote";
3014
3623
  };
3015
3624
  };
3625
+ readonly requested_count: {
3626
+ readonly type: "integer";
3627
+ readonly description: "How many agents the request was broadcast to, so silence is distinguishable from a\ndecline without a second call. Same meaning and same absence rule as on the status\nendpoint: absent means unknown, never zero.\n";
3628
+ readonly example: 8;
3629
+ };
3630
+ readonly decline_summary: {
3631
+ readonly type: "array";
3632
+ readonly description: "Why the request drew few or no quotes, carried here so that a `ready` response with an\nempty `quotes` array explains itself rather than requiring a follow-up read.\n\nSame counting rules as the status endpoint: every declining agent counted exactly once\nunder its most recent reason, empty when nobody declined, absent when the detail could not\nbe read. Provisional while `status` is `collecting`, because agents are still responding.\n";
3633
+ readonly items: {
3634
+ readonly $ref: "#/components/schemas/DeclineSummaryEntry";
3635
+ };
3636
+ };
3016
3637
  };
3017
3638
  };
3018
3639
  declare const $QuoteRequestAccepted: {
3019
3640
  readonly type: "object";
3020
- readonly description: "Asynchronous (202) response to POST /v1/payments/quote-requests. Returns the batch handle\nplus the echoed corridor; quotes are retrieved via the status endpoint.\n";
3021
- readonly required: readonly ["quote_request_id", "status"];
3641
+ readonly description: "Asynchronous (202) response to POST /v1/payments/quote-requests. Returns the batch handle\nplus the echoed corridor; quotes are retrieved via the status endpoint.\n\nThe corridor echoed here describes the batch you actually receive. On an idempotent\nreplay that is the ORIGINAL batch's corridor and window, which may differ from what you\njust sent in the ways a retry is allowed to differ (the deadlines, and address casing).\n";
3642
+ readonly required: readonly ["quote_request_id", "status", "idempotent_replay"];
3022
3643
  readonly properties: {
3023
3644
  readonly quote_request_id: {
3024
3645
  readonly type: "string";
@@ -3027,9 +3648,13 @@ declare const $QuoteRequestAccepted: {
3027
3648
  readonly status: {
3028
3649
  readonly type: "string";
3029
3650
  readonly enum: readonly ["collecting"];
3030
- readonly description: "Always `collecting` — collection is in progress server-side.";
3651
+ readonly description: "Always `collecting` — a constant on this response, not a report of the batch's state.\nOn an idempotent replay the batch's window may already have closed; read\nGET /v1/payments/quote-requests/{quoteRequestId} for its actual state.\n";
3031
3652
  readonly example: "collecting";
3032
3653
  };
3654
+ readonly idempotent_replay: {
3655
+ readonly type: "boolean";
3656
+ readonly description: "Whether this response describes a batch that already existed, rather than one opened\nby this request. `true` means the `request_id` had been used before and you are being\nhanded the ORIGINAL batch — no second batch was opened and no second broadcast went\nout to settlement agents.\n\nThe idempotency contract is the same as on the synchronous (200) response: a\nre-submission may carry expired deadlines and is resolved onto the existing batch\nrather than rejected, the collection window is the batch's own and is not extended,\nand differing economics are rejected with 409 IDEMPOTENCY_TERMS_MISMATCH rather than\ncollapsed onto the first batch.\n\nPresent on every response, `false` for a newly opened batch. A response without the\nfield is from a gateway predating it, not a newly opened batch.\n";
3657
+ };
3033
3658
  readonly source: {
3034
3659
  readonly $ref: "#/components/schemas/OwnedAsset";
3035
3660
  };
@@ -3088,8 +3713,46 @@ declare const $QuoteRequestStatusResponse: {
3088
3713
  readonly $ref: "#/components/schemas/AwardedPayment";
3089
3714
  };
3090
3715
  };
3716
+ readonly requested_count: {
3717
+ readonly type: "integer";
3718
+ readonly description: "How many agents the request was broadcast to. The only auction count that is not\nderivable from the rest of this response:\n\n- quoted = `quotes` length\n- declined = sum of `decline_summary[].count`\n- participated = quoted + declined\n- silent = `requested_count` - participated\n\nSilence and a decline are different signals, which is why the denominator is surfaced\nrather than left implicit.\n\nABSENT when the number is unknown, which happens when the broadcast count was never\nrecorded or when the auction detail could not be read. Absence means unknown, never zero,\nso `silent` is derivable only when this field is present.\n";
3719
+ readonly example: 8;
3720
+ };
3721
+ readonly decline_summary: {
3722
+ readonly type: "array";
3723
+ readonly description: "Why the request drew few or no quotes, so a caller can tell \"nobody can fund this right\nnow\" from \"my request was malformed\".\n\nEXHAUSTIVE over agents: every agent that declined is counted exactly once, under its most\nrecent reason, so the counts sum to the number of agents that declined. An agent that\ndeclined more than once with different reasons is counted once, not once per reason.\n\nEmpty means nobody declined. ABSENT means the auction detail could not be read, so the\nbreakdown is unknown. While `status` is `collecting` it is provisional, because agents are\nstill responding.\n\nThe free-form decline detail is never relayed, because that detail carries an agent's\nbalances and would let a caller map inventory by polling cheap quote-requests across\ncorridors.\n";
3724
+ readonly items: {
3725
+ readonly $ref: "#/components/schemas/DeclineSummaryEntry";
3726
+ };
3727
+ };
3091
3728
  };
3092
3729
  };
3730
+ declare const $DeclineSummaryEntry: {
3731
+ readonly type: "object";
3732
+ readonly required: readonly ["reason", "count"];
3733
+ readonly properties: {
3734
+ readonly reason: {
3735
+ readonly $ref: "#/components/schemas/DeclineReason";
3736
+ };
3737
+ readonly count: {
3738
+ readonly type: "integer";
3739
+ readonly description: "Agents whose most recent decline reason was this one. Counts agents, never rows, and an\nagent appears under one reason only.\n";
3740
+ readonly example: 4;
3741
+ };
3742
+ readonly retry_classification: {
3743
+ readonly type: "string";
3744
+ readonly description: "What would have to change for a settler giving this reason to bid, drawn from the same\nclosed set as the `retry_classification` on an error response so a caller reads one\nvocabulary.\n\nIt describes the decline only. The authoritative instruction for the payment is the\n`retry_classification` on its own error response: a payment can fail for a reason no\nsettler named, and it can succeed while some settlers declined.\n\nOptional, and a pattern-constrained string for the same reason `DeclineReason` is.\n";
3745
+ readonly pattern: "^[A-Z][A-Z0-9_]*$";
3746
+ readonly example: "RETRY_AFTER_DELAY";
3747
+ };
3748
+ };
3749
+ };
3750
+ declare const $DeclineReason: {
3751
+ readonly type: "string";
3752
+ readonly description: "A settler's reason for not bidding, projected from its internal reason code through\nthe shared decline catalog (`apis/decline/v1/catalog.json`), which is the single\nsource of truth for the reason set. Several internal codes may map to one public\nreason.\n\nDeliberately a pattern-constrained string rather than a closed enum. The set grows\nwhenever a settler gains a cause worth naming, and a consumer whose generated client\ncloses the set rejects the whole response on a value it has not seen. Treat an\nunrecognised value as `OTHER`.\n\n`OTHER` covers a reason whose detail is settler-authored free text, and any reason\nthis gateway does not recognise. Both are counted so the summary stays exhaustive,\nwithout relaying text we neither author nor validate.\n";
3753
+ readonly pattern: "^[A-Z][A-Z0-9_]*$";
3754
+ readonly example: "INSUFFICIENT_LIQUIDITY";
3755
+ };
3093
3756
  declare const $AwardRequest: {
3094
3757
  readonly type: "object";
3095
3758
  readonly description: "Request body for POST /v1/payments/awards. Carries the two originator-signed artifacts:\n`sender_auth` (Permit2 deposit authorization) and a fully-formed `bid_award` declaration.\nThe awarded quote is derived server-side from bid_award.fulfillment_quote_json — no\nexplicit quote_id on the wire.\n";
@@ -3152,7 +3815,7 @@ declare const $AwardResponse: {
3152
3815
  readonly properties: {
3153
3816
  readonly payment_id: {
3154
3817
  readonly type: "string";
3155
- readonly example: "py_9876fedc-ba98-7654-3210-fedcba987654";
3818
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
3156
3819
  };
3157
3820
  readonly status: {
3158
3821
  readonly type: "string";
@@ -3172,7 +3835,7 @@ declare const $AwardAccepted: {
3172
3835
  readonly properties: {
3173
3836
  readonly payment_id: {
3174
3837
  readonly type: "string";
3175
- readonly example: "py_9876fedc-ba98-7654-3210-fedcba987654";
3838
+ readonly example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f";
3176
3839
  };
3177
3840
  readonly status: {
3178
3841
  readonly type: "string";
@@ -3182,6 +3845,125 @@ declare const $AwardAccepted: {
3182
3845
  };
3183
3846
  };
3184
3847
  };
3848
+ declare const $ChainDefaults: {
3849
+ readonly type: "object";
3850
+ readonly description: "The addresses for one chain. Optional fields appear only where they apply to that\nchain; an absent optional field is not an error.\n";
3851
+ readonly required: readonly ["chain_id", "quote_selector", "escrow_contract", "fulfillment_proxy", "fulfillment_verifier"];
3852
+ readonly properties: {
3853
+ readonly chain_id: {
3854
+ readonly type: "string";
3855
+ readonly description: "CAIP-2 identifier of the chain these defaults describe, normalised to lower case.";
3856
+ readonly example: "eip155:84532";
3857
+ };
3858
+ readonly quote_selector: {
3859
+ readonly type: "string";
3860
+ readonly description: "The account named as the reserver in the deposit authorization. Sign against this exact value; a deposit reserved by anyone else is rejected.";
3861
+ readonly example: "0xd0f080E23F95571D26eEb1FAD24a5F3d66835195";
3862
+ };
3863
+ readonly escrow_contract: {
3864
+ readonly type: "string";
3865
+ readonly description: "The escrow the deposit is made into, and the spender of the token approval. Empty when the chain is not fully configured.";
3866
+ readonly example: "0xa61a0C025943Aa79B73D8D07E3aDbEe1873738b4";
3867
+ };
3868
+ readonly fulfillment_proxy: {
3869
+ readonly type: "string";
3870
+ readonly description: "The contract that pays the receiver. Read this from the DESTINATION chain's defaults, not the source chain's. Empty when the chain is not fully configured.";
3871
+ readonly example: "0x09A5a0d6955E5394A661Cd9E7007076fa63B4158";
3872
+ };
3873
+ readonly fulfillment_verifier: {
3874
+ readonly type: "object";
3875
+ readonly description: "The service that attests settlement, and the account it signs with.";
3876
+ readonly required: readonly ["account", "endpoint"];
3877
+ readonly properties: {
3878
+ readonly account: {
3879
+ readonly type: "string";
3880
+ readonly description: "The account named as the releaser in the deposit authorization. Sign against this exact value.";
3881
+ readonly example: "0x27050EE47befC43F4dF7807a7AA8073039e5fa89";
3882
+ };
3883
+ readonly endpoint: {
3884
+ readonly type: "string";
3885
+ readonly format: "uri";
3886
+ readonly description: "Base URL of the fulfillment verifier serving this chain.";
3887
+ readonly example: "https://veri-fill.example.com";
3888
+ };
3889
+ };
3890
+ };
3891
+ readonly permit2_contract: {
3892
+ readonly type: "string";
3893
+ readonly minLength: 1;
3894
+ readonly description: "The Permit2 this chain's escrow verifies against, sent only when it is not the canonical deployment. When absent, use the canonical Permit2 address for the chain. EVM and Tron only.";
3895
+ readonly example: "0x000000000022D473030F116dDEE9F6B43aC78BA3";
3896
+ };
3897
+ readonly deposit_witness_version: {
3898
+ readonly type: "integer";
3899
+ readonly minimum: 3;
3900
+ readonly description: "Which deposit witness this chain's escrow expects. `4` and above select the four-member witness, `3` the two-member one; absent means four. EVM and Tron only - on Solana this is carried by `svm_signature_domain_version`.";
3901
+ readonly example: 4;
3902
+ };
3903
+ readonly tokens: {
3904
+ readonly type: "array";
3905
+ readonly description: "Tokens this chain's escrow accepts for deposit. Absent when the gateway has no listing for the chain, which does not mean no token is accepted.";
3906
+ readonly items: {
3907
+ readonly type: "object";
3908
+ readonly required: readonly ["symbol", "address", "decimals"];
3909
+ readonly properties: {
3910
+ readonly symbol: {
3911
+ readonly type: "string";
3912
+ readonly example: "USDC";
3913
+ };
3914
+ readonly address: {
3915
+ readonly type: "string";
3916
+ readonly description: "Token contract address, in the chain's native address format.";
3917
+ readonly example: "0x036cbd53842c5426634e7929541ec2318f3dcf7e";
3918
+ };
3919
+ readonly decimals: {
3920
+ readonly type: "integer";
3921
+ readonly description: "Decimal places, for converting a human amount to base units.";
3922
+ readonly example: 6;
3923
+ };
3924
+ };
3925
+ };
3926
+ };
3927
+ readonly svm_signature_cluster_id: {
3928
+ readonly type: "string";
3929
+ readonly description: "Solana only. The cluster the escrow's signing domain is bound to, needed to build the deposit hash. Absent for EVM and Tron.";
3930
+ readonly example: "devnet";
3931
+ };
3932
+ readonly svm_signature_domain_version: {
3933
+ readonly type: "integer";
3934
+ readonly minimum: 1;
3935
+ readonly description: "Solana only. Version of the escrow's signing domain. Absent for EVM and Tron.";
3936
+ readonly example: 2;
3937
+ };
3938
+ };
3939
+ };
3940
+ declare const $GetDefaultsResult: {
3941
+ readonly description: "Either one chain's defaults or every chain keyed by CAIP-2 chain id, depending on whether `chain_id` was supplied. A top-level `chain_id` identifies the first.";
3942
+ readonly oneOf: readonly [{
3943
+ readonly $ref: "#/components/schemas/ChainDefaults";
3944
+ }, {
3945
+ readonly $ref: "#/components/schemas/ChainDefaultsByChain";
3946
+ }];
3947
+ };
3948
+ declare const $ChainDefaultsByChain: {
3949
+ readonly type: "object";
3950
+ readonly description: "Defaults for every chain the gateway serves, keyed by CAIP-2 chain id. Each key repeats the `chain_id` of the value it maps to.";
3951
+ readonly additionalProperties: {
3952
+ readonly $ref: "#/components/schemas/ChainDefaults";
3953
+ };
3954
+ readonly example: {
3955
+ readonly 'eip155:84532': {
3956
+ readonly chain_id: "eip155:84532";
3957
+ readonly quote_selector: "0xd0f080E23F95571D26eEb1FAD24a5F3d66835195";
3958
+ readonly escrow_contract: "0xa61a0C025943Aa79B73D8D07E3aDbEe1873738b4";
3959
+ readonly fulfillment_proxy: "0x09A5a0d6955E5394A661Cd9E7007076fa63B4158";
3960
+ readonly fulfillment_verifier: {
3961
+ readonly account: "0x27050EE47befC43F4dF7807a7AA8073039e5fa89";
3962
+ readonly endpoint: "https://veri-fill.example.com";
3963
+ };
3964
+ };
3965
+ };
3966
+ };
3185
3967
 
3186
3968
  type ApiResult<TData = any> = {
3187
3969
  readonly body: TData;
@@ -3200,6 +3982,20 @@ declare class ApiError extends Error {
3200
3982
  constructor(request: ApiRequestOptions, response: ApiResult, message: string);
3201
3983
  }
3202
3984
 
3985
+ /**
3986
+ * The gateway accepted the request but did not answer inside the client's budget.
3987
+ *
3988
+ * Not an {@link ApiError}: there is no response, status or error body, so
3989
+ * `isApiError` and `getErrorResponse` stay false for it. It carries no verdict on
3990
+ * the request either, since a timed-out submit may still have been accepted.
3991
+ */
3992
+ declare class GatewayTimeoutError extends Error {
3993
+ readonly baseUrl: string;
3994
+ readonly timeoutMs: number;
3995
+ constructor(baseUrl: string, timeoutMs: number);
3996
+ }
3997
+ /** Type guard for {@link GatewayTimeoutError}, the unresponsive-gateway case. */
3998
+ declare function isGatewayTimeoutError(err: unknown): err is GatewayTimeoutError;
3203
3999
  /**
3204
4000
  * Type guard for the SDK's transport-level error.
3205
4001
  *
@@ -3213,10 +4009,12 @@ declare function isApiError(err: unknown): err is ApiError;
3213
4009
  * body is not the public {@link ErrorResponse} shape.
3214
4010
  *
3215
4011
  * The gateway serializes errors as an {@link ErrorResponse}
3216
- * (`{ code, message, request_id?, docs_url?, domain? }`), but the generated
3217
- * client widens the parsed body to `unknown`. This helper narrows it back so
3218
- * consumers can branch on `code` and quote `request_id` to support. It only
3219
- * ever exposes this outward-facing shape — never any internal error taxonomy.
4012
+ * (`{ code, message, request_id?, payment_id?, docs_url?, domain? }`), but the
4013
+ * generated client widens the parsed body to `unknown`. This helper narrows it
4014
+ * back so consumers can branch on `code`, quote `request_id` to support, and read
4015
+ * `payment_id` to reconcile the payment a failed settlement was attempted under.
4016
+ * It only ever exposes this outward-facing shape — never any internal error
4017
+ * taxonomy.
3220
4018
  *
3221
4019
  * @example
3222
4020
  * try {
@@ -3232,6 +4030,275 @@ declare function isApiError(err: unknown): err is ApiError;
3232
4030
  */
3233
4031
  declare function getErrorResponse(err: unknown): ErrorResponse | undefined;
3234
4032
 
4033
+ /**
4034
+ * Polling a submitted payment until it reaches a state it cannot leave.
4035
+ *
4036
+ * The gateway holds a submission for its own synchronous window before answering, so a payment that
4037
+ * is still pending by the time the caller sees it settled more slowly than that window. A submission usually
4038
+ * comes back pending, so following one is the ordinary path rather than an edge case.
4039
+ *
4040
+ * The wait budget is a client-side convenience, not a deadline with any meaning to the network.
4041
+ * Nothing is affected by giving up: the payment continues, and re-submitting the same request id or
4042
+ * asking for the payment's status picks up wherever it got to. In particular a settlement that
4043
+ * stalls will never become terminal on its own, so no budget can promise a terminal answer — giving
4044
+ * up while still pending is a normal ending, not a failure.
4045
+ */
4046
+ /**
4047
+ * True for the states a payment can never leave.
4048
+ *
4049
+ * An unrecognized or absent status is deliberately NOT terminal: a status this client does not
4050
+ * know is treated as still in flight, so a gateway that adds one does not make a caller report a
4051
+ * payment as finished on the strength of a value it cannot interpret.
4052
+ */
4053
+ declare function isTerminalStatus(status: string | undefined): boolean;
4054
+ /**
4055
+ * Default budget for {@link waitForTerminalStatus}, in milliseconds.
4056
+ *
4057
+ * The gateway has already held the submission for its own window by the time a caller sees a
4058
+ * pending payment, so anything still pending is settling slowly. A minute past that covers the
4059
+ * common case without holding a request handler open indefinitely.
4060
+ */
4061
+ declare const DEFAULT_WAIT_BUDGET_MS: number;
4062
+ /** Gap between status checks. Short enough to feel responsive, long enough not to hammer. */
4063
+ declare const DEFAULT_POLL_INTERVAL_MS = 2000;
4064
+ /**
4065
+ * All this module needs of a status response: something that reports a status. Deciding when to
4066
+ * stop is the only thing it does, so it constrains the shape rather than defining it, and callers
4067
+ * get their own richer type back unchanged.
4068
+ */
4069
+ interface StatusSnapshot {
4070
+ status?: string;
4071
+ }
4072
+ /** Outcome of a wait. */
4073
+ interface WaitOutcome<T extends StatusSnapshot> {
4074
+ /** The last status successfully read, or undefined if no check ever succeeded. */
4075
+ snapshot?: T;
4076
+ /**
4077
+ * Whether the wait ended without the payment reaching a terminal state — because the budget ran
4078
+ * out, or because {@link WaitParams.signal} was aborted. False only when `snapshot` holds a
4079
+ * terminal status, so it is safe to branch on: a payment is finished when this is false.
4080
+ */
4081
+ timedOut: boolean;
4082
+ /** Whether {@link WaitParams.signal} ended the wait. Implies `timedOut`. */
4083
+ aborted: boolean;
4084
+ /** How many status checks failed outright (network or gateway errors). */
4085
+ errorCount: number;
4086
+ }
4087
+ /** Everything the wait needs, with time and I/O injected so it can be tested without a clock. */
4088
+ interface WaitParams<T extends StatusSnapshot> {
4089
+ /** Read the payment's current status. */
4090
+ fetchStatus: () => Promise<T>;
4091
+ /**
4092
+ * How long to keep checking, in **milliseconds**; defaults to {@link DEFAULT_WAIT_BUDGET_MS}.
4093
+ * A budget of zero or less checks nothing.
4094
+ */
4095
+ budgetMs?: number;
4096
+ /** Gap between checks; defaults to {@link DEFAULT_POLL_INTERVAL_MS}. */
4097
+ intervalMs?: number;
4098
+ /** Monotonic-enough clock, in milliseconds; defaults to `Date.now`. */
4099
+ now?: () => number;
4100
+ /**
4101
+ * Test seam for the delay. Replacing it opts out of abort-aware sleeping, so a wait then ends
4102
+ * at the next check rather than immediately.
4103
+ */
4104
+ sleep?: (ms: number) => Promise<void>;
4105
+ /** Called for each failed check, so a caller can report it without this module owning output. */
4106
+ onError?: (error: unknown) => void;
4107
+ /**
4108
+ * Ends the wait early, for a caller that must stop on shutdown or when its request is cancelled.
4109
+ * The outcome reports `aborted`, and carries the last status read.
4110
+ */
4111
+ signal?: AbortSignal;
4112
+ }
4113
+ /**
4114
+ * Poll a payment's status until it is terminal, the budget runs out, or `signal` is aborted.
4115
+ *
4116
+ * A failed check does not end the wait: a blip while a payment is mid-settlement is exactly when
4117
+ * giving up is least useful, so failures are counted, reported through `onError`, and polling
4118
+ * continues until the budget is spent.
4119
+ *
4120
+ * @param params - the status reader, the budget, and injectable time
4121
+ * @returns the last status read, whether the wait ended without a terminal status, whether
4122
+ * `signal` ended it, and how many checks failed
4123
+ */
4124
+ declare function waitForTerminalStatus<T extends StatusSnapshot>(params: WaitParams<T>): Promise<WaitOutcome<T>>;
4125
+
4126
+ /**
4127
+ * Result of an {@link ensureSourceApproval} call.
4128
+ */
4129
+ interface EnsureApprovalResult {
4130
+ /** The existing allowance already covered the requirement; no transaction was sent. */
4131
+ alreadySufficient: boolean;
4132
+ /** The approval transaction hash, when one was sent. */
4133
+ txHash?: string;
4134
+ /**
4135
+ * Set only when the token refused to overwrite a non-zero allowance and it had to be reset to
4136
+ * zero first: the hash of that reset. Its absence means one transaction was sent, not two.
4137
+ */
4138
+ resetTxHash?: string;
4139
+ }
4140
+ /** What TronWeb reports about a broadcast transaction. Empty until it is confirmed. */
4141
+ interface TronTransactionInfo {
4142
+ receipt?: {
4143
+ result?: string;
4144
+ };
4145
+ }
4146
+ /**
4147
+ * The slice of a TronWeb instance this package needs.
4148
+ *
4149
+ * Declared structurally rather than imported from `tronweb` on purpose: the package then
4150
+ * type-checks and builds with tronweb absent, and consumers that never pay from Tron do not
4151
+ * carry an 11 MB dependency they cannot reach. The caller constructs the instance and passes
4152
+ * it in, exactly as the EVM path takes a caller-constructed ethers signer.
4153
+ */
4154
+ interface TronWebLike {
4155
+ /**
4156
+ * The ABI-and-address form, which builds the handle locally. The `contract().at(address)`
4157
+ * form fetches the ABI from the node instead: a round trip per use, and an interface that
4158
+ * depends on what the chain happens to report for that address.
4159
+ *
4160
+ * Returns `unknown` on purpose. TronWeb types this as a contract whose methods are produced
4161
+ * dynamically from the ABI, so pinning it to {@link TronTokenContract} here would stop a real
4162
+ * TronWeb instance assigning to this interface at all and force every caller to write a cast.
4163
+ * The cast belongs in one place — next to the ABI we passed, which is what makes it true.
4164
+ */
4165
+ contract(abi: unknown, address: string): unknown;
4166
+ trx: {
4167
+ getTransactionInfo(txId: string): Promise<TronTransactionInfo>;
4168
+ };
4169
+ /**
4170
+ * The account this instance signs as. Read to check it against `owner` before broadcasting,
4171
+ * since an approval only ever applies to the account that sends it.
4172
+ *
4173
+ * Optional, and `false` is TronWeb's own "not set": both mean the instance cannot say which
4174
+ * account it would use, and neither is treated as a mismatch.
4175
+ */
4176
+ defaultAddress?: {
4177
+ base58?: string | false;
4178
+ };
4179
+ }
4180
+ /** How long to wait for a broadcast approval to confirm before giving up, on either chain. */
4181
+ interface ConfirmationOptions {
4182
+ /**
4183
+ * Default 60_000. On timeout the approval is reported as unconfirmed rather than failed: it
4184
+ * was broadcast and may still confirm, so the caller is told to check it before sending
4185
+ * another one.
4186
+ */
4187
+ timeoutMs?: number;
4188
+ /** Tron only: how often to poll for the receipt. Default 1_500, under Tron's ~3s block time. */
4189
+ pollIntervalMs?: number;
4190
+ /** Tron only: default 100_000_000 SUN. Tron charges the caller for contract execution. */
4191
+ feeLimit?: number;
4192
+ }
4193
+ /**
4194
+ * Inputs to {@link ensureSourceApproval} and {@link needsSourceApproval}.
4195
+ *
4196
+ * `signer` and `tronWeb` are both optional here because which one is required is decided by
4197
+ * `network`, a runtime string that no type can constrain. Supplying the wrong one for the
4198
+ * chain fails with a message naming the one that was needed.
4199
+ */
4200
+ interface ApprovalParams {
4201
+ /** CAIP-2 source chain id, e.g. `eip155:8453` or `tron:mainnet`. */
4202
+ network: string;
4203
+ /** Source token address. */
4204
+ token: string;
4205
+ /** The payer's account. */
4206
+ owner: string;
4207
+ /**
4208
+ * The contract to approve. Defaults to the canonical Permit2 for the chain: the EVM
4209
+ * deployment on `eip155:*`, and the pinned per-network address on `tron:*`.
4210
+ */
4211
+ spender?: string;
4212
+ /**
4213
+ * The minimum allowance this charge needs. Answers "is what I already have enough?".
4214
+ * When omitted, only an unlimited approval counts as sufficient, so a smaller leftover
4215
+ * allowance cannot be mistaken for enough and revert a larger later charge on-chain.
4216
+ */
4217
+ requiredAllowance?: bigint;
4218
+ /**
4219
+ * How much to approve when an approval IS sent. Defaults to unlimited, so later charges on
4220
+ * the same token need no further transaction.
4221
+ *
4222
+ * On its own, a bounded amount is treated as its own requirement: an allowance still holding
4223
+ * the full bound is left alone rather than re-approved. That is the right answer for a one-off
4224
+ * approval, where nothing else in the call says what a later charge would need.
4225
+ *
4226
+ * Across repeated payments, PAIR IT WITH `requiredAllowance`. Permit2 decrements the allowance
4227
+ * on every payment, so a bound measured against itself stops being sufficient the moment the
4228
+ * first charge lands, and every later call sends another approval. `requiredAllowance` states
4229
+ * what the NEXT charge needs, which is the question a partly spent bound can still answer yes
4230
+ * to.
4231
+ *
4232
+ * Trade-off: a bounded approval limits what the escrow can ever move, but it is consumed as it
4233
+ * is spent and eventually has to be granted again, whichever way it is used.
4234
+ */
4235
+ approvalAmount?: bigint;
4236
+ /** An ethers signer connected to the source chain. Required for `eip155:*`. */
4237
+ signer?: Signer;
4238
+ /** A TronWeb instance configured for the source chain. Required for `tron:*`. */
4239
+ tronWeb?: TronWebLike;
4240
+ /** Broadcast and confirmation tuning. Applies to both chains. */
4241
+ confirmation?: ConfirmationOptions;
4242
+ /**
4243
+ * Called with each transaction hash the moment it is broadcast, before the wait for it to
4244
+ * confirm. Without this a caller has nothing to show for a transaction that is already
4245
+ * spending their gas — and nothing to look up if the wait times out.
4246
+ *
4247
+ * `purpose` distinguishes the approval itself from the zero-reset some tokens demand first,
4248
+ * so two hashes in one call read as one deliberate sequence rather than a double spend.
4249
+ */
4250
+ onSubmitted?: (txHash: string, purpose: "approval" | "reset") => void;
4251
+ }
4252
+
4253
+ /** Whether an error came from a broadcast transaction that was never seen to confirm. */
4254
+ declare function isUnconfirmed(error: unknown): boolean;
4255
+
4256
+ /**
4257
+ * Payer-side Permit2 approval for the source token an escrow deposit moves.
4258
+ *
4259
+ * On EVM and Tron the escrow moves the source token through Permit2, so the payer must have
4260
+ * approved Permit2 on that token BEFORE paying. Without it the payment is built, signed and
4261
+ * accepted by the gateway, and then the deposit reverts on-chain at settlement — a late and
4262
+ * misleading failure. Solana authorizes the transfer inside the signed deposit itself, so
4263
+ * there is nothing to approve there.
4264
+ *
4265
+ * Worth arranging before the payment is signed: a deposit that reverts is a terminal
4266
+ * settlement failure, and a terminal failure is bound to the request identifier that produced
4267
+ * it, so re-attempting then needs a NEW identifier. Getting the allowance right up front keeps
4268
+ * the identifier usable.
4269
+ *
4270
+ * This package reads chain state and broadcasts a transaction, which is why it is separate
4271
+ * from the sender-auth SDK next door: that one is pure, offline and byte-parity-tested against
4272
+ * Go. The caller supplies the connected signer, so this package never chooses an RPC endpoint.
4273
+ */
4274
+
4275
+ /**
4276
+ * Whether a payment on these terms would need an approval transaction first.
4277
+ *
4278
+ * Read-only: it spends no gas and sends nothing, so it is safe to call on every payment as a
4279
+ * preflight. Returns false on Solana, which needs no approval at all.
4280
+ *
4281
+ * @remarks
4282
+ * Unlike a try-and-see, this reports the answer instead of acting on it — use it to tell a
4283
+ * payer what is about to happen, or to check whether a wallet is ready before asking for a
4284
+ * signature.
4285
+ */
4286
+ declare function needsSourceApproval(params: ApprovalParams): Promise<boolean>;
4287
+ /**
4288
+ * Ensure the payer has approved Permit2 to move the source token, so the escrow deposit does
4289
+ * not revert at settlement. Reads the current allowance and sends an approval only if it falls
4290
+ * short; the approval it sends is unlimited unless `approvalAmount` bounds it.
4291
+ *
4292
+ * Applies to EVM (`params.signer`) and Tron (`params.tronWeb`). On Solana it reports
4293
+ * `alreadySufficient` without touching the chain.
4294
+ *
4295
+ * @remarks
4296
+ * Not concurrency-safe: two overlapping calls for the same `(owner, token, spender)` may both
4297
+ * read a short allowance and both send an approval. They target the same value, so this only
4298
+ * wastes gas; serialize calls per token if that matters.
4299
+ */
4300
+ declare function ensureSourceApproval(params: ApprovalParams): Promise<EnsureApprovalResult>;
4301
+
3235
4302
  /**
3236
4303
  * EVM Permit2 PermitWitnessTransferFrom deposit prehash + EIP-712 digest.
3237
4304
  *
@@ -3483,11 +4550,16 @@ declare const MAX_VALID_SLOT: number;
3483
4550
  *
3484
4551
  * encodeU64LE, generateSolanaNonce (generateNonce), and MAX_VALID_SLOT are
3485
4552
  * imported from the shared @atum-labs/solana-escrow-encoding package and
3486
- * re-exported here to preserve the public API. The V1 hashSolanaDeposit,
3487
- * base58ToBytes, payment-id generation, and prehash creation stay local: the
3488
- * package has no non-domain-separated V1 hash, and the local base58/hex helpers
3489
- * carry the exact error messages the client tests assert. The V3 deposit hash
3490
- * already delegates to the package (hashSolanaDepositV3 → computeDepositHash).
4553
+ * re-exported here to preserve the public API. base58ToBytes, payment-id
4554
+ * generation, and prehash creation stay local, because the local base58/hex
4555
+ * helpers carry the exact error messages the client tests assert.
4556
+ *
4557
+ * NO DEPOSIT HASH IS COMPUTED HERE ANY MORE. hashSolanaDeposit computed the
4558
+ * pre-domain-separation layout above and now throws (see its doc comment), and
4559
+ * hashSolanaDepositV3 was deleted as an un-exported third copy of the package's
4560
+ * own call. Build a deposit through the shared sender_auth adapter, which selects
4561
+ * the preimage from the escrow domain version; reach for computeDepositHash /
4562
+ * computeDepositHashV2 from the package if you need the raw primitive.
3491
4563
  *
3492
4564
  * The canonical reference is the @atum-labs/solana-escrow-encoding package in
3493
4565
  * this repo (contracts/svm/escrow-encoding), the TypeScript sibling of the
@@ -3496,7 +4568,10 @@ declare const MAX_VALID_SLOT: number;
3496
4568
 
3497
4569
  /** Replay horizon in seconds — deposit deadline must be within this window of issuedAt. */
3498
4570
  declare const REPLAY_HORIZON_SECS = 128;
3499
- /** Total number of replay-protection buckets. */
4571
+ /**
4572
+ * Widest bucket ID the replay nonce layout carries. Generated nonces draw from the smaller
4573
+ * bounded set the escrow-encoding package defines, which keeps the replay_bucket PDAs reusable.
4574
+ */
3500
4575
  declare const TOTAL_BUCKETS = 131072;
3501
4576
  /** Exact byte size of a serialized deposit message (7 + 32*5 + 8*3). */
3502
4577
  declare const DEPOSIT_MESSAGE_SIZE = 199;
@@ -3578,22 +4653,34 @@ interface SolanaDepositPrehash {
3578
4653
  */
3579
4654
  declare function createSolanaDepositPrehash(paymentId: string, params: SolanaDepositParams): SolanaDepositPrehash;
3580
4655
  /**
3581
- * Computes the keccak256 deposit hash from a prehash structure.
4656
+ * REMOVED — this function computed the PRE-DOMAIN-SEPARATION deposit hash, which no deployed
4657
+ * escrow program accepts. It now throws rather than returning one.
3582
4658
  *
3583
- * Formula: keccak256("deposit" || payment_id[32] || depositor[32] || mint[32] ||
3584
- * amount[8,LE] || reserver[32] || releaser[32] ||
3585
- * nonce[8,LE] || issued_at[8,LE] || deadline[8,LE])
4659
+ * The layout it used, kept here as a record of the historical scheme:
3586
4660
  *
3587
- * Total input: 199 bytes (7 + 32*5 + 8*3)
4661
+ * keccak256("deposit" || payment_id[32] || depositor[32] || mint[32] ||
4662
+ * amount[8,LE] || reserver[32] || releaser[32] ||
4663
+ * nonce[8,LE] || issued_at[8,LE] || deadline[8,LE]) = 199 bytes
3588
4664
  *
3589
- * TODO: Replace with computeDepositHash from @atum-labs/solana-escrow-encoding once public.
3590
- * The bindings version uses EscrowDepositParams with Pubkey objects instead of base58 strings,
3591
- * so this function will need to convert from prehash strings to the bindings' types.
4665
+ * Every current program prefixes the preimage with its domain —
4666
+ * `"escrow" || signature_domain_version || cluster_id[32] || program_id[32]` — and from domain
4667
+ * version 4 also binds `destination_hash`. So the 199-byte hash is not merely out of date, it is
4668
+ * unverifiable everywhere: `escrow.rs`'s `require!(deposit_hash == message, InvalidData)` rejects
4669
+ * it on every cluster.
3592
4670
  *
3593
- * @param prehash The structured prehash from createSolanaDepositPrehash()
3594
- * @returns 0x-prefixed hex string (32 bytes)
4671
+ * WHY IT THROWS INSTEAD OF BEING DELETED OR LEFT ALONE. It was exported from this package's
4672
+ * entry point, so removing the symbol outright is a hard break for any consumer that imports it,
4673
+ * while leaving it was worse: it returned a well-formed 32-byte hash that fails on-chain with
4674
+ * `InvalidData` and no indication why. Throwing turns an undiagnosable on-chain rejection into an
4675
+ * error at the call site that names the replacement.
4676
+ *
4677
+ * Build deposit authorizations through the shared sender_auth adapter
4678
+ * (`getChainAdapter(chainId).buildAuthMessage(...)`), which selects the correct preimage from the
4679
+ * domain version it is given and is the same implementation the facilitator verifies against.
4680
+ *
4681
+ * @throws Always.
3595
4682
  */
3596
- declare function hashSolanaDeposit(prehash: SolanaDepositPrehash): string;
4683
+ declare function hashSolanaDeposit(_prehash: SolanaDepositPrehash): never;
3597
4684
  /**
3598
4685
  * Generates a valid nonce for Solana replay protection (upper 32 bits: random
3599
4686
  * bucket, lower 8 bits: random slot 0..MAX_VALID_SLOT). Delegates to the shared
@@ -3621,6 +4708,11 @@ declare const PAYMENT_REQUEST_VERSION = "1.0";
3621
4708
  */
3622
4709
  declare function signPaymentRequest(request: PaymentRequest, signer: SenderSigner): Promise<PaymentRequest>;
3623
4710
  type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
4711
+ /**
4712
+ * Request-layer configuration plus this package's network timeouts. Omit the
4713
+ * timeouts for the defaults; see {@link RequestTimeouts}.
4714
+ */
4715
+ type PaymentGatewayClientConfig = Partial<OpenAPIConfig> & RequestTimeouts;
3624
4716
  declare const defaultGateway: string;
3625
4717
  /**
3626
4718
  * Default request-layer configuration, with `BASE` set to this package's default
@@ -3660,11 +4752,14 @@ declare const DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS = 10;
3660
4752
  * Extended PaymentGatewayClient with convenience methods
3661
4753
  */
3662
4754
  declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3663
- private baseUrl;
3664
- constructor(config?: Partial<OpenAPIConfig>, HttpRequest?: HttpRequestConstructor);
4755
+ constructor(config?: PaymentGatewayClientConfig, HttpRequest?: HttpRequestConstructor);
3665
4756
  /**
3666
4757
  * Fetches chain defaults from the payment gateway.
3667
4758
  *
4759
+ * Goes through the generated typed client, so the request shares the payment calls'
4760
+ * transport: one base URL, one timeout policy, and `/v1/defaults` is described by the
4761
+ * OpenAPI contract rather than assembled by hand here.
4762
+ *
3668
4763
  * @param chainId The CAIP-2 chain identifier (e.g., "eip155:42161")
3669
4764
  * @returns The chain defaults including escrow, quote selector, and fulfillment verifier
3670
4765
  */
@@ -3672,7 +4767,7 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3672
4767
  /**
3673
4768
  * Prepares a payment request with defaults, ready for signing.
3674
4769
  *
3675
- * By default this resolves the corridor addresses from the gateway `/defaults`
4770
+ * By default this resolves the corridor addresses from the gateway `/v1/defaults`
3676
4771
  * endpoint. It reaches the gateway only for what the caller has NOT already
3677
4772
  * supplied via `resolvedDefaults`: supply `resolvedDefaults.source` to skip the
3678
4773
  * source-chain fetch and `resolvedDefaults.destination` to skip the destination
@@ -3748,7 +4843,7 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3748
4843
  solanaClockReader?: SolanaClusterUnixTimeReader;
3749
4844
  /**
3750
4845
  * Pre-resolved corridor addresses. Omit to fetch them from the gateway
3751
- * `/defaults`; supply to build offline. Each side is resolved independently —
4846
+ * `/v1/defaults`; supply to build offline. Each side is resolved independently —
3752
4847
  * a field left out is still fetched. The destination contributes only its
3753
4848
  * `fulfillmentProxy` (its escrow/roles are source-side concepts, unused here).
3754
4849
  */
@@ -3782,7 +4877,7 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3782
4877
  * defaults and populates the SAME contract fields (`escrow_contract_address`,
3783
4878
  * `quote_selector`, `fulfillment_verifier`, `fulfillment_proxy`). These are not
3784
4879
  * optional in practice: the gateway requires `fulfillment_verifier` to build the
3785
- * QuoteRequested event it broadcasts to settlers, so the quote-request body
4880
+ * request event it broadcasts to settlers, so the quote-request body
3786
4881
  * must carry the identical contract fields the payment flow does. The ONLY
3787
4882
  * field this drops relative to `preparePaymentRequest` is `sender_auth`, which
3788
4883
  * is supplied at award time (quote-time is unauthenticated — no signing, no
@@ -3798,8 +4893,12 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3798
4893
  destinationAccount: string;
3799
4894
  destinationAsset: string;
3800
4895
  maxSourceAmount?: string;
3801
- requestId?: string;
3802
- requestIdPrefix?: string;
4896
+ /**
4897
+ * The request id. Reuse the SAME value to retry: the gateway returns the original batch
4898
+ * (same `quote_request_id`) instead of opening a second one, and answers `409`
4899
+ * IDEMPOTENCY_TERMS_MISMATCH if you reuse it for a different corridor.
4900
+ */
4901
+ requestId: string;
3803
4902
  settlerRequirements?: {
3804
4903
  whitelist?: string[];
3805
4904
  blacklist?: string[];
@@ -3809,4 +4908,4 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3809
4908
  }): Promise<CreateQuoteRequest>;
3810
4909
  }
3811
4910
 
3812
- export { $AuthorizationResult, $AwardAccepted, $AwardRequest, $AwardResponse, $AwardedPayment, $AwardedQuote, $BidAward, $CreateQuoteRequest, $DataIntegrityProof, $ErrorResponse, $FulfillmentConfirmation, $GetPaymentStatusResponse, type $OpenApiTs, $OwnedAsset, $PaymentBlockchainContext, $PaymentError, $PaymentRequest, $PaymentResponse, $PaymentSummary, $PaymentTimelineResponse, $PreparePaymentRequest, $PreparePaymentResponse, $Quote, $QuoteRequestAccepted, $QuoteRequestResponse, $QuoteRequestStatusResponse, $ResolvePaymentResponse, $SenderAuth, $SenderAuthMessageScheme, $SignedMessage, $TimelineError, $TimelineStep, $VerifiableCredential, $VerifiableCredentialAuth, ApiError, type ApiRequestOptions, type ApiResult, type AuthorizationResult, AuthorizationsService, type AuthorizePaymentData, type AuthorizePaymentResponse, type AwardAccepted, type AwardQuoteData, type AwardQuoteResponse, type AwardRequest, type AwardResponse, type AwardedPayment, type AwardedQuote, type BidAward, CancelError, CancelablePromise, type ChainDefaults, type CreateQuoteRequest, type CreateQuoteRequestData, type CreateQuoteRequestResponse, DEFAULT_FULFILLMENT_DEADLINE_SECONDS, DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS, DEFAULT_QUOTE_DEADLINE_SECONDS, DEPOSIT_MESSAGE_SIZE, type DataIntegrityProof, type ErrorResponse, type FulfillmentConfirmation, type GetPaymentStatusData, type GetPaymentStatusResponse, type GetPaymentStatusResponse2, type GetPaymentTimelineData, type GetPaymentTimelineResponse, type GetQuoteRequestStatusData, type GetQuoteRequestStatusResponse, type HealthCheckResponse, HealthService, Interceptors, MAX_VALID_SLOT, type OnCancel, OpenAPI, type OpenAPIConfig, type OwnedAsset, PAYMENT_REQUEST_VERSION, PERMIT2_CONTRACT_ADDRESS, type PaymentBlockchainContext, type PaymentError, PaymentGatewayClient, type PaymentRequest, type PaymentResponse, type PaymentSummary, type PaymentTimelineResponse, PaymentsService, type PermitWitnessTransferFromParams, type PreparePaymentData, type PreparePaymentRequest, type PreparePaymentResponse, type PreparePaymentResponse2, type Quote, type QuoteRequestAccepted, type QuoteRequestResponse, type QuoteRequestStatusResponse, QuoteRequestsService, REPLAY_HORIZON_SECS, type ResolvePaymentData, type ResolvePaymentResponse, type ResolvePaymentResponse2, type SenderAuth, type SenderAuthMessageScheme, type SenderSignature, type SenderSigner, type SenderSignerOptions, type SignedMessage, type SolanaClusterUnixTimeReader, type SolanaDepositParams, type SolanaDepositPrehash, type SubmitPaymentData, type SubmitPaymentResponse, TOTAL_BUCKETS, type TimelineError, type TimelineStep, type TurnkeyConfig, TurnkeySenderSigner, type TvmPermitWitnessTransferFromParams, type VerifiableCredential, type VerifiableCredentialAuth, base58ToBytes, base58ToHex, bytesToHex, createPermitWitnessTransferFromPrehash, createSenderSigner, createSolanaDepositPrehash, createTvmPermitWitnessTransferFromPrehash, defaultGateway, type domain, encodeU64LE, type error_code, generateSolanaNonce, generateSolanaPaymentId, getErrorResponse, hashPermitWitnessTransferFrom, hashRequestId, hashSolanaDeposit, hashTvmPermitWitnessTransferFrom, hexToBytes, isApiError, maskChainId, normalizeAddress, resolveTurnkeyAddresses, signPaymentRequest, type status, type status2, type status3, type status4, type status5, type status6, type status7, type status8, type status9 };
4911
+ export { $AuthorizationResult, $AwardAccepted, $AwardRequest, $AwardResponse, $AwardedPayment, $AwardedQuote, $BidAward, $ChainDefaults, $ChainDefaultsByChain, $CreateQuoteRequest, $DataIntegrityProof, $DeclineReason, $DeclineSummaryEntry, $ErrorResponse, $FulfillmentConfirmation, $GetDefaultsResult, $GetPaymentStatusResponse, type $OpenApiTs, $OwnedAsset, $PaymentBlockchainContext, $PaymentError, $PaymentRequest, $PaymentResponse, $PaymentSummary, $PaymentTimelineResponse, $PreparePaymentRequest, $PreparePaymentResponse, $Quote, $QuoteRequestAccepted, $QuoteRequestResponse, $QuoteRequestStatusResponse, $ResolvePaymentResponse, $SenderAuth, $SenderAuthMessageScheme, $SignedMessage, $TimelineError, $TimelineStep, $VerifiableCredential, $VerifiableCredentialAuth, ApiError, type ApiRequestOptions, type ApiResult, type ApprovalParams, type AuthorizationResult, AuthorizationsService, type AuthorizePaymentData, type AuthorizePaymentResponse, type AwardAccepted, type AwardQuoteData, type AwardQuoteResponse, type AwardRequest, type AwardResponse, type AwardedPayment, type AwardedQuote, type BidAward, CancelError, CancelablePromise, type ChainDefaults, type ChainDefaultsByChain, ChainDefaultsService, type ChainDefaults$1 as ChainDefaultsWire, type ConfirmationOptions, type CreateQuoteRequest, type CreateQuoteRequestData, type CreateQuoteRequestResponse, DEFAULT_FULFILLMENT_DEADLINE_SECONDS, DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS, DEFAULT_POLL_INTERVAL_MS, DEFAULT_QUOTE_DEADLINE_SECONDS, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_SYNC_WAIT_TIMEOUT_MS, DEFAULT_WAIT_BUDGET_MS, DEPOSIT_MESSAGE_SIZE, type DataIntegrityProof, type DeclineReason, type DeclineSummaryEntry, type EnsureApprovalResult, type ErrorResponse, type FulfillmentConfirmation, GatewayTimeoutError, type GetDefaultsData, type GetDefaultsResponse, type GetDefaultsResult, type GetPaymentStatusData, type GetPaymentStatusResponse, type GetPaymentStatusResponse2, type GetPaymentTimelineData, type GetPaymentTimelineResponse, type GetQuoteRequestStatusData, type GetQuoteRequestStatusResponse, type HealthCheckResponse, HealthService, Interceptors, InvalidAccountError, type Reason as InvalidAccountReason, MAX_VALID_SLOT, type OnCancel, OpenAPI, type OpenAPIConfig, type OwnedAsset, PAYMENT_REQUEST_VERSION, PERMIT2_CONTRACT_ADDRESS, type ParsedAssetIdentifier, type PaymentBlockchainContext, type PaymentError, PaymentGatewayClient, type PaymentGatewayClientConfig, type PaymentRequest, type PaymentResponse, type PaymentSummary, type PaymentTimelineResponse, PaymentsService, type PermitWitnessTransferFromParams, type PreparePaymentData, type PreparePaymentRequest, type PreparePaymentResponse, type PreparePaymentResponse2, type Quote, type QuoteRequestAccepted, type QuoteRequestResponse, type QuoteRequestStatusResponse, QuoteRequestsService, REPLAY_HORIZON_SECS, type RequestTimeouts, type ResolvePaymentData, type ResolvePaymentResponse, type ResolvePaymentResponse2, type SenderAuth, type SenderAuthMessageScheme, type SenderSignature, type SenderSigner, type SenderSignerOptions, type SignedMessage, type SolanaClusterUnixTimeReader, type SolanaDepositParams, type SolanaDepositPrehash, type StatusSnapshot, type SubmitPaymentData, type SubmitPaymentResponse, TOTAL_BUCKETS, type TimelineError, type TimelineStep, type TronWebLike, type TurnkeyConfig, TurnkeySenderSigner, type TvmPermitWitnessTransferFromParams, type VerifiableCredential, type VerifiableCredentialAuth, type WaitOutcome, type WaitParams, assetChainId, base58ToBytes, base58ToHex, bytesToHex, createPermitWitnessTransferFromPrehash, createSenderSigner, createSolanaDepositPrehash, createTvmPermitWitnessTransferFromPrehash, defaultGateway, type domain, encodeU64LE, ensureSourceApproval, type error_code, generateSolanaNonce, generateSolanaPaymentId, getErrorResponse, hashPermitWitnessTransferFrom, hashRequestId, hashSolanaDeposit, hashTvmPermitWitnessTransferFrom, hexToBytes, isApiError, isGatewayTimeoutError, isTerminalStatus, isUnconfirmed, maskChainId, needsSourceApproval, normalizeAddress, parseAssetIdentifier, resolveTurnkeyAddresses, signPaymentRequest, type status, type status2, type status3, type status4, type status5, type status6, type status7, type status8, type status9, waitForTerminalStatus };