@atumlabs/payment-gateway-client 2.0.0 → 2.1.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
@@ -65,7 +65,6 @@ type OpenAPIConfig = {
65
65
  response: Interceptors<AxiosResponse>;
66
66
  };
67
67
  };
68
- declare const OpenAPI: OpenAPIConfig;
69
68
 
70
69
  declare abstract class BaseHttpRequest {
71
70
  readonly config: OpenAPIConfig;
@@ -203,7 +202,10 @@ type PaymentRequest = {
203
202
  */
204
203
  account: string;
205
204
  /**
206
- * The API endpoint URL where the verification service can be reached
205
+ * Origin of the fulfillment verifier service, with no path — the caller
206
+ * appends the verifier's own API paths. The gateway's `/defaults` response
207
+ * supplies the default fulfillment verifier for each chain.
208
+ *
207
209
  */
208
210
  endpoint: string;
209
211
  };
@@ -893,7 +895,10 @@ type CreateQuoteRequest = {
893
895
  */
894
896
  account: string;
895
897
  /**
896
- * The API endpoint URL where the verification service can be reached
898
+ * Origin of the fulfillment verifier service, with no path — the caller
899
+ * appends the verifier's own API paths. The gateway's `/defaults` response
900
+ * supplies the default fulfillment verifier for each chain.
901
+ *
897
902
  */
898
903
  endpoint: string;
899
904
  };
@@ -975,7 +980,7 @@ type Quote = {
975
980
  quote_id: string;
976
981
  /**
977
982
  * The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
978
- * declaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned
983
+ * declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
979
984
  * verbatim as an opaque signed document. A client recomputes quote_hash over the returned
980
985
  * bytes and verifies the settler signature, then re-embeds them into
981
986
  * bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
@@ -997,7 +1002,7 @@ type AwardedQuote = {
997
1002
  quote_id: string;
998
1003
  /**
999
1004
  * The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
1000
- * declaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned
1005
+ * declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
1001
1006
  * verbatim as an opaque signed document. A client recomputes quote_hash over the returned
1002
1007
  * bytes and verifies the settler signature, then re-embeds them into
1003
1008
  * bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
@@ -1996,8 +2001,8 @@ declare const $PaymentRequest: {
1996
2001
  readonly endpoint: {
1997
2002
  readonly type: "string";
1998
2003
  readonly format: "uri";
1999
- readonly description: "The API endpoint URL where the verification service can be reached";
2000
- readonly example: "https://verifier.atum.network/api/v1/verify";
2004
+ 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";
2005
+ readonly example: "https://veri-fill.production-testnet.atum.xyz";
2001
2006
  };
2002
2007
  };
2003
2008
  };
@@ -2705,8 +2710,8 @@ declare const $CreateQuoteRequest: {
2705
2710
  readonly endpoint: {
2706
2711
  readonly type: "string";
2707
2712
  readonly format: "uri";
2708
- readonly description: "The API endpoint URL where the verification service can be reached";
2709
- readonly example: "https://verifier.atum.network/api/v1/verify";
2713
+ 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";
2714
+ readonly example: "https://veri-fill.production-testnet.atum.xyz";
2710
2715
  };
2711
2716
  };
2712
2717
  };
@@ -2817,7 +2822,7 @@ declare const $Quote: {
2817
2822
  };
2818
2823
  readonly fulfillment_quote: {
2819
2824
  readonly type: "object";
2820
- readonly description: "The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1\ndeclaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned\nverbatim as an opaque signed document. A client recomputes quote_hash over the returned\nbytes and verifies the settler signature, then re-embeds them into\nbid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based\n(URDNA2015), so it is stable across JSON key-order/whitespace normalization. The\nreturned bytes are hash-equivalent to, but not necessarily byte-identical with, what the\nsettler emitted (quotes are stored as JSONB, which normalizes on write). The gateway\nstill never re-serializes the quote through a typed struct (that renormalizes timestamp\nvalues and WOULD change quote_hash), so the Go binding exposes it as a raw JSON passthrough.\n";
2825
+ readonly description: "The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1\ndeclaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned\nverbatim as an opaque signed document. A client recomputes quote_hash over the returned\nbytes and verifies the settler signature, then re-embeds them into\nbid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based\n(URDNA2015), so it is stable across JSON key-order/whitespace normalization. The\nreturned bytes are hash-equivalent to, but not necessarily byte-identical with, what the\nsettler emitted (quotes are stored as JSONB, which normalizes on write). The gateway\nstill never re-serializes the quote through a typed struct (that renormalizes timestamp\nvalues and WOULD change quote_hash), so the Go binding exposes it as a raw JSON passthrough.\n";
2821
2826
  readonly 'x-go-type': "json.RawMessage";
2822
2827
  };
2823
2828
  };
@@ -2833,7 +2838,7 @@ declare const $AwardedQuote: {
2833
2838
  };
2834
2839
  readonly fulfillment_quote: {
2835
2840
  readonly type: "object";
2836
- readonly description: "The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1\ndeclaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned\nverbatim as an opaque signed document. A client recomputes quote_hash over the returned\nbytes and verifies the settler signature, then re-embeds them into\nbid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based\n(URDNA2015), so it is stable across JSON key-order/whitespace normalization. The\nreturned bytes are hash-equivalent to, but not necessarily byte-identical with, what the\nsettler emitted (quotes are stored as JSONB, which normalizes on write). The gateway\nstill never re-serializes the quote through a typed struct (that renormalizes timestamp\nvalues and WOULD change quote_hash), so the Go binding exposes it as a raw JSON passthrough.\n";
2841
+ readonly description: "The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1\ndeclaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned\nverbatim as an opaque signed document. A client recomputes quote_hash over the returned\nbytes and verifies the settler signature, then re-embeds them into\nbid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based\n(URDNA2015), so it is stable across JSON key-order/whitespace normalization. The\nreturned bytes are hash-equivalent to, but not necessarily byte-identical with, what the\nsettler emitted (quotes are stored as JSONB, which normalizes on write). The gateway\nstill never re-serializes the quote through a typed struct (that renormalizes timestamp\nvalues and WOULD change quote_hash), so the Go binding exposes it as a raw JSON passthrough.\n";
2837
2842
  readonly 'x-go-type': "json.RawMessage";
2838
2843
  };
2839
2844
  readonly awarded_payment_id: {
@@ -3096,6 +3101,38 @@ declare class ApiError extends Error {
3096
3101
  constructor(request: ApiRequestOptions, response: ApiResult, message: string);
3097
3102
  }
3098
3103
 
3104
+ /**
3105
+ * Type guard for the SDK's transport-level error.
3106
+ *
3107
+ * Every non-2xx gateway response is thrown by the generated client as an
3108
+ * {@link ApiError}, which also carries the transport detail (`status`, `url`).
3109
+ */
3110
+ declare function isApiError(err: unknown): err is ApiError;
3111
+ /**
3112
+ * Return the typed, public-facing gateway error carried by a caught
3113
+ * {@link ApiError}, or `undefined` when the value is not an `ApiError` or its
3114
+ * body is not the public {@link ErrorResponse} shape.
3115
+ *
3116
+ * The gateway serializes errors as an {@link ErrorResponse}
3117
+ * (`{ code, message, request_id?, docs_url?, domain? }`), but the generated
3118
+ * client widens the parsed body to `unknown`. This helper narrows it back so
3119
+ * consumers can branch on `code` and quote `request_id` to support. It only
3120
+ * ever exposes this outward-facing shape — never any internal error taxonomy.
3121
+ *
3122
+ * @example
3123
+ * try {
3124
+ * await client.payments.submitPayment({ requestBody });
3125
+ * } catch (err) {
3126
+ * const gwError = getErrorResponse(err);
3127
+ * if (gwError) {
3128
+ * console.error(gwError.code, gwError.message, gwError.request_id);
3129
+ * } else {
3130
+ * throw err;
3131
+ * }
3132
+ * }
3133
+ */
3134
+ declare function getErrorResponse(err: unknown): ErrorResponse | undefined;
3135
+
3099
3136
  /**
3100
3137
  * EVM Permit2 PermitWitnessTransferFrom deposit prehash + EIP-712 digest.
3101
3138
  *
@@ -3486,6 +3523,21 @@ declare const PAYMENT_REQUEST_VERSION = "1.0";
3486
3523
  declare function signPaymentRequest(request: PaymentRequest, signer: SenderSigner): Promise<PaymentRequest>;
3487
3524
  type HttpRequestConstructor = new (config: OpenAPIConfig) => BaseHttpRequest;
3488
3525
  declare const defaultGateway: string;
3526
+ /**
3527
+ * Default request-layer configuration, with `BASE` set to this package's default
3528
+ * gateway ({@link defaultGateway}, production-testnet).
3529
+ *
3530
+ * The generated value mirrors the first `servers` entry of the OpenAPI contract,
3531
+ * which is mainnet. This package defaults to testnet instead, so a client created
3532
+ * without an explicit URL never targets a live-funds environment. The override
3533
+ * lives here rather than in `src/generated/`, which is reproduced from the
3534
+ * contract and stays in sync with it.
3535
+ *
3536
+ * Exported for callers that want the default configuration shape.
3537
+ * {@link PaymentGatewayClient} does not read it: the client resolves its own
3538
+ * `BASE` and passes it explicitly.
3539
+ */
3540
+ declare const OpenAPI: OpenAPIConfig;
3489
3541
  /**
3490
3542
  * Default quote-collection window for {@link PaymentGatewayClient.prepareQuoteRequest}
3491
3543
  * (`quote_deadline = now + this`, in seconds). Chosen as the largest value that still
@@ -3658,4 +3710,4 @@ declare class PaymentGatewayClient extends PaymentGatewayClient$1 {
3658
3710
  }): Promise<CreateQuoteRequest>;
3659
3711
  }
3660
3712
 
3661
- 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, hashPermitWitnessTransferFrom, hashRequestId, hashSolanaDeposit, hashTvmPermitWitnessTransferFrom, hexToBytes, maskChainId, normalizeAddress, resolveTurnkeyAddresses, signPaymentRequest, type status, type status2, type status3, type status4, type status5, type status6, type status7, type status8, type status9 };
3713
+ 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 };
package/dist/index.js CHANGED
@@ -1,3 +1,9 @@
1
+ /*
2
+ * Copyright (c) 2026 Atum Labs, Inc. All rights reserved.
3
+ * Proprietary and confidential.
4
+ * Access and use are governed by the LICENSE file distributed with this package.
5
+ * Do not remove, alter, or obscure this notice.
6
+ */
1
7
  "use strict";
2
8
  var __create = Object.create;
3
9
  var __defProp = Object.defineProperty;
@@ -4674,7 +4680,7 @@ __export(index_exports, {
4674
4680
  HealthService: () => HealthService,
4675
4681
  Interceptors: () => Interceptors,
4676
4682
  MAX_VALID_SLOT: () => import_solana_escrow_encoding.MAX_VALID_SLOT,
4677
- OpenAPI: () => OpenAPI,
4683
+ OpenAPI: () => OpenAPI2,
4678
4684
  PAYMENT_REQUEST_VERSION: () => PAYMENT_REQUEST_VERSION,
4679
4685
  PERMIT2_CONTRACT_ADDRESS: () => import_evm_escrow_encoding.PERMIT2_CONTRACT_ADDRESS,
4680
4686
  PaymentGatewayClient: () => PaymentGatewayClient2,
@@ -4694,11 +4700,13 @@ __export(index_exports, {
4694
4700
  encodeU64LE: () => import_solana_escrow_encoding.encodeU64LE,
4695
4701
  generateSolanaNonce: () => generateSolanaNonce,
4696
4702
  generateSolanaPaymentId: () => generateSolanaPaymentId,
4703
+ getErrorResponse: () => getErrorResponse,
4697
4704
  hashPermitWitnessTransferFrom: () => import_evm_escrow_encoding.hashPermitWitnessTransferFrom,
4698
4705
  hashRequestId: () => hashRequestId,
4699
4706
  hashSolanaDeposit: () => hashSolanaDeposit,
4700
4707
  hashTvmPermitWitnessTransferFrom: () => import_tvm_escrow_encoding.hashTvmPermitWitnessTransferFrom,
4701
4708
  hexToBytes: () => hexToBytes,
4709
+ isApiError: () => isApiError,
4702
4710
  maskChainId: () => import_tvm_escrow_encoding.maskChainId,
4703
4711
  normalizeAddress: () => import_tvm_escrow_encoding.normalizeAddress,
4704
4712
  resolveTurnkeyAddresses: () => resolveTurnkeyAddresses,
@@ -4722,7 +4730,7 @@ var Interceptors = class {
4722
4730
  }
4723
4731
  };
4724
4732
  var OpenAPI = {
4725
- BASE: "https://api.atum.network",
4733
+ BASE: "https://payment-gw.production-mainnet.atum.xyz",
4726
4734
  CREDENTIALS: "include",
4727
4735
  ENCODE_PATH: void 0,
4728
4736
  HEADERS: void 0,
@@ -4905,7 +4913,7 @@ var getUrl = (config, options) => {
4905
4913
  var getFormData = (options) => {
4906
4914
  if (options.formData) {
4907
4915
  const formData = new FormData();
4908
- const process = (key, value) => {
4916
+ const process2 = (key, value) => {
4909
4917
  if (isString(value) || isBlob(value)) {
4910
4918
  formData.append(key, value);
4911
4919
  } else {
@@ -4914,9 +4922,9 @@ var getFormData = (options) => {
4914
4922
  };
4915
4923
  Object.entries(options.formData).filter(([, value]) => value !== void 0 && value !== null).forEach(([key, value]) => {
4916
4924
  if (Array.isArray(value)) {
4917
- value.forEach((v) => process(key, v));
4925
+ value.forEach((v) => process2(key, v));
4918
4926
  } else {
4919
- process(key, value);
4927
+ process2(key, value);
4920
4928
  }
4921
4929
  });
4922
4930
  return formData;
@@ -5445,7 +5453,7 @@ var HealthService = class {
5445
5453
  var PaymentGatewayClient = class {
5446
5454
  constructor(config, HttpRequest = AxiosHttpRequest) {
5447
5455
  this.request = new HttpRequest({
5448
- BASE: config?.BASE ?? "https://api.atum.network",
5456
+ BASE: config?.BASE ?? "https://payment-gw.production-mainnet.atum.xyz",
5449
5457
  VERSION: config?.VERSION ?? "1.0.0",
5450
5458
  WITH_CREDENTIALS: config?.WITH_CREDENTIALS ?? false,
5451
5459
  CREDENTIALS: config?.CREDENTIALS ?? "include",
@@ -5830,8 +5838,11 @@ Leave empty to use the default verifier.
5830
5838
  endpoint: {
5831
5839
  type: "string",
5832
5840
  format: "uri",
5833
- description: "The API endpoint URL where the verification service can be reached",
5834
- example: "https://verifier.atum.network/api/v1/verify"
5841
+ description: `Origin of the fulfillment verifier service, with no path \u2014 the caller
5842
+ appends the verifier's own API paths. The gateway's \`/defaults\` response
5843
+ supplies the default fulfillment verifier for each chain.
5844
+ `,
5845
+ example: "https://veri-fill.production-testnet.atum.xyz"
5835
5846
  }
5836
5847
  }
5837
5848
  },
@@ -6699,8 +6710,11 @@ Leave empty to use the default selector.
6699
6710
  endpoint: {
6700
6711
  type: "string",
6701
6712
  format: "uri",
6702
- description: "The API endpoint URL where the verification service can be reached",
6703
- example: "https://verifier.atum.network/api/v1/verify"
6713
+ description: `Origin of the fulfillment verifier service, with no path \u2014 the caller
6714
+ appends the verifier's own API paths. The gateway's \`/defaults\` response
6715
+ supplies the default fulfillment verifier for each chain.
6716
+ `,
6717
+ example: "https://veri-fill.production-testnet.atum.xyz"
6704
6718
  }
6705
6719
  }
6706
6720
  },
@@ -6820,7 +6834,7 @@ bid_award.fulfillment_quote_json.
6820
6834
  fulfillment_quote: {
6821
6835
  type: "object",
6822
6836
  description: `The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
6823
- declaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned
6837
+ declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
6824
6838
  verbatim as an opaque signed document. A client recomputes quote_hash over the returned
6825
6839
  bytes and verifies the settler signature, then re-embeds them into
6826
6840
  bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
@@ -6846,7 +6860,7 @@ var $AwardedQuote = {
6846
6860
  fulfillment_quote: {
6847
6861
  type: "object",
6848
6862
  description: `The settler-signed FulfillmentQuote (structurally the canonical FulfillmentQuote/v1
6849
- declaration at https://schemas.atum.network/declarations/FulfillmentQuote/v1), returned
6863
+ declaration at https://schemas.atum.xyz/declarations/FulfillmentQuote/v1), returned
6850
6864
  verbatim as an opaque signed document. A client recomputes quote_hash over the returned
6851
6865
  bytes and verifies the settler signature, then re-embeds them into
6852
6866
  bid_award.fulfillment_quote_json at award. quote_hash is canonicalization-based
@@ -7160,6 +7174,21 @@ var $AwardAccepted = {
7160
7174
  }
7161
7175
  };
7162
7176
 
7177
+ // src/errors.ts
7178
+ function isApiError(err) {
7179
+ return err instanceof ApiError;
7180
+ }
7181
+ function getErrorResponse(err) {
7182
+ if (!(err instanceof ApiError)) {
7183
+ return void 0;
7184
+ }
7185
+ const body = err.body;
7186
+ if (body && typeof body === "object" && typeof body.code === "string" && typeof body.message === "string") {
7187
+ return body;
7188
+ }
7189
+ return void 0;
7190
+ }
7191
+
7163
7192
  // src/sender_auth_schemes/evm_permit2.ts
7164
7193
  var import_ethers3 = require("ethers");
7165
7194
  var import_evm_escrow_encoding = __toESM(require_dist2());
@@ -7333,7 +7362,8 @@ async function signPaymentRequest(request2, signer) {
7333
7362
  }
7334
7363
  return request2;
7335
7364
  }
7336
- var defaultGateway = "https://payment-gateway-testnet.atumlabs.xyz";
7365
+ var defaultGateway = "https://payment-gw.production-testnet.atum.xyz";
7366
+ var OpenAPI2 = { ...OpenAPI, BASE: defaultGateway };
7337
7367
  var DEFAULT_QUOTE_DEADLINE_SECONDS = 5;
7338
7368
  var DEFAULT_FULFILLMENT_DEADLINE_SECONDS = 3600;
7339
7369
  var DEFAULT_PAYMENT_QUOTE_DEADLINE_SECONDS = 10;
@@ -7422,8 +7452,10 @@ async function assemblePaymentRequest(params) {
7422
7452
  }
7423
7453
  var PaymentGatewayClient2 = class extends PaymentGatewayClient {
7424
7454
  constructor(config, HttpRequest = AxiosHttpRequest) {
7425
- super(config, HttpRequest);
7426
- this.baseUrl = config?.BASE ?? defaultGateway;
7455
+ const envBase = (typeof process !== "undefined" ? process.env.GATEWAY_URL : void 0)?.trim();
7456
+ const base = config?.BASE ?? (envBase || defaultGateway);
7457
+ super({ ...config, BASE: base }, HttpRequest);
7458
+ this.baseUrl = base;
7427
7459
  }
7428
7460
  /**
7429
7461
  * Fetches chain defaults from the payment gateway.
@@ -7703,11 +7735,13 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
7703
7735
  encodeU64LE,
7704
7736
  generateSolanaNonce,
7705
7737
  generateSolanaPaymentId,
7738
+ getErrorResponse,
7706
7739
  hashPermitWitnessTransferFrom,
7707
7740
  hashRequestId,
7708
7741
  hashSolanaDeposit,
7709
7742
  hashTvmPermitWitnessTransferFrom,
7710
7743
  hexToBytes,
7744
+ isApiError,
7711
7745
  maskChainId,
7712
7746
  normalizeAddress,
7713
7747
  resolveTurnkeyAddresses,
@@ -0,0 +1,62 @@
1
+ # Payment idempotency
2
+
3
+ Submit the same payment twice — a retry, a timeout, a network blip — and you
4
+ should end up with **one** payment, not two, and receive the **same** answer both
5
+ times. The key to both properties is the `request_id` you send with each payment.
6
+
7
+ ## Using the SDK
8
+
9
+ With `@atumlabs/payment-gateway-client` this is automatic. Pass a stable
10
+ `request_id` and reuse it on retry. `request_id` is required on the payment path
11
+ (`preparePaymentRequest`); the SDK derives the on-chain deposit nonce
12
+ deterministically from it, so both guarantees below line up on their own. You
13
+ never manage nonces — `request_id` is the only value you control.
14
+
15
+ Reuse the same `request_id` across attempts of the same logical payment. Use a
16
+ fresh `request_id` only for a genuinely new payment.
17
+
18
+ ## The two guarantees
19
+
20
+ ### 1. Gateway dedup — enforced for every caller
21
+
22
+ The gateway records your `request_id` (scoped to your source account and signing
23
+ identity). If the same `request_id` arrives again, the gateway returns the
24
+ original payment — same `payment_id`, same status and receipt — and never creates
25
+ a second payment or broadcasts a second deposit. This holds whether you use the
26
+ SDK or call the API directly, as long as you send a stable `request_id` and reuse
27
+ it on retry.
28
+
29
+ ### 2. On-chain single-settlement — enforced by the blockchain
30
+
31
+ Each deposit authorization carries a nonce, and the chain guarantees a given
32
+ nonce can settle at most once. This ties your retries together on-chain **only
33
+ if** each retry carries the **same** nonce. The SDK derives that nonce from your
34
+ `request_id`, so retries reuse it automatically. A direct caller sets the nonce
35
+ themselves in the signed permit.
36
+
37
+ The caveat runs in both directions. A changing `request_id` defeats both
38
+ guarantees, because each attempt is then treated as a different payment — keep it
39
+ stable and reuse it on retry. Equally, reusing a `request_id` with different terms
40
+ (a corrected amount, a different token) returns the **original** payment rather
41
+ than an error, so the new terms are silently dropped. A genuinely new payment
42
+ always needs a new id.
43
+
44
+ ## Chain-specific behavior
45
+
46
+ The SDK gives you the same guarantee on every chain; the on-chain half works
47
+ slightly differently underneath:
48
+
49
+ - **EVM / Tron:** the on-chain nonce is spent permanently, so guarantee 2 lasts
50
+ indefinitely.
51
+ - **Solana:** the on-chain guard covers only a short, bounded window (roughly two
52
+ minutes). Beyond that window the durable protection is guarantee 1 (the
53
+ gateway's `request_id` record). The SDK keeps a rebuild inside the window by
54
+ pinning `issued_at` through its Solana clock reader, so you do not have to.
55
+
56
+ Either way, a stable `request_id` keeps you safe on every chain.
57
+
58
+ ## A note on addresses
59
+
60
+ EVM `0x` addresses are case-insensitive, so casing never affects your payment.
61
+ Solana and Tron base58 addresses **are** case-sensitive — pass them exactly as
62
+ issued.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atumlabs/payment-gateway-client",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "TypeScript client for Atum Payment Gateway API",
5
5
  "author": "Atum Labs, Inc.",
6
6
  "homepage": "https://github.com/Atum-Labs/protocol/tree/main/payment-gateway-client#readme",
@@ -41,11 +41,12 @@
41
41
  "generate": "openapi-ts --input ../schemas/apis/payment-gateway/v1/openapi.yaml --output ./src/generated --client axios --name PaymentGatewayClient --useOptions",
42
42
  "prebuild:deps": "node -e \"if(!require('fs').existsSync('../key-management/common/typescript/tsconfig.json')){console.error('protocol key-management packages not found at ../key-management. Is this checked out inside the protocol monorepo?');process.exit(1)}\"",
43
43
  "build:deps": "tsc -p ../key-management/common/typescript/tsconfig.json && tsc -p ../key-management/providers/turnkey/typescript/tsconfig.json && tsc -p ../contracts/svm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/evm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/tvm/escrow-encoding/typescript/tsconfig.json && tsc -p ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/tsconfig.json",
44
- "build": "pnpm run build:deps && tsup && chmod +x dist/cli/*.js",
44
+ "build": "pnpm run build:deps && tsup && chmod +x dist/cli/*.js && node scripts/stamp-entry-headers.mjs",
45
45
  "pretest": "pnpm run build:deps",
46
46
  "test": "jest",
47
47
  "clean": "rm -rf dist ../key-management/common/typescript/dist ../key-management/providers/turnkey/typescript/dist ../contracts/svm/escrow-encoding/typescript/dist ../contracts/evm/escrow-encoding/typescript/dist ../contracts/tvm/escrow-encoding/typescript/dist ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist",
48
48
  "check:publishable": "node scripts/check-publishable.mjs",
49
+ "gen:notices": "node scripts/gen-third-party-notices.mjs",
49
50
  "prepare": "pnpm run build",
50
51
  "prepublishOnly": "pnpm run build && pnpm run check:publishable"
51
52
  },
@@ -54,6 +55,7 @@
54
55
  "axios": "1.13.2",
55
56
  "bs58": "^6.0.0",
56
57
  "commander": "^12.0.0",
58
+ "dotenv": "^16.6.1",
57
59
  "ethers": "^6.11.0",
58
60
  "tweetnacl": "^1.0.3",
59
61
  "zod": "^3.25.0"
@@ -62,6 +64,7 @@
62
64
  "@atum-labs/evm-escrow-encoding": "workspace:*",
63
65
  "@atum-labs/km-core": "workspace:*",
64
66
  "@atum-labs/payment-request-sender-auth": "workspace:*",
67
+ "@atum-labs/publish-guard": "workspace:*",
65
68
  "@atum-labs/solana-escrow-encoding": "workspace:*",
66
69
  "@atum-labs/turnkey-signer": "workspace:*",
67
70
  "@atum-labs/tvm-escrow-encoding": "workspace:*",
@@ -76,7 +79,14 @@
76
79
  },
77
80
  "files": [
78
81
  "dist/**/*",
79
- "CHANGELOG.md"
82
+ "README.md",
83
+ "CHANGELOG.md",
84
+ "docs/**",
85
+ "LICENSE",
86
+ "THIRD-PARTY-NOTICES.txt"
80
87
  ],
81
- "license": "UNLICENSED"
88
+ "license": "SEE LICENSE IN LICENSE",
89
+ "publishConfig": {
90
+ "access": "restricted"
91
+ }
82
92
  }
File without changes