@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/CHANGELOG.md +24 -0
- package/README.md +127 -51
- package/THIRD-PARTY-NOTICES.txt +45 -0
- package/dist/cli/payment-status.js +58 -39
- package/dist/cli/quote-status.js +58 -39
- package/dist/cli/request-quote.js +59 -40
- package/dist/cli/send-payment.js +60 -39
- package/dist/index.d.ts +64 -12
- package/dist/index.js +49 -15
- package/docs/idempotency.md +62 -0
- package/package.json +14 -4
- /package/{LICENSE.md → LICENSE} +0 -0
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
|
-
*
|
|
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
|
-
*
|
|
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.
|
|
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.
|
|
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: "
|
|
2000
|
-
readonly example: "https://
|
|
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: "
|
|
2709
|
-
readonly example: "https://
|
|
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.
|
|
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.
|
|
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: () =>
|
|
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://
|
|
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
|
|
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) =>
|
|
4925
|
+
value.forEach((v) => process2(key, v));
|
|
4918
4926
|
} else {
|
|
4919
|
-
|
|
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://
|
|
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:
|
|
5834
|
-
|
|
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:
|
|
6703
|
-
|
|
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.
|
|
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.
|
|
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-
|
|
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
|
-
|
|
7426
|
-
|
|
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.
|
|
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
|
-
"
|
|
82
|
+
"README.md",
|
|
83
|
+
"CHANGELOG.md",
|
|
84
|
+
"docs/**",
|
|
85
|
+
"LICENSE",
|
|
86
|
+
"THIRD-PARTY-NOTICES.txt"
|
|
80
87
|
],
|
|
81
|
-
"license": "
|
|
88
|
+
"license": "SEE LICENSE IN LICENSE",
|
|
89
|
+
"publishConfig": {
|
|
90
|
+
"access": "restricted"
|
|
91
|
+
}
|
|
82
92
|
}
|
/package/{LICENSE.md → LICENSE}
RENAMED
|
File without changes
|