@atumlabs/payment-gateway-client 3.0.0 → 3.0.1
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 +19 -0
- package/LICENSE +202 -83
- package/NOTICE +2 -0
- package/README.md +30 -13
- package/THIRD-PARTY-NOTICES.txt +4 -5
- package/dist/cli/approve-permit2.js +262 -37
- package/dist/cli/payment-status.js +78 -17
- package/dist/cli/quote-status.js +76 -15
- package/dist/cli/request-quote.js +76 -15
- package/dist/cli/send-payment.js +257 -42
- package/dist/index.d.ts +108 -1982
- package/dist/index.js +440 -149
- package/dist/sender-auth-verify-C-Q-zvAO.d.ts +2013 -0
- package/dist/signing.d.ts +223 -0
- package/dist/signing.js +7219 -0
- package/docs/idempotency.md +2 -1
- package/docs/signing.md +218 -0
- package/package.json +25 -6
- package/signing.d.ts +2 -0
- package/signing.js +11 -0
package/dist/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright
|
|
3
|
-
*
|
|
4
|
-
* Access and use are governed by the LICENSE file distributed with this package.
|
|
5
|
-
* Do not remove, alter, or obscure this notice.
|
|
2
|
+
* Copyright 2026 Atum Labs, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
6
4
|
*/
|
|
7
5
|
"use strict";
|
|
8
6
|
var __create = Object.create;
|
|
@@ -11,11 +9,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
|
11
9
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
13
11
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
-
var __esm = (fn, res) => function __init() {
|
|
15
|
-
|
|
12
|
+
var __esm = (fn, res, err) => function __init() {
|
|
13
|
+
if (err) throw err[0];
|
|
14
|
+
try {
|
|
15
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
throw err = [e], e;
|
|
18
|
+
}
|
|
16
19
|
};
|
|
17
20
|
var __commonJS = (cb, mod) => function __require() {
|
|
18
|
-
|
|
21
|
+
try {
|
|
22
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
23
|
+
} catch (e) {
|
|
24
|
+
throw mod = 0, e;
|
|
25
|
+
}
|
|
19
26
|
};
|
|
20
27
|
var __export = (target, all) => {
|
|
21
28
|
for (var name in all)
|
|
@@ -2105,7 +2112,7 @@ var require_errors2 = __commonJS({
|
|
|
2105
2112
|
"../contracts/svm/escrow-encoding/typescript/dist/errors.js"(exports2) {
|
|
2106
2113
|
"use strict";
|
|
2107
2114
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2108
|
-
exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroSourceAmountError = exports2.ZeroQuoteHashError = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = void 0;
|
|
2115
|
+
exports2.InvalidEscrowDomainError = exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroSourceAmountError = exports2.ZeroQuoteHashError = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = void 0;
|
|
2109
2116
|
var EncodingError = class extends Error {
|
|
2110
2117
|
constructor(message) {
|
|
2111
2118
|
super(message);
|
|
@@ -2218,6 +2225,13 @@ var require_errors2 = __commonJS({
|
|
|
2218
2225
|
}
|
|
2219
2226
|
};
|
|
2220
2227
|
exports2.DestinationTooLongError = DestinationTooLongError;
|
|
2228
|
+
var InvalidEscrowDomainError = class extends EncodingError {
|
|
2229
|
+
constructor(message) {
|
|
2230
|
+
super(message);
|
|
2231
|
+
this.name = "InvalidEscrowDomainError";
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
exports2.InvalidEscrowDomainError = InvalidEscrowDomainError;
|
|
2221
2235
|
}
|
|
2222
2236
|
});
|
|
2223
2237
|
|
|
@@ -2926,12 +2940,17 @@ var require_escrow_domain = __commonJS({
|
|
|
2926
2940
|
"use strict";
|
|
2927
2941
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
2928
2942
|
exports2.escrowDomainPrefixBytes = escrowDomainPrefixBytes;
|
|
2943
|
+
exports2.newEscrowDomain = newEscrowDomain;
|
|
2944
|
+
var errors_1 = require_errors2();
|
|
2929
2945
|
function escrowDomainPrefixBytes(domain) {
|
|
2930
2946
|
if (domain.clusterId.length !== 32) {
|
|
2931
|
-
throw new
|
|
2947
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.clusterId must be 32 bytes, got ${domain.clusterId.length}`);
|
|
2948
|
+
}
|
|
2949
|
+
if (domain.programId.isZero()) {
|
|
2950
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain.programId cannot be zero");
|
|
2932
2951
|
}
|
|
2933
2952
|
if (!Number.isInteger(domain.signatureDomainVersion) || domain.signatureDomainVersion < 1 || domain.signatureDomainVersion > 255) {
|
|
2934
|
-
throw new
|
|
2953
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.signatureDomainVersion must be an integer in 1..=255, got ${domain.signatureDomainVersion}`);
|
|
2935
2954
|
}
|
|
2936
2955
|
return [
|
|
2937
2956
|
new TextEncoder().encode("escrow"),
|
|
@@ -2940,6 +2959,25 @@ var require_escrow_domain = __commonJS({
|
|
|
2940
2959
|
domain.programId.toBytes()
|
|
2941
2960
|
];
|
|
2942
2961
|
}
|
|
2962
|
+
function newEscrowDomain(clusterName, signatureDomainVersion, programId) {
|
|
2963
|
+
const trimmed = clusterName.trim();
|
|
2964
|
+
if (trimmed.length === 0) {
|
|
2965
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain cluster name cannot be empty");
|
|
2966
|
+
}
|
|
2967
|
+
const encoded = new TextEncoder().encode(trimmed);
|
|
2968
|
+
if (encoded.length > 32) {
|
|
2969
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain cluster name "${trimmed}" exceeds 32 bytes`);
|
|
2970
|
+
}
|
|
2971
|
+
if (!Number.isInteger(signatureDomainVersion) || signatureDomainVersion < 1 || signatureDomainVersion > 255) {
|
|
2972
|
+
throw new errors_1.InvalidEscrowDomainError(`EscrowDomain.signatureDomainVersion must be an integer in 1..=255, got ${signatureDomainVersion}`);
|
|
2973
|
+
}
|
|
2974
|
+
if (programId.isZero()) {
|
|
2975
|
+
throw new errors_1.InvalidEscrowDomainError("EscrowDomain.programId cannot be zero");
|
|
2976
|
+
}
|
|
2977
|
+
const clusterId = new Uint8Array(32);
|
|
2978
|
+
clusterId.set(encoded);
|
|
2979
|
+
return { clusterId, signatureDomainVersion, programId };
|
|
2980
|
+
}
|
|
2943
2981
|
}
|
|
2944
2982
|
});
|
|
2945
2983
|
|
|
@@ -3138,7 +3176,7 @@ var require_dist4 = __commonJS({
|
|
|
3138
3176
|
"../contracts/svm/escrow-encoding/typescript/dist/index.js"(exports2) {
|
|
3139
3177
|
"use strict";
|
|
3140
3178
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
3141
|
-
exports2.DEPOSIT_COMPUTE_UNIT_LIMIT = exports2.REPLAY_BUCKETS = exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = exports2.generateNonce = exports2.computeRefundHashV2 = exports2.computeRefundHash = exports2.computeReleaseHashV2 = exports2.computeReleaseHash = exports2.computeReserveHashV3 = exports2.computeReserveHashV2 = exports2.computeReserveHash = exports2.MAX_DESTINATION_LEN = exports2.computeDestinationHash = exports2.computeDepositHashV2 = exports2.computeDepositHash = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroQuoteHashError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = exports2.escrowDomainPrefixBytes = exports2.isZeroBytes32 = exports2.stringToBytes = exports2.keccak256 = exports2.encodeU64LE = exports2.Pubkey = void 0;
|
|
3179
|
+
exports2.DEPOSIT_COMPUTE_UNIT_LIMIT = exports2.REPLAY_BUCKETS = exports2.MAX_VALID_SLOT = exports2.REPLAY_SLOTS = exports2.generateNonce = exports2.computeRefundHashV2 = exports2.computeRefundHash = exports2.computeReleaseHashV2 = exports2.computeReleaseHash = exports2.computeReserveHashV3 = exports2.computeReserveHashV2 = exports2.computeReserveHash = exports2.MAX_DESTINATION_LEN = exports2.computeDestinationHash = exports2.computeDepositHashV2 = exports2.computeDepositHash = exports2.InvalidHexError = exports2.InvalidBase58Error = exports2.InvalidPubkeyLengthError = exports2.InvalidEscrowDomainError = exports2.ZeroSourceAmountError = exports2.ZeroDepositHashError = exports2.ZeroRecipientError = exports2.ZeroReleaserError = exports2.ZeroReserverError = exports2.ZeroAmountError = exports2.ZeroMintError = exports2.ZeroDepositorError = exports2.DestinationTooLongError = exports2.EmptyDestinationError = exports2.ZeroQuoteHashError = exports2.ZeroDepositRequestHashError = exports2.EncodingError = exports2.newEscrowDomain = exports2.escrowDomainPrefixBytes = exports2.isZeroBytes32 = exports2.stringToBytes = exports2.keccak256 = exports2.encodeU64LE = exports2.Pubkey = void 0;
|
|
3142
3180
|
var pubkey_1 = require_pubkey();
|
|
3143
3181
|
Object.defineProperty(exports2, "Pubkey", { enumerable: true, get: function() {
|
|
3144
3182
|
return pubkey_1.Pubkey;
|
|
@@ -3160,6 +3198,9 @@ var require_dist4 = __commonJS({
|
|
|
3160
3198
|
Object.defineProperty(exports2, "escrowDomainPrefixBytes", { enumerable: true, get: function() {
|
|
3161
3199
|
return escrow_domain_1.escrowDomainPrefixBytes;
|
|
3162
3200
|
} });
|
|
3201
|
+
Object.defineProperty(exports2, "newEscrowDomain", { enumerable: true, get: function() {
|
|
3202
|
+
return escrow_domain_1.newEscrowDomain;
|
|
3203
|
+
} });
|
|
3163
3204
|
var errors_1 = require_errors2();
|
|
3164
3205
|
Object.defineProperty(exports2, "EncodingError", { enumerable: true, get: function() {
|
|
3165
3206
|
return errors_1.EncodingError;
|
|
@@ -3197,6 +3238,12 @@ var require_dist4 = __commonJS({
|
|
|
3197
3238
|
Object.defineProperty(exports2, "ZeroDepositHashError", { enumerable: true, get: function() {
|
|
3198
3239
|
return errors_1.ZeroDepositHashError;
|
|
3199
3240
|
} });
|
|
3241
|
+
Object.defineProperty(exports2, "ZeroSourceAmountError", { enumerable: true, get: function() {
|
|
3242
|
+
return errors_1.ZeroSourceAmountError;
|
|
3243
|
+
} });
|
|
3244
|
+
Object.defineProperty(exports2, "InvalidEscrowDomainError", { enumerable: true, get: function() {
|
|
3245
|
+
return errors_1.InvalidEscrowDomainError;
|
|
3246
|
+
} });
|
|
3200
3247
|
Object.defineProperty(exports2, "InvalidPubkeyLengthError", { enumerable: true, get: function() {
|
|
3201
3248
|
return errors_1.InvalidPubkeyLengthError;
|
|
3202
3249
|
} });
|
|
@@ -5477,6 +5524,7 @@ var require_policies = __commonJS({
|
|
|
5477
5524
|
exports2.buildDenyApproveToNonAllowedSpenderTron = buildDenyApproveToNonAllowedSpenderTron;
|
|
5478
5525
|
exports2.listPolicies = listPolicies;
|
|
5479
5526
|
exports2.deletePolicy = deletePolicy;
|
|
5527
|
+
exports2.planPolicyChanges = planPolicyChanges;
|
|
5480
5528
|
exports2.applyPolicies = applyPolicies;
|
|
5481
5529
|
function derivePoliciesFromAllowlist(policy, chain, context) {
|
|
5482
5530
|
const policies = [];
|
|
@@ -5664,26 +5712,54 @@ var require_policies = __commonJS({
|
|
|
5664
5712
|
policyId
|
|
5665
5713
|
});
|
|
5666
5714
|
}
|
|
5715
|
+
function planPolicyChanges(existing, policies) {
|
|
5716
|
+
const existingByName = new Map(existing.map((p) => [p.policyName, p]));
|
|
5717
|
+
const drifted = [];
|
|
5718
|
+
for (const p of policies) {
|
|
5719
|
+
const prev = existingByName.get(p.policyName);
|
|
5720
|
+
if (!prev)
|
|
5721
|
+
continue;
|
|
5722
|
+
const matches = prev.effect === p.effect && prev.condition === p.condition && (prev.consensus ?? "") === (p.consensus ?? "");
|
|
5723
|
+
if (!matches)
|
|
5724
|
+
drifted.push({ name: p.policyName, diff: formatPolicyDiff(prev, p) });
|
|
5725
|
+
}
|
|
5726
|
+
const emittedNames = new Set(policies.map((p) => p.policyName));
|
|
5727
|
+
const stale = existing.filter((p) => !emittedNames.has(p.policyName));
|
|
5728
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5729
|
+
const duplicateNames = [
|
|
5730
|
+
...new Set(existing.filter((p) => !(seen.size === seen.add(p.policyName).size)).map((p) => p.policyName))
|
|
5731
|
+
];
|
|
5732
|
+
return { drifted, stale, duplicateNames };
|
|
5733
|
+
}
|
|
5667
5734
|
async function applyPolicies(client, policies, options) {
|
|
5668
5735
|
const existing = await listPolicies(client, options.organizationId);
|
|
5669
5736
|
const existingByName = new Map(existing.map((p) => [p.policyName, p]));
|
|
5670
5737
|
const created = [];
|
|
5671
5738
|
const skippedUnchanged = [];
|
|
5672
|
-
const drifted = [];
|
|
5673
5739
|
const replaced = [];
|
|
5740
|
+
const pruned = [];
|
|
5741
|
+
const { drifted, stale } = planPolicyChanges(existing, policies);
|
|
5742
|
+
if (stale.length > 0 && !options.prune) {
|
|
5743
|
+
const detail = stale.map((p) => ` - ${p.policyName} [${p.effect}] (${p.policyId})`).join("\n");
|
|
5744
|
+
throw new Error(`${stale.length} live polic${stale.length === 1 ? "y is" : "ies are"} absent from the emitted set:
|
|
5745
|
+
${detail}
|
|
5746
|
+
|
|
5747
|
+
A retired ALLOW left live keeps granting what it always granted, so a narrower replacement does not take effect until it is gone. Re-run with --prune to delete them, or reconcile the config if they are policies this set should still emit.`);
|
|
5748
|
+
}
|
|
5749
|
+
if (drifted.length > 0 && !options.update) {
|
|
5750
|
+
const detail = drifted.map((d) => ` - ${d.name}:
|
|
5751
|
+
${indent(d.diff, " ")}`).join("\n");
|
|
5752
|
+
throw new Error(`Content drift detected on ${drifted.length} polic${drifted.length === 1 ? "y" : "ies"}. Re-run with --update to delete-and-recreate, or fix the existing policy in the Turnkey console.
|
|
5753
|
+
${detail}`);
|
|
5754
|
+
}
|
|
5755
|
+
const driftedNames = new Set(drifted.map((d) => d.name));
|
|
5674
5756
|
for (const p of policies) {
|
|
5675
5757
|
const prev = existingByName.get(p.policyName);
|
|
5676
5758
|
if (prev) {
|
|
5677
|
-
|
|
5678
|
-
if (matches) {
|
|
5759
|
+
if (!driftedNames.has(p.policyName)) {
|
|
5679
5760
|
skippedUnchanged.push(p.policyName);
|
|
5680
5761
|
continue;
|
|
5681
5762
|
}
|
|
5682
|
-
const diff = formatPolicyDiff(prev, p);
|
|
5683
|
-
if (!options.update) {
|
|
5684
|
-
drifted.push({ name: p.policyName, diff });
|
|
5685
|
-
continue;
|
|
5686
|
-
}
|
|
5687
5763
|
await deletePolicy(client, prev.policyId);
|
|
5688
5764
|
const newId = await createPolicyRaw(client, p);
|
|
5689
5765
|
replaced.push({ name: p.policyName, oldPolicyId: prev.policyId, newPolicyId: newId });
|
|
@@ -5693,13 +5769,11 @@ var require_policies = __commonJS({
|
|
|
5693
5769
|
const id = await createPolicyRaw(client, p);
|
|
5694
5770
|
created.push(id);
|
|
5695
5771
|
}
|
|
5696
|
-
|
|
5697
|
-
|
|
5698
|
-
|
|
5699
|
-
throw new Error(`Content drift detected on ${drifted.length} polic${drifted.length === 1 ? "y" : "ies"}. Re-run with --update to delete-and-recreate, or fix the existing policy in the Turnkey console.
|
|
5700
|
-
${detail}`);
|
|
5772
|
+
for (const p of stale) {
|
|
5773
|
+
await deletePolicy(client, p.policyId);
|
|
5774
|
+
pruned.push({ name: p.policyName, policyId: p.policyId });
|
|
5701
5775
|
}
|
|
5702
|
-
return { created, skippedUnchanged, replaced };
|
|
5776
|
+
return { created, skippedUnchanged, replaced, pruned };
|
|
5703
5777
|
}
|
|
5704
5778
|
async function createPolicyRaw(client, p) {
|
|
5705
5779
|
const result = await client.executeActivity("ACTIVITY_TYPE_CREATE_POLICY_V3", "create_policy", {
|
|
@@ -5745,6 +5819,8 @@ var require_sender_policies = __commonJS({
|
|
|
5745
5819
|
"use strict";
|
|
5746
5820
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
5747
5821
|
exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = void 0;
|
|
5822
|
+
exports2.tronTip712ChainId = tronTip712ChainId;
|
|
5823
|
+
exports2.toTronEvmHex = toTronEvmHex;
|
|
5748
5824
|
exports2.buildSenderPolicies = buildSenderPolicies;
|
|
5749
5825
|
exports2.tronBase58ToEvmHex = tronBase58ToEvmHex;
|
|
5750
5826
|
var node_crypto_1 = require("crypto");
|
|
@@ -5754,6 +5830,57 @@ var require_sender_policies = __commonJS({
|
|
|
5754
5830
|
shasta: "TPUqJPASUn1zLvbLBgRZ5pBYrx7WSe5ahp"
|
|
5755
5831
|
};
|
|
5756
5832
|
var APPROVE_SELECTOR = "0x095ea7b3";
|
|
5833
|
+
var PERMIT2_PRIMARY_TYPE = "PermitWitnessTransferFrom";
|
|
5834
|
+
var PERMIT2_DOMAIN_NAME = "Permit2";
|
|
5835
|
+
var TRON_TIP712_CHAIN_IDS = {
|
|
5836
|
+
mainnet: 728126428,
|
|
5837
|
+
shasta: 2494104990
|
|
5838
|
+
};
|
|
5839
|
+
function tronTip712ChainId(caip2) {
|
|
5840
|
+
const cluster = caip2.split(":")[1] ?? "";
|
|
5841
|
+
const id = Object.hasOwn(TRON_TIP712_CHAIN_IDS, cluster) ? TRON_TIP712_CHAIN_IDS[cluster] : void 0;
|
|
5842
|
+
if (id === void 0) {
|
|
5843
|
+
throw new Error(`Sender extras: unsupported Tron network "${caip2}". Known clusters: ${Object.keys(TRON_TIP712_CHAIN_IDS).join(", ")}.`);
|
|
5844
|
+
}
|
|
5845
|
+
return (id & 4294967295) >>> 0;
|
|
5846
|
+
}
|
|
5847
|
+
function evmNumericChainId(caip2) {
|
|
5848
|
+
const id = Number.parseInt(caip2.split(":")[1] ?? "", 10);
|
|
5849
|
+
if (!Number.isSafeInteger(id) || id <= 0) {
|
|
5850
|
+
throw new Error(`Sender extras: chain id "${caip2}" is not a usable eip155 CAIP-2 identifier.`);
|
|
5851
|
+
}
|
|
5852
|
+
return id;
|
|
5853
|
+
}
|
|
5854
|
+
var lower = (a) => a.toLowerCase();
|
|
5855
|
+
function assertEvmAddress(address, chainKey) {
|
|
5856
|
+
if (!/^0x[0-9a-fA-F]{40}$/.test(address)) {
|
|
5857
|
+
throw new Error(`Sender extras: ${JSON.stringify(address)} on chain "${chainKey}" is not a 20-byte 0x hex address. A malformed literal matches nothing, which denies every payment on this chain.`);
|
|
5858
|
+
}
|
|
5859
|
+
return address;
|
|
5860
|
+
}
|
|
5861
|
+
function toTronEvmHex(address) {
|
|
5862
|
+
if (address.startsWith("T"))
|
|
5863
|
+
return `0x${tronBase58ToEvmHex(address)}`;
|
|
5864
|
+
if (/^0x[0-9a-fA-F]{40}$/.test(address))
|
|
5865
|
+
return lower(address);
|
|
5866
|
+
throw new Error(`Sender extras: Tron address ${JSON.stringify(address)} is neither a base58 (T\u2026) address nor a 20-byte 0x hex address, so its TIP-712 message form cannot be derived.`);
|
|
5867
|
+
}
|
|
5868
|
+
var quotedLower = (xs) => xs.map((x) => `'${lower(x)}'`).join(", ");
|
|
5869
|
+
function quotedExact(xs, chainKey) {
|
|
5870
|
+
for (const x of xs) {
|
|
5871
|
+
if (x.includes("'") || x.includes("\\")) {
|
|
5872
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" contains a quote or backslash, which cannot appear in a policy condition literal.`);
|
|
5873
|
+
}
|
|
5874
|
+
if (x.length === 0 || !x.includes("@")) {
|
|
5875
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" is not a composed destination (<caip19-asset>@<account>). Build it with buildEscrowDestination.`);
|
|
5876
|
+
}
|
|
5877
|
+
if (Buffer.byteLength(x, "utf8") > MAX_DESTINATION_BYTES) {
|
|
5878
|
+
throw new Error(`Sender extras: destination ${JSON.stringify(x)} on chain "${chainKey}" is longer than ${MAX_DESTINATION_BYTES} bytes, which the escrow rejects as DestinationTooLong, so no deposit could ever carry it.`);
|
|
5879
|
+
}
|
|
5880
|
+
}
|
|
5881
|
+
return xs.map((x) => `'${x}'`).join(", ");
|
|
5882
|
+
}
|
|
5883
|
+
var MAX_DESTINATION_BYTES = 256;
|
|
5757
5884
|
var SOLANA_STANDARD_PROGRAMS = [
|
|
5758
5885
|
"11111111111111111111111111111111",
|
|
5759
5886
|
// System
|
|
@@ -5783,12 +5910,20 @@ var require_sender_policies = __commonJS({
|
|
|
5783
5910
|
}
|
|
5784
5911
|
function buildSenderPolicies(extras, chains) {
|
|
5785
5912
|
const policies = [];
|
|
5786
|
-
|
|
5787
|
-
|
|
5788
|
-
|
|
5789
|
-
|
|
5790
|
-
|
|
5791
|
-
}
|
|
5913
|
+
const permit2Evm = lower(extras.permit2 ?? exports2.EVM_PERMIT2);
|
|
5914
|
+
for (const chain of chains) {
|
|
5915
|
+
if (chain.kind !== "evm" && chain.kind !== "tron")
|
|
5916
|
+
continue;
|
|
5917
|
+
policies.push(permit2TypedDataAllow(chain, extras, permit2Evm));
|
|
5918
|
+
}
|
|
5919
|
+
if (chains.some((c) => c.kind === "solana")) {
|
|
5920
|
+
policies.push({
|
|
5921
|
+
policyName: "allowEd25519RawPayload",
|
|
5922
|
+
effect: "EFFECT_ALLOW",
|
|
5923
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2' && activity.params.encoding in ['PAYLOAD_ENCODING_HEXADECIMAL', 'PAYLOAD_ENCODING_TEXT_UTF8'] && activity.params.hash_function == 'HASH_FUNCTION_NOT_APPLICABLE'`,
|
|
5924
|
+
notes: "Solana deposit inner signature (ed25519 over the deposit digest). Legal on secp256k1 only with EIP712, which the API enforces, so this stays an ed25519-only path."
|
|
5925
|
+
});
|
|
5926
|
+
}
|
|
5792
5927
|
for (const chain of chains) {
|
|
5793
5928
|
if (chain.kind === "evm") {
|
|
5794
5929
|
const evmChainId = parseInt(chain.chainId.split(":")[1], 10);
|
|
@@ -5797,7 +5932,7 @@ var require_sender_policies = __commonJS({
|
|
|
5797
5932
|
throw new Error(`Sender extras: chain "${chain.key}" has no allowedTokens. Add at least one ERC-20 contract address the sender's wallet is permitted to approve, or remove this chain.`);
|
|
5798
5933
|
}
|
|
5799
5934
|
const tokenList = tokens.map((t) => `'${t}'`).join(", ");
|
|
5800
|
-
const permit2Lower =
|
|
5935
|
+
const permit2Lower = permit2Evm.replace(/^0x/, "");
|
|
5801
5936
|
policies.push({
|
|
5802
5937
|
policyName: `allowApproveToPermit2 (${chain.chainId})`,
|
|
5803
5938
|
effect: "EFFECT_ALLOW",
|
|
@@ -5887,13 +6022,70 @@ var require_sender_policies = __commonJS({
|
|
|
5887
6022
|
}
|
|
5888
6023
|
}
|
|
5889
6024
|
policies.push({
|
|
5890
|
-
policyName: "
|
|
6025
|
+
policyName: "denyNonTypedDataHashFunctions",
|
|
6026
|
+
effect: "EFFECT_DENY",
|
|
6027
|
+
condition: `activity.type in ['ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2', 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'] && activity.params.hash_function in ['HASH_FUNCTION_NO_OP', 'HASH_FUNCTION_SHA256', 'HASH_FUNCTION_KECCAK256']`,
|
|
6028
|
+
notes: "NO_OP signs a caller-chosen digest as-is; KECCAK256 signs a caller-chosen preimage, which reproduces any EIP-712 digest and bypasses every typed-data condition."
|
|
6029
|
+
});
|
|
6030
|
+
policies.push({
|
|
6031
|
+
policyName: "denyAccountDelegationEncoding",
|
|
5891
6032
|
effect: "EFFECT_DENY",
|
|
5892
|
-
condition: `activity.type in ['ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2', 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'] && activity.params.
|
|
5893
|
-
notes: "
|
|
6033
|
+
condition: `activity.type in ['ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2', 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'] && activity.params.encoding == 'PAYLOAD_ENCODING_EIP7702_AUTHORIZATION'`,
|
|
6034
|
+
notes: "One signature would delegate the sender EOA to an attacker contract."
|
|
6035
|
+
});
|
|
6036
|
+
policies.push({
|
|
6037
|
+
policyName: "denyBatchRawPayloads",
|
|
6038
|
+
effect: "EFFECT_DENY",
|
|
6039
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOADS'`,
|
|
6040
|
+
notes: "Message conditions bind one payload of a batch, so a second could ride along unbound."
|
|
5894
6041
|
});
|
|
5895
6042
|
return policies;
|
|
5896
6043
|
}
|
|
6044
|
+
function permit2TypedDataAllow(chain, extras, permit2Evm) {
|
|
6045
|
+
const escrowsRaw = extras.escrows?.[chain.key] ?? [];
|
|
6046
|
+
if (escrowsRaw.length === 0) {
|
|
6047
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no escrows. Permit2 leaves the transfer recipient out of the signed struct, so the escrow named as \`spender\` IS the funds destination \u2014 without it a stolen key can authorize a pull to anywhere. Read it from payment-gw /v1/defaults?chain_id=${chain.chainId} (escrow_contract).`);
|
|
6048
|
+
}
|
|
6049
|
+
const isTron = chain.kind === "tron";
|
|
6050
|
+
const tronCluster = isTron ? chain.chainId.split(":")[1] ?? "" : "";
|
|
6051
|
+
if (isTron) {
|
|
6052
|
+
const expected = extras.network === "mainnet" ? "mainnet" : "shasta";
|
|
6053
|
+
if (tronCluster !== expected) {
|
|
6054
|
+
throw new Error(`Sender extras: network "${extras.network}" selects the ${expected} Permit2 deployment, but chain "${chain.key}" is "${chain.chainId}". The domain would carry one cluster's Permit2 with another's chain id, which matches no signature the runtime produces.`);
|
|
6055
|
+
}
|
|
6056
|
+
}
|
|
6057
|
+
const permit2 = isTron ? `0x${tronBase58ToEvmHex(exports2.TRON_PERMIT2[tronCluster])}` : permit2Evm;
|
|
6058
|
+
const chainIdValue = isTron ? tronTip712ChainId(chain.chainId) : evmNumericChainId(chain.chainId);
|
|
6059
|
+
const addr = (xs) => quotedLower(xs.map((x) => isTron ? toTronEvmHex(x) : assertEvmAddress(x, chain.key)));
|
|
6060
|
+
const tokens = extras.allowedTokens[chain.key] ?? [];
|
|
6061
|
+
if (tokens.length === 0) {
|
|
6062
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no allowedTokens, so the typed-data allow would not bind which token the permit moves.`);
|
|
6063
|
+
}
|
|
6064
|
+
const tokenClause = ` && eth.eip_712.message['permitted']['token'] in [${addr(tokens)}]`;
|
|
6065
|
+
const reservers = extras.reservers?.[chain.key] ?? [];
|
|
6066
|
+
const releasers = extras.releasers?.[chain.key] ?? [];
|
|
6067
|
+
for (const [role, vals, field] of [
|
|
6068
|
+
["reservers", reservers, "quote_selector"],
|
|
6069
|
+
["releasers", releasers, "fulfillment_verifier.account"]
|
|
6070
|
+
]) {
|
|
6071
|
+
if (vals.length === 0) {
|
|
6072
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no ${role}. Either witness role can divert funds at settlement and the payer pins neither client-side, so leaving this unset is a hole this policy set is meant to close. Read it from payment-gw /v1/defaults?chain_id=${chain.chainId} (${field}).`);
|
|
6073
|
+
}
|
|
6074
|
+
}
|
|
6075
|
+
const reserverClause = ` && eth.eip_712.message['witness']['reserver'] in [${addr(reservers)}]`;
|
|
6076
|
+
const releaserClause = ` && eth.eip_712.message['witness']['releaser'] in [${addr(releasers)}]`;
|
|
6077
|
+
const destinations = extras.allowedDestinations?.[chain.key] ?? [];
|
|
6078
|
+
if (destinations.length === 0) {
|
|
6079
|
+
throw new Error(`Sender extras: chain "${chain.key}" has no allowedDestinations. Without them a stolen key can authorize a deposit whose payout instruction names the attacker, which is the hole this policy set exists to close. Compose each entry with buildEscrowDestination, or remove the chain.`);
|
|
6080
|
+
}
|
|
6081
|
+
const destinationClause = ` && eth.eip_712.message['witness']['destination'] in [${quotedExact(destinations, chain.key)}]`;
|
|
6082
|
+
return {
|
|
6083
|
+
policyName: `allowPermit2DepositTypedData (${chain.chainId})`,
|
|
6084
|
+
effect: "EFFECT_ALLOW",
|
|
6085
|
+
condition: `activity.type == 'ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2' && activity.params.encoding == 'PAYLOAD_ENCODING_EIP712' && activity.params.hash_function == 'HASH_FUNCTION_NOT_APPLICABLE' && eth.eip_712.primary_type == '${PERMIT2_PRIMARY_TYPE}' && eth.eip_712.domain.name == '${PERMIT2_DOMAIN_NAME}' && eth.eip_712.domain.verifying_contract == '${permit2}' && eth.eip_712.domain.chain_id == ${chainIdValue} && eth.eip_712.message['spender'] in [${addr(escrowsRaw)}]` + tokenClause + reserverClause + releaserClause + destinationClause,
|
|
6086
|
+
notes: "The sender's only fund-moving signature: a Permit2 deposit authorization into an allowlisted escrow, for an allowlisted token, committing to an allowlisted destination."
|
|
6087
|
+
};
|
|
6088
|
+
}
|
|
5897
6089
|
function tronBase58ToEvmHex(b58) {
|
|
5898
6090
|
const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
5899
6091
|
let bn = 0n;
|
|
@@ -6197,7 +6389,7 @@ var require_admin = __commonJS({
|
|
|
6197
6389
|
"../key-management/providers/turnkey/typescript/dist/admin/index.js"(exports2) {
|
|
6198
6390
|
"use strict";
|
|
6199
6391
|
Object.defineProperty(exports2, "__esModule", { value: true });
|
|
6200
|
-
exports2.validateExtras = exports2.buildExtrasPolicies = exports2.tronBase58ToEvmHex = exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = exports2.buildSenderPolicies = exports2.listPolicies = exports2.derivePoliciesFromAllowlist = exports2.deletePolicy = exports2.buildDenyApproveToNonAllowedSpenderTron = exports2.buildDenyApproveToNonAllowedSpenderEvm = exports2.buildAllowSignRawPayloadPolicy = exports2.applyPolicies = exports2.createWalletWithChainAccounts = exports2.planRevocation = exports2.listUsers = exports2.isExpiredApiKey = exports2.isDurableApiKey = exports2.getUser = exports2.findApiKeyByPublicKey = exports2.deleteApiKeys = exports2.addApiKeys = exports2.UnsafeRevocationError = exports2.MAX_API_KEYS_PER_USER = exports2.listPendingActivities = exports2.getRootQuorum = exports2.getActivity = exports2.approvedVoterIds = exports2.approveActivity = exports2.provisionAgentUser = exports2.deleteSubOrganization = exports2.listSubOrganizations = exports2.createSubOrganization = void 0;
|
|
6392
|
+
exports2.validateExtras = exports2.buildExtrasPolicies = exports2.tronTip712ChainId = exports2.tronBase58ToEvmHex = exports2.toTronEvmHex = exports2.TRON_PERMIT2 = exports2.EVM_PERMIT2 = exports2.buildSenderPolicies = exports2.planPolicyChanges = exports2.listPolicies = exports2.derivePoliciesFromAllowlist = exports2.deletePolicy = exports2.buildDenyApproveToNonAllowedSpenderTron = exports2.buildDenyApproveToNonAllowedSpenderEvm = exports2.buildAllowSignRawPayloadPolicy = exports2.applyPolicies = exports2.createWalletWithChainAccounts = exports2.planRevocation = exports2.listUsers = exports2.isExpiredApiKey = exports2.isDurableApiKey = exports2.getUser = exports2.findApiKeyByPublicKey = exports2.deleteApiKeys = exports2.addApiKeys = exports2.UnsafeRevocationError = exports2.MAX_API_KEYS_PER_USER = exports2.listPendingActivities = exports2.getRootQuorum = exports2.getActivity = exports2.approvedVoterIds = exports2.approveActivity = exports2.provisionAgentUser = exports2.deleteSubOrganization = exports2.listSubOrganizations = exports2.createSubOrganization = void 0;
|
|
6201
6393
|
var sub_organizations_1 = require_sub_organizations();
|
|
6202
6394
|
Object.defineProperty(exports2, "createSubOrganization", { enumerable: true, get: function() {
|
|
6203
6395
|
return sub_organizations_1.createSubOrganization;
|
|
@@ -6287,6 +6479,9 @@ var require_admin = __commonJS({
|
|
|
6287
6479
|
Object.defineProperty(exports2, "listPolicies", { enumerable: true, get: function() {
|
|
6288
6480
|
return policies_1.listPolicies;
|
|
6289
6481
|
} });
|
|
6482
|
+
Object.defineProperty(exports2, "planPolicyChanges", { enumerable: true, get: function() {
|
|
6483
|
+
return policies_1.planPolicyChanges;
|
|
6484
|
+
} });
|
|
6290
6485
|
var sender_policies_1 = require_sender_policies();
|
|
6291
6486
|
Object.defineProperty(exports2, "buildSenderPolicies", { enumerable: true, get: function() {
|
|
6292
6487
|
return sender_policies_1.buildSenderPolicies;
|
|
@@ -6297,9 +6492,15 @@ var require_admin = __commonJS({
|
|
|
6297
6492
|
Object.defineProperty(exports2, "TRON_PERMIT2", { enumerable: true, get: function() {
|
|
6298
6493
|
return sender_policies_1.TRON_PERMIT2;
|
|
6299
6494
|
} });
|
|
6495
|
+
Object.defineProperty(exports2, "toTronEvmHex", { enumerable: true, get: function() {
|
|
6496
|
+
return sender_policies_1.toTronEvmHex;
|
|
6497
|
+
} });
|
|
6300
6498
|
Object.defineProperty(exports2, "tronBase58ToEvmHex", { enumerable: true, get: function() {
|
|
6301
6499
|
return sender_policies_1.tronBase58ToEvmHex;
|
|
6302
6500
|
} });
|
|
6501
|
+
Object.defineProperty(exports2, "tronTip712ChainId", { enumerable: true, get: function() {
|
|
6502
|
+
return sender_policies_1.tronTip712ChainId;
|
|
6503
|
+
} });
|
|
6303
6504
|
var extras_policies_1 = require_extras_policies();
|
|
6304
6505
|
Object.defineProperty(exports2, "buildExtrasPolicies", { enumerable: true, get: function() {
|
|
6305
6506
|
return extras_policies_1.buildExtrasPolicies;
|
|
@@ -6543,11 +6744,14 @@ __export(index_exports, {
|
|
|
6543
6744
|
$GetPaymentStatusResponse: () => $GetPaymentStatusResponse,
|
|
6544
6745
|
$OwnedAsset: () => $OwnedAsset,
|
|
6545
6746
|
$PaymentBlockchainContext: () => $PaymentBlockchainContext,
|
|
6546
|
-
$
|
|
6747
|
+
$PaymentFailure: () => $PaymentFailure,
|
|
6547
6748
|
$PaymentRequest: () => $PaymentRequest,
|
|
6548
6749
|
$PaymentResponse: () => $PaymentResponse,
|
|
6750
|
+
$PaymentStatus: () => $PaymentStatus,
|
|
6549
6751
|
$PaymentSummary: () => $PaymentSummary,
|
|
6550
6752
|
$PaymentTimelineResponse: () => $PaymentTimelineResponse,
|
|
6753
|
+
$PaymentTransaction: () => $PaymentTransaction,
|
|
6754
|
+
$PaymentTransactions: () => $PaymentTransactions,
|
|
6551
6755
|
$PreparePaymentRequest: () => $PreparePaymentRequest,
|
|
6552
6756
|
$PreparePaymentResponse: () => $PreparePaymentResponse,
|
|
6553
6757
|
$Quote: () => $Quote,
|
|
@@ -6558,7 +6762,6 @@ __export(index_exports, {
|
|
|
6558
6762
|
$SenderAuth: () => $SenderAuth,
|
|
6559
6763
|
$SenderAuthMessageScheme: () => $SenderAuthMessageScheme,
|
|
6560
6764
|
$SignedMessage: () => $SignedMessage,
|
|
6561
|
-
$TimelineError: () => $TimelineError,
|
|
6562
6765
|
$TimelineStep: () => $TimelineStep,
|
|
6563
6766
|
$VerifiableCredential: () => $VerifiableCredential,
|
|
6564
6767
|
$VerifiableCredentialAuth: () => $VerifiableCredentialAuth,
|
|
@@ -7501,6 +7704,9 @@ var PaymentGatewayClient = class {
|
|
|
7501
7704
|
}
|
|
7502
7705
|
};
|
|
7503
7706
|
|
|
7707
|
+
// src/timeout-http-request.ts
|
|
7708
|
+
var import_axios2 = __toESM(require("axios"));
|
|
7709
|
+
|
|
7504
7710
|
// src/errors.ts
|
|
7505
7711
|
var GatewayTimeoutError = class extends Error {
|
|
7506
7712
|
constructor(baseUrl, timeoutMs) {
|
|
@@ -7574,6 +7780,12 @@ function isAxiosTimeout(error) {
|
|
|
7574
7780
|
if (failure.code === "ECONNABORTED" || failure.code === "ETIMEDOUT") return true;
|
|
7575
7781
|
return failure.code === "ERR_BAD_RESPONSE" && /stream has been aborted/i.test(failure.message ?? "");
|
|
7576
7782
|
}
|
|
7783
|
+
function dropPartialResponseOnTimeout(error) {
|
|
7784
|
+
if (isAxiosTimeout(error) && error !== null && typeof error === "object" && "response" in error) {
|
|
7785
|
+
delete error.response;
|
|
7786
|
+
}
|
|
7787
|
+
return error;
|
|
7788
|
+
}
|
|
7577
7789
|
function translateTimeout(error, baseUrl, fallbackTimeoutMs) {
|
|
7578
7790
|
if (!isAxiosTimeout(error)) return error;
|
|
7579
7791
|
const configured = error.config?.timeout;
|
|
@@ -7581,6 +7793,11 @@ function translateTimeout(error, baseUrl, fallbackTimeoutMs) {
|
|
|
7581
7793
|
}
|
|
7582
7794
|
|
|
7583
7795
|
// src/timeout-http-request.ts
|
|
7796
|
+
var timeoutAxios = import_axios2.default.create();
|
|
7797
|
+
timeoutAxios.interceptors.response.use(
|
|
7798
|
+
void 0,
|
|
7799
|
+
(error) => Promise.reject(dropPartialResponseOnTimeout(error))
|
|
7800
|
+
);
|
|
7584
7801
|
function withRequestTimeout(config, timeouts) {
|
|
7585
7802
|
const request2 = new Interceptors();
|
|
7586
7803
|
for (const fn of config?.interceptors?.request?._fns ?? []) request2.use(fn);
|
|
@@ -7596,7 +7813,7 @@ var TimeoutHttpRequest = class extends AxiosHttpRequest {
|
|
|
7596
7813
|
}
|
|
7597
7814
|
request(options) {
|
|
7598
7815
|
return new CancelablePromise((resolve2, reject, onCancel) => {
|
|
7599
|
-
const pending =
|
|
7816
|
+
const pending = request(this.config, options, timeoutAxios);
|
|
7600
7817
|
onCancel(() => pending.cancel());
|
|
7601
7818
|
pending.then(resolve2, (error) => {
|
|
7602
7819
|
const request2 = { method: options.method, url: options.url, wait: options.query?.wait };
|
|
@@ -8046,7 +8263,7 @@ a past value is rejected with 400.`,
|
|
|
8046
8263
|
type: "string",
|
|
8047
8264
|
format: "date-time",
|
|
8048
8265
|
description: `Required. The final deadline for completing the payment. If not completed by this time the
|
|
8049
|
-
payment
|
|
8266
|
+
payment fails and is eligible for a refund. The gateway injects no default and validates
|
|
8050
8267
|
the value is in the future. The originator must supply it, and a request that omits it or
|
|
8051
8268
|
supplies a past value is rejected with 400.`,
|
|
8052
8269
|
example: "2024-12-25T11:00:00Z"
|
|
@@ -8394,6 +8611,104 @@ var $VerifiableCredential = {
|
|
|
8394
8611
|
}
|
|
8395
8612
|
}
|
|
8396
8613
|
};
|
|
8614
|
+
var $PaymentStatus = {
|
|
8615
|
+
type: "string",
|
|
8616
|
+
description: `Where your payment is in its lifecycle. One payment reads the same however you ask
|
|
8617
|
+
about it.
|
|
8618
|
+
|
|
8619
|
+
- \`pending\`: accepted and in progress. Nothing has reached the recipient yet.
|
|
8620
|
+
- \`finalizing\`: the transaction paying your recipient is on chain and is accruing
|
|
8621
|
+
the confirmations its chain requires. NOT FINAL, see below.
|
|
8622
|
+
- \`completed\`: delivered, with the required confirmations behind it.
|
|
8623
|
+
- \`failed\`: did not complete. Any funds held in escrow are returned, and \`error\`
|
|
8624
|
+
describes what went wrong.
|
|
8625
|
+
|
|
8626
|
+
\`completed\` and \`failed\` are final and will not change afterwards. \`pending\` and
|
|
8627
|
+
\`finalizing\` will.
|
|
8628
|
+
|
|
8629
|
+
**Do not treat \`finalizing\` as delivered.** It says the payment has been made on
|
|
8630
|
+
chain but is not yet irreversible, much as a card authorization is not yet a
|
|
8631
|
+
settlement. It normally becomes \`completed\`, and it can still become \`failed\` if
|
|
8632
|
+
the transaction never reaches the confirmation depth its chain requires. Acting on
|
|
8633
|
+
\`finalizing\` \u2014 releasing goods, crediting an account \u2014 means accepting that risk
|
|
8634
|
+
deliberately, at whatever threshold suits you rather than the one we wait for.
|
|
8635
|
+
|
|
8636
|
+
\`finalizing\` is about paying the recipient. While your own funds are still being
|
|
8637
|
+
committed on the source chain the payment is \`pending\`, because nothing has reached
|
|
8638
|
+
the recipient yet.
|
|
8639
|
+
`,
|
|
8640
|
+
enum: ["pending", "finalizing", "completed", "failed"],
|
|
8641
|
+
example: "pending"
|
|
8642
|
+
};
|
|
8643
|
+
var $PaymentTransaction = {
|
|
8644
|
+
type: "object",
|
|
8645
|
+
description: `One on-chain transaction belonging to a payment: which chain, which transaction, and
|
|
8646
|
+
which block it landed in.
|
|
8647
|
+
|
|
8648
|
+
Whether the payment has actually happened is answered by \`status\`, not here. Read this
|
|
8649
|
+
to look the transaction up on chain and to verify it yourself.
|
|
8650
|
+
`,
|
|
8651
|
+
required: ["transaction_hash", "chain_id"],
|
|
8652
|
+
properties: {
|
|
8653
|
+
transaction_hash: {
|
|
8654
|
+
type: "string",
|
|
8655
|
+
description: `The transaction's hash on its chain. Hex hashes carry the \`0x\` prefix, including on
|
|
8656
|
+
Tron, whose own tooling omits it.
|
|
8657
|
+
`,
|
|
8658
|
+
pattern: "^(0x[a-fA-F0-9]{64}|[1-9A-HJ-NP-Za-km-z]{32,88})$",
|
|
8659
|
+
example: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"
|
|
8660
|
+
},
|
|
8661
|
+
chain_id: {
|
|
8662
|
+
type: "string",
|
|
8663
|
+
description: "CAIP-2 identifier of the chain the transaction is on.",
|
|
8664
|
+
pattern: "^[a-z0-9]+:[a-zA-Z0-9_-]+$",
|
|
8665
|
+
example: "eip155:42161"
|
|
8666
|
+
},
|
|
8667
|
+
block_number: {
|
|
8668
|
+
type: "integer",
|
|
8669
|
+
description: `The block the transaction landed in. Absent until it has been mined.
|
|
8670
|
+
|
|
8671
|
+
Provisional while \`status\` is \`finalizing\`: on a chain that settles against another,
|
|
8672
|
+
a reorganization there can move the transaction to a different block. Settled once
|
|
8673
|
+
\`status\` is \`completed\` \u2014 keep it as a final record only from then.
|
|
8674
|
+
`,
|
|
8675
|
+
example: 61234567
|
|
8676
|
+
}
|
|
8677
|
+
}
|
|
8678
|
+
};
|
|
8679
|
+
var $PaymentTransactions = {
|
|
8680
|
+
type: "object",
|
|
8681
|
+
description: `The transactions a payment has produced, one entry per stage, added as each becomes
|
|
8682
|
+
known. A stage absent here has produced no transaction yet.
|
|
8683
|
+
|
|
8684
|
+
These are the two movements that decide whether your payment happened: your funds
|
|
8685
|
+
being committed, and your recipient being paid. Present on every outcome, so a
|
|
8686
|
+
payment that did not complete can still be traced on chain.
|
|
8687
|
+
\`fulfillment_confirmation\` is not a substitute: it is written only once a payment
|
|
8688
|
+
completes, and describes the finished delivery rather than progress towards it.
|
|
8689
|
+
|
|
8690
|
+
Where a stage is attempted more than once, the entry describes the attempt that
|
|
8691
|
+
counts \u2014 the one that succeeded, or the last one if none did.
|
|
8692
|
+
`,
|
|
8693
|
+
properties: {
|
|
8694
|
+
deposit: {
|
|
8695
|
+
allOf: [
|
|
8696
|
+
{
|
|
8697
|
+
"$ref": "#/components/schemas/PaymentTransaction"
|
|
8698
|
+
}
|
|
8699
|
+
],
|
|
8700
|
+
description: "Committing your funds on the source chain."
|
|
8701
|
+
},
|
|
8702
|
+
fulfillment: {
|
|
8703
|
+
allOf: [
|
|
8704
|
+
{
|
|
8705
|
+
"$ref": "#/components/schemas/PaymentTransaction"
|
|
8706
|
+
}
|
|
8707
|
+
],
|
|
8708
|
+
description: "Paying your recipient on the destination chain."
|
|
8709
|
+
}
|
|
8710
|
+
}
|
|
8711
|
+
};
|
|
8397
8712
|
var $PaymentResponse = {
|
|
8398
8713
|
type: "object",
|
|
8399
8714
|
description: `Response from submitting a payment request. If settlement completes inside the
|
|
@@ -8401,9 +8716,9 @@ gateway's synchronous window, the response includes a fulfillment_confirmation w
|
|
|
8401
8716
|
full settlement details. Otherwise you receive a payment_id plus the payment's
|
|
8402
8717
|
current \`status\`, and can poll /v1/payments/{paymentId}/status for updates.
|
|
8403
8718
|
|
|
8404
|
-
Read \`status\` before deciding what to do next: a \`pending\` payment is
|
|
8405
|
-
must NOT be re-submitted under a new request_id (that would be a second
|
|
8406
|
-
whereas a \`failed\`
|
|
8719
|
+
Read \`status\` before deciding what to do next: a \`pending\` or \`finalizing\` payment is
|
|
8720
|
+
in flight and must NOT be re-submitted under a new request_id (that would be a second
|
|
8721
|
+
payment), whereas a \`failed\` one is terminal \u2014 re-submitting it under the SAME
|
|
8407
8722
|
request_id resolves to the same terminal payment, so a genuine re-attempt needs a
|
|
8408
8723
|
new request_id.
|
|
8409
8724
|
|
|
@@ -8413,6 +8728,10 @@ settlement lands inside the window you get \`status: completed\`, a full
|
|
|
8413
8728
|
\`quote_id\` and \`fulfillment_quote\`. The fast path therefore needs no follow-up call to
|
|
8414
8729
|
verify: recompute \`quote_hash\` over the returned quote and compare it against the on-chain
|
|
8415
8730
|
commitment from this response alone.
|
|
8731
|
+
|
|
8732
|
+
\`status\` is present on every response. \`completed\` is always accompanied by
|
|
8733
|
+
fulfillment_confirmation; \`failed\` is accompanied by \`error\` where a reason has been
|
|
8734
|
+
recorded.
|
|
8416
8735
|
`,
|
|
8417
8736
|
required: ["payment_id", "status", "idempotent_replay"],
|
|
8418
8737
|
properties: {
|
|
@@ -8423,19 +8742,10 @@ commitment from this response alone.
|
|
|
8423
8742
|
example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f"
|
|
8424
8743
|
},
|
|
8425
8744
|
status: {
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
/
|
|
8430
|
-
- \`pending\`: accepted and being processed
|
|
8431
|
-
- \`completed\`: successfully delivered
|
|
8432
|
-
- \`failed\`: failed (funds returned if escrowed)
|
|
8433
|
-
- \`cancelled\`: cancelled before completion
|
|
8434
|
-
|
|
8435
|
-
Present on every response. \`completed\` is always accompanied by
|
|
8436
|
-
fulfillment_confirmation; \`failed\` is accompanied by \`error\` where a reason has
|
|
8437
|
-
been recorded.
|
|
8438
|
-
`
|
|
8745
|
+
"$ref": "#/components/schemas/PaymentStatus"
|
|
8746
|
+
},
|
|
8747
|
+
transactions: {
|
|
8748
|
+
"$ref": "#/components/schemas/PaymentTransactions"
|
|
8439
8749
|
},
|
|
8440
8750
|
idempotent_replay: {
|
|
8441
8751
|
type: "boolean",
|
|
@@ -8498,7 +8808,7 @@ the status endpoint rather than treat the payment as unverified.
|
|
|
8498
8808
|
"$ref": "#/components/schemas/FulfillmentConfirmation"
|
|
8499
8809
|
},
|
|
8500
8810
|
error: {
|
|
8501
|
-
"$ref": "#/components/schemas/
|
|
8811
|
+
"$ref": "#/components/schemas/PaymentFailure"
|
|
8502
8812
|
}
|
|
8503
8813
|
}
|
|
8504
8814
|
};
|
|
@@ -8512,14 +8822,10 @@ var $GetPaymentStatusResponse = {
|
|
|
8512
8822
|
example: "0x761989729fefb4b0cb8b3e6f787301a3878c91e8fba35ed362a079292879f34f"
|
|
8513
8823
|
},
|
|
8514
8824
|
status: {
|
|
8515
|
-
|
|
8516
|
-
|
|
8517
|
-
|
|
8518
|
-
|
|
8519
|
-
- \`completed\`: Payment successfully delivered
|
|
8520
|
-
- \`failed\`: Payment failed (funds returned if escrowed)
|
|
8521
|
-
- \`cancelled\`: Payment was cancelled before completion
|
|
8522
|
-
`
|
|
8825
|
+
"$ref": "#/components/schemas/PaymentStatus"
|
|
8826
|
+
},
|
|
8827
|
+
transactions: {
|
|
8828
|
+
"$ref": "#/components/schemas/PaymentTransactions"
|
|
8523
8829
|
},
|
|
8524
8830
|
updated_at: {
|
|
8525
8831
|
type: "string",
|
|
@@ -8562,7 +8868,7 @@ JSON passthrough.
|
|
|
8562
8868
|
"$ref": "#/components/schemas/FulfillmentConfirmation"
|
|
8563
8869
|
},
|
|
8564
8870
|
error: {
|
|
8565
|
-
"$ref": "#/components/schemas/
|
|
8871
|
+
"$ref": "#/components/schemas/PaymentFailure"
|
|
8566
8872
|
},
|
|
8567
8873
|
requested_count: {
|
|
8568
8874
|
type: "integer",
|
|
@@ -8589,37 +8895,51 @@ As on the quote-request endpoints, the free-form decline detail is never relayed
|
|
|
8589
8895
|
}
|
|
8590
8896
|
}
|
|
8591
8897
|
};
|
|
8592
|
-
var $
|
|
8898
|
+
var $PaymentFailure = {
|
|
8593
8899
|
type: "object",
|
|
8594
|
-
description: `
|
|
8595
|
-
|
|
8596
|
-
|
|
8900
|
+
description: `Why a payment failed. Present only when \`status\` is \`failed\`, and identical
|
|
8901
|
+
however you ask about the payment.
|
|
8902
|
+
|
|
8903
|
+
\`code\` is the stable, machine-readable identity of the failure \u2014 branch on it
|
|
8904
|
+
rather than on \`message\`, which is written for a person and may be reworded.
|
|
8905
|
+
\`docs_url\` points at the page describing that code.
|
|
8597
8906
|
`,
|
|
8598
8907
|
required: ["code", "message"],
|
|
8599
8908
|
properties: {
|
|
8600
8909
|
code: {
|
|
8601
8910
|
type: "string",
|
|
8602
|
-
description: `Public error category in SCREAMING_SNAKE_CASE.
|
|
8603
|
-
|
|
8604
|
-
- \`
|
|
8605
|
-
- \`
|
|
8606
|
-
- \`INTERNAL_ERROR\`: An unexpected error occurred
|
|
8911
|
+
description: `Public error category in SCREAMING_SNAKE_CASE. Common codes:
|
|
8912
|
+
- \`SETTLEMENT_FAILED\`: the settlement could not be completed
|
|
8913
|
+
- \`NO_QUOTES_RECEIVED\`: no quotes arrived within the auction window
|
|
8914
|
+
- \`INTERNAL_ERROR\`: an unexpected error occurred
|
|
8607
8915
|
`,
|
|
8608
8916
|
example: "SETTLEMENT_FAILED"
|
|
8609
8917
|
},
|
|
8610
8918
|
message: {
|
|
8611
8919
|
type: "string",
|
|
8612
|
-
description: `Human-readable
|
|
8920
|
+
description: `Human-readable description of the failure, for a person reading it. Do not
|
|
8921
|
+
branch on this text.
|
|
8613
8922
|
`,
|
|
8614
8923
|
example: "No quotes received within the auction window"
|
|
8615
8924
|
},
|
|
8616
8925
|
domain: {
|
|
8617
8926
|
type: "string",
|
|
8618
|
-
description: `
|
|
8927
|
+
description: `Which part of the system reported the failure.
|
|
8619
8928
|
`,
|
|
8620
8929
|
enum: ["PAYMENT_GATEWAY", "SETTLER_GATEWAY", "SETTLER_AGENT", "WALLET_ORCHESTRATION", "VERIFICATION_SERVICE", "BLOCKCHAIN", "EXTERNAL_SERVICE"],
|
|
8621
8930
|
example: "PAYMENT_GATEWAY"
|
|
8622
8931
|
},
|
|
8932
|
+
docs_url: {
|
|
8933
|
+
type: "string",
|
|
8934
|
+
format: "uri",
|
|
8935
|
+
description: "Link to the documentation page for this public code."
|
|
8936
|
+
},
|
|
8937
|
+
retry_classification: {
|
|
8938
|
+
type: "string",
|
|
8939
|
+
description: `What the caller should do next. Absent means the condition has not been classified, which is not the same as safe to retry.
|
|
8940
|
+
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 payment. See https://docs.atum.xyz/errors for the value set.`,
|
|
8941
|
+
example: "RECONCILE_THEN_DECIDE"
|
|
8942
|
+
},
|
|
8623
8943
|
blockchain_context: {
|
|
8624
8944
|
"$ref": "#/components/schemas/PaymentBlockchainContext"
|
|
8625
8945
|
}
|
|
@@ -8627,46 +8947,46 @@ Common codes:
|
|
|
8627
8947
|
};
|
|
8628
8948
|
var $PaymentBlockchainContext = {
|
|
8629
8949
|
type: "object",
|
|
8630
|
-
description: `
|
|
8631
|
-
|
|
8632
|
-
|
|
8633
|
-
`,
|
|
8950
|
+
description: `Where on chain a failed payment failed. Present only when the failure happened
|
|
8951
|
+
on chain \u2014 an escrow revert, or a fulfillment that could not be delivered \u2014 so a
|
|
8952
|
+
payment that failed before any transaction was sent carries no context here.`,
|
|
8634
8953
|
properties: {
|
|
8635
8954
|
chain_id: {
|
|
8636
8955
|
type: "string",
|
|
8637
8956
|
description: "CAIP-2 chain identifier",
|
|
8638
|
-
|
|
8957
|
+
pattern: "^[a-z0-9]+:[a-zA-Z0-9_-]+$"
|
|
8639
8958
|
},
|
|
8640
|
-
|
|
8959
|
+
transaction_hash: {
|
|
8641
8960
|
type: "string",
|
|
8642
8961
|
description: "Failed transaction hash",
|
|
8643
|
-
|
|
8962
|
+
pattern: "^(0x[a-fA-F0-9]{64}|[1-9A-HJ-NP-Za-km-z]{32,88})$"
|
|
8644
8963
|
},
|
|
8645
8964
|
block_number: {
|
|
8646
8965
|
type: "integer",
|
|
8647
|
-
description: "Block number where error occurred"
|
|
8648
|
-
example: 12345678
|
|
8966
|
+
description: "Block number where error occurred"
|
|
8649
8967
|
},
|
|
8650
8968
|
contract_address: {
|
|
8651
8969
|
type: "string",
|
|
8652
|
-
description: "Contract
|
|
8653
|
-
|
|
8970
|
+
description: "Contract that caused the error",
|
|
8971
|
+
pattern: "^(0x[a-fA-F0-9]{40}|[1-9A-HJ-NP-Za-km-z]{32,44})$"
|
|
8654
8972
|
},
|
|
8655
8973
|
revert_reason: {
|
|
8656
8974
|
type: "string",
|
|
8657
|
-
description: "Smart contract revert reason"
|
|
8658
|
-
example: "Insufficient balance"
|
|
8975
|
+
description: "Smart contract revert reason"
|
|
8659
8976
|
},
|
|
8660
8977
|
gas_used: {
|
|
8661
8978
|
type: "string",
|
|
8662
|
-
description: "Gas consumed before failure"
|
|
8663
|
-
example: "21000"
|
|
8979
|
+
description: "Gas consumed before failure"
|
|
8664
8980
|
},
|
|
8665
8981
|
estimated_gas_needed: {
|
|
8666
8982
|
type: "string",
|
|
8667
|
-
description: "Estimated gas needed for success"
|
|
8668
|
-
example: "50000"
|
|
8983
|
+
description: "Estimated gas needed for success"
|
|
8669
8984
|
}
|
|
8985
|
+
},
|
|
8986
|
+
"x-go-type": "atumerror.BlockchainContext",
|
|
8987
|
+
"x-go-type-import": {
|
|
8988
|
+
name: "atumerror",
|
|
8989
|
+
path: "github.com/atum-labs/protocol/schemas/apis/error/v1/bindings/go"
|
|
8670
8990
|
}
|
|
8671
8991
|
};
|
|
8672
8992
|
var $PreparePaymentRequest = {
|
|
@@ -8796,15 +9116,10 @@ structured error describing where and why.
|
|
|
8796
9116
|
example: "0x8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f"
|
|
8797
9117
|
},
|
|
8798
9118
|
status: {
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
- \`settling\`: Settlement in progress (on-chain steps executing)
|
|
8804
|
-
- \`completed\`: Payment successfully delivered
|
|
8805
|
-
- \`failed\`: Payment failed
|
|
8806
|
-
- \`cancelled\`: Payment was cancelled
|
|
8807
|
-
`
|
|
9119
|
+
"$ref": "#/components/schemas/PaymentStatus"
|
|
9120
|
+
},
|
|
9121
|
+
transactions: {
|
|
9122
|
+
"$ref": "#/components/schemas/PaymentTransactions"
|
|
8808
9123
|
},
|
|
8809
9124
|
created_at: {
|
|
8810
9125
|
type: "string",
|
|
@@ -8823,7 +9138,7 @@ structured error describing where and why.
|
|
|
8823
9138
|
"$ref": "#/components/schemas/PaymentSummary"
|
|
8824
9139
|
},
|
|
8825
9140
|
error: {
|
|
8826
|
-
"$ref": "#/components/schemas/
|
|
9141
|
+
"$ref": "#/components/schemas/PaymentFailure"
|
|
8827
9142
|
},
|
|
8828
9143
|
steps: {
|
|
8829
9144
|
type: "array",
|
|
@@ -8877,40 +9192,6 @@ Only set when the source asset's decimals are known via the token registry.
|
|
|
8877
9192
|
}
|
|
8878
9193
|
}
|
|
8879
9194
|
};
|
|
8880
|
-
var $TimelineError = {
|
|
8881
|
-
type: "object",
|
|
8882
|
-
description: "Structured error details when a payment has failed",
|
|
8883
|
-
required: ["code", "message"],
|
|
8884
|
-
properties: {
|
|
8885
|
-
code: {
|
|
8886
|
-
type: "string",
|
|
8887
|
-
description: "Machine-readable error code",
|
|
8888
|
-
example: "ESCROW_DEPOSIT_FAILED"
|
|
8889
|
-
},
|
|
8890
|
-
message: {
|
|
8891
|
-
type: "string",
|
|
8892
|
-
description: "Human-readable error description"
|
|
8893
|
-
},
|
|
8894
|
-
domain: {
|
|
8895
|
-
type: "string",
|
|
8896
|
-
description: "Which component reported the error",
|
|
8897
|
-
example: "SETTLER_AGENT"
|
|
8898
|
-
},
|
|
8899
|
-
chain_id: {
|
|
8900
|
-
type: "string",
|
|
8901
|
-
description: "CAIP-2 chain where the error occurred (if on-chain)",
|
|
8902
|
-
example: "eip155:1"
|
|
8903
|
-
},
|
|
8904
|
-
tx_hash: {
|
|
8905
|
-
type: "string",
|
|
8906
|
-
description: "Transaction hash of the failed on-chain attempt (if applicable)"
|
|
8907
|
-
},
|
|
8908
|
-
revert_reason: {
|
|
8909
|
-
type: "string",
|
|
8910
|
-
description: "Smart-contract revert reason (if the error was an on-chain revert)"
|
|
8911
|
-
}
|
|
8912
|
-
}
|
|
8913
|
-
};
|
|
8914
9195
|
var $TimelineStep = {
|
|
8915
9196
|
type: "object",
|
|
8916
9197
|
required: ["name", "label", "status"],
|
|
@@ -8951,7 +9232,7 @@ var $TimelineStep = {
|
|
|
8951
9232
|
description: "CAIP-2 chain this step happened on (if on-chain)",
|
|
8952
9233
|
example: "eip155:1"
|
|
8953
9234
|
},
|
|
8954
|
-
|
|
9235
|
+
transaction_hash: {
|
|
8955
9236
|
type: "string",
|
|
8956
9237
|
description: "Transaction hash associated with this step (if on-chain)"
|
|
8957
9238
|
},
|
|
@@ -9071,7 +9352,7 @@ the future. Must be strictly earlier than fulfillment_deadline.
|
|
|
9071
9352
|
fulfillment_deadline: {
|
|
9072
9353
|
type: "string",
|
|
9073
9354
|
format: "date-time",
|
|
9074
|
-
description: `Required. Final deadline for completing the payment. Past it the payment
|
|
9355
|
+
description: `Required. Final deadline for completing the payment. Past it the payment fails and
|
|
9075
9356
|
eligible for refund. The gateway injects no default and never mutates the
|
|
9076
9357
|
originator-supplied body, so the value is carried through verbatim to the award call. It
|
|
9077
9358
|
must be supplied and must be in the future. Must be strictly later than quote_deadline.
|
|
@@ -9579,9 +9860,9 @@ agent appears under one reason only.
|
|
|
9579
9860
|
},
|
|
9580
9861
|
retry_classification: {
|
|
9581
9862
|
type: "string",
|
|
9582
|
-
description: `What would have to change for a settler giving this reason to
|
|
9583
|
-
closed set as the \`retry_classification\` on an error response so
|
|
9584
|
-
vocabulary.
|
|
9863
|
+
description: `What would have to change for a settler giving this reason to submit a price quote,
|
|
9864
|
+
drawn from the same closed set as the \`retry_classification\` on an error response so
|
|
9865
|
+
a caller reads one vocabulary.
|
|
9585
9866
|
|
|
9586
9867
|
It describes the decline only. The authoritative instruction for the payment is the
|
|
9587
9868
|
\`retry_classification\` on its own error response: a payment can fail for a reason no
|
|
@@ -9591,6 +9872,14 @@ Optional, and a pattern-constrained string for the same reason \`DeclineReason\`
|
|
|
9591
9872
|
`,
|
|
9592
9873
|
pattern: "^[A-Z][A-Z0-9_]*$",
|
|
9593
9874
|
example: "RETRY_AFTER_DELAY"
|
|
9875
|
+
},
|
|
9876
|
+
docs_url: {
|
|
9877
|
+
type: "string",
|
|
9878
|
+
format: "uri",
|
|
9879
|
+
description: `Link to the documentation for this reason. Absent rather than empty when no page is
|
|
9880
|
+
published, so a reader never follows a link to the site root.
|
|
9881
|
+
`,
|
|
9882
|
+
example: "https://docs.atum.xyz/decline-reasons#insufficient-liquidity"
|
|
9594
9883
|
}
|
|
9595
9884
|
}
|
|
9596
9885
|
};
|
|
@@ -9864,7 +10153,7 @@ var $ChainDefaultsByChain = {
|
|
|
9864
10153
|
|
|
9865
10154
|
// src/payment-tracking.ts
|
|
9866
10155
|
function isTerminalStatus(status) {
|
|
9867
|
-
return status === "completed" || status === "failed"
|
|
10156
|
+
return status === "completed" || status === "failed";
|
|
9868
10157
|
}
|
|
9869
10158
|
var DEFAULT_WAIT_SECONDS = 60;
|
|
9870
10159
|
var DEFAULT_WAIT_BUDGET_MS = DEFAULT_WAIT_SECONDS * 1e3;
|
|
@@ -9983,7 +10272,7 @@ function createSolanaDepositPrehash(paymentId, params) {
|
|
|
9983
10272
|
}
|
|
9984
10273
|
function hashSolanaDeposit(_prehash) {
|
|
9985
10274
|
throw new Error(
|
|
9986
|
-
'hashSolanaDeposit computes the pre-domain-separation Solana deposit hash (199-byte preimage, no "escrow"/version/cluster_id/program_id prefix and no destination_hash). No deployed escrow program accepts it \u2014 on-chain verification rejects it with
|
|
10275
|
+
'hashSolanaDeposit computes the pre-domain-separation Solana deposit hash (199-byte preimage, no "escrow"/version/cluster_id/program_id prefix and no destination_hash). No deployed escrow program accepts it \u2014 on-chain verification rejects it with DepositHashMismatch on every cluster \u2014 so it cannot be used to build a deposit. Use the shared sender_auth adapter instead: getChainAdapter(chainId).buildAuthMessage({ ... }), which picks the preimage that matches the escrow domain version and is what the facilitator verifies against.'
|
|
9987
10276
|
);
|
|
9988
10277
|
}
|
|
9989
10278
|
function generateSolanaNonce() {
|
|
@@ -10314,8 +10603,8 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
10314
10603
|
// reasonable against that type - would otherwise build an EIP-712 domain around a
|
|
10315
10604
|
// null verifyingContract.
|
|
10316
10605
|
permit2Contract: data.permit2_contract ?? void 0,
|
|
10317
|
-
// Which deposit witness the escrow on this chain pins
|
|
10318
|
-
// four-member
|
|
10606
|
+
// Which deposit witness the escrow on this chain pins. Absent means the
|
|
10607
|
+
// four-member witness — see ChainDefaults.depositWitnessVersion for why
|
|
10319
10608
|
// absence is the permissive default. EVM/Tron only; Solana uses the svm_* fields below.
|
|
10320
10609
|
depositWitnessVersion: data.deposit_witness_version ?? void 0,
|
|
10321
10610
|
// V3 Solana escrow domain separation. Present only for Solana
|
|
@@ -10520,11 +10809,14 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
10520
10809
|
$GetPaymentStatusResponse,
|
|
10521
10810
|
$OwnedAsset,
|
|
10522
10811
|
$PaymentBlockchainContext,
|
|
10523
|
-
$
|
|
10812
|
+
$PaymentFailure,
|
|
10524
10813
|
$PaymentRequest,
|
|
10525
10814
|
$PaymentResponse,
|
|
10815
|
+
$PaymentStatus,
|
|
10526
10816
|
$PaymentSummary,
|
|
10527
10817
|
$PaymentTimelineResponse,
|
|
10818
|
+
$PaymentTransaction,
|
|
10819
|
+
$PaymentTransactions,
|
|
10528
10820
|
$PreparePaymentRequest,
|
|
10529
10821
|
$PreparePaymentResponse,
|
|
10530
10822
|
$Quote,
|
|
@@ -10535,7 +10827,6 @@ var PaymentGatewayClient2 = class extends PaymentGatewayClient {
|
|
|
10535
10827
|
$SenderAuth,
|
|
10536
10828
|
$SenderAuthMessageScheme,
|
|
10537
10829
|
$SignedMessage,
|
|
10538
|
-
$TimelineError,
|
|
10539
10830
|
$TimelineStep,
|
|
10540
10831
|
$VerifiableCredential,
|
|
10541
10832
|
$VerifiableCredentialAuth,
|