@atumlabs/mppx-atum-escrow 0.1.1 → 0.3.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 +50 -0
- package/README.md +212 -47
- package/dist/chunk-4YD6566T.js +371 -0
- package/dist/chunk-Z3AUNEU5.js +2645 -0
- package/dist/{chunk-2MWWLU75.js → chunk-ZFA5SSUP.js} +1691 -1653
- package/dist/client.d.ts +21 -16
- package/dist/client.js +4 -2
- package/dist/index.d.ts +19 -18
- package/dist/index.js +19 -3
- package/dist/internal-9tB7y-A7.d.ts +365 -0
- package/dist/server.d.ts +234 -17
- package/dist/server.js +18 -2
- package/package.json +7 -4
- package/dist/chunk-L62WG2VU.js +0 -131
- package/dist/chunk-W6D2D767.js +0 -1410
- package/dist/internal-CjcEyEsm.d.ts +0 -842
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { createRequire as __atumCreateRequire } from 'module'; const require = __atumCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
INTENT_ID_META_KEY,
|
|
4
|
+
METHOD_NAME,
|
|
5
|
+
__toESM,
|
|
6
|
+
assetIdentifier,
|
|
7
|
+
atumEscrowChargeMethod,
|
|
8
|
+
chargeRequestId,
|
|
9
|
+
contractOverridesFromExtra,
|
|
10
|
+
import_payment_request_sender_auth,
|
|
11
|
+
intentIdOf,
|
|
12
|
+
namespaceOf,
|
|
13
|
+
require_dist2 as require_dist,
|
|
14
|
+
sameAddress
|
|
15
|
+
} from "./chunk-Z3AUNEU5.js";
|
|
16
|
+
|
|
17
|
+
// src/server.ts
|
|
18
|
+
var import_payment_request_sender_auth2 = __toESM(require_dist(), 1);
|
|
19
|
+
import { Errors as Errors2, Method } from "mppx";
|
|
20
|
+
|
|
21
|
+
// src/errors.ts
|
|
22
|
+
import { Errors } from "mppx";
|
|
23
|
+
function hasMarker(err, marker) {
|
|
24
|
+
return typeof err === "object" && err !== null && err[marker] === true;
|
|
25
|
+
}
|
|
26
|
+
function isSettlementPending(err) {
|
|
27
|
+
return hasMarker(err, "isSettlementPending");
|
|
28
|
+
}
|
|
29
|
+
function isSettlementFailed(err) {
|
|
30
|
+
return hasMarker(err, "isSettlementFailed");
|
|
31
|
+
}
|
|
32
|
+
function isPaymentRejected(err) {
|
|
33
|
+
return hasMarker(err, "isPaymentRejected");
|
|
34
|
+
}
|
|
35
|
+
var SettlementPendingError = class extends Errors.PaymentActionRequiredError {
|
|
36
|
+
/** Discriminant; test it with {@link isSettlementPending}. */
|
|
37
|
+
isSettlementPending = true;
|
|
38
|
+
paymentId;
|
|
39
|
+
constructor(options = {}) {
|
|
40
|
+
super({
|
|
41
|
+
reason: "the payment is still settling" + (options.paymentId ? ` (payment ${options.paymentId})` : "") + "; re-attempt the purchase to collect the result \u2014 request a fresh challenge and sign it again, keeping the SAME intent id, and it resolves onto this payment rather than charging again. Do not re-present the credential already signed: its deadlines are fixed"
|
|
42
|
+
});
|
|
43
|
+
this.paymentId = options.paymentId;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Adds `paymentId` as its own field, not just interpolated into `detail`'s prose. A merchant
|
|
47
|
+
* catching this in-process already has `.paymentId`; a real cross-network payer only ever
|
|
48
|
+
* sees this JSON body, and without a dedicated field would have to parse it out of a sentence
|
|
49
|
+
* to reconcile the attempt against the gateway. The return type is declared (not left to
|
|
50
|
+
* inference) so a TypeScript merchant that re-serializes through the base type still sees
|
|
51
|
+
* `paymentId` in intellisense.
|
|
52
|
+
*/
|
|
53
|
+
toProblemDetails(challengeId) {
|
|
54
|
+
return {
|
|
55
|
+
...super.toProblemDetails(challengeId),
|
|
56
|
+
...this.paymentId !== void 0 ? { paymentId: this.paymentId } : {}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
var SettlementFailedError = class extends Errors.VerificationFailedError {
|
|
61
|
+
/** Discriminant; test it with {@link isSettlementFailed}. */
|
|
62
|
+
isSettlementFailed = true;
|
|
63
|
+
paymentId;
|
|
64
|
+
/** The terminal state the gateway reported. */
|
|
65
|
+
state;
|
|
66
|
+
constructor(options) {
|
|
67
|
+
super({
|
|
68
|
+
reason: `the payment ${options.state}` + (options.paymentId ? ` (payment ${options.paymentId})` : "") + "; retrying this purchase resolves to the same failed payment, so recovering requires a new purchase under a new identifier"
|
|
69
|
+
});
|
|
70
|
+
this.paymentId = options.paymentId;
|
|
71
|
+
this.state = options.state;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Adds `paymentId` and `state` as their own fields, not just interpolated into `detail`'s
|
|
75
|
+
* prose — see {@link SettlementPendingError.toProblemDetails} for why a payer needs this on
|
|
76
|
+
* the wire, not only a same-process merchant. Return type declared for the same reason: so a
|
|
77
|
+
* TypeScript merchant sees `paymentId`/`state` in intellisense, not only at runtime.
|
|
78
|
+
*/
|
|
79
|
+
toProblemDetails(challengeId) {
|
|
80
|
+
return {
|
|
81
|
+
...super.toProblemDetails(challengeId),
|
|
82
|
+
...this.paymentId !== void 0 ? { paymentId: this.paymentId } : {},
|
|
83
|
+
state: this.state
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
var PaymentRejectedError = class extends Errors.BadRequestError {
|
|
88
|
+
/** Discriminant; test it with {@link isPaymentRejected}. */
|
|
89
|
+
isPaymentRejected = true;
|
|
90
|
+
/** The gateway's error code, for programmatic handling. */
|
|
91
|
+
code;
|
|
92
|
+
constructor(options) {
|
|
93
|
+
super({ reason: `${options.detail} (${options.code})` });
|
|
94
|
+
this.code = options.code;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// src/server.ts
|
|
99
|
+
var DEADLINE_SKEW_TOLERANCE_MS = 6e4;
|
|
100
|
+
var SOLANA_MAX_FULFILLMENT_DEADLINE_SECONDS = import_payment_request_sender_auth2.REPLAY_HORIZON_SECS - 10;
|
|
101
|
+
function registerServer(config) {
|
|
102
|
+
const now = config.now ?? (() => Date.now());
|
|
103
|
+
return Method.toServer(atumEscrowChargeMethod, {
|
|
104
|
+
async verify({ credential, request }) {
|
|
105
|
+
const pr = credential.payload.paymentRequest;
|
|
106
|
+
const { source, extra } = request;
|
|
107
|
+
const namespace = namespaceOf(source.network);
|
|
108
|
+
const senderAuth = pr.sender_auth;
|
|
109
|
+
if (!senderAuth || senderAuth.signed_messages.length === 0) {
|
|
110
|
+
throw new Error("atum-escrow: credential is missing sender_auth");
|
|
111
|
+
}
|
|
112
|
+
const signed = senderAuth.signed_messages[0];
|
|
113
|
+
if (!signed.message_prehash) {
|
|
114
|
+
throw new Error("atum-escrow: sender_auth is missing message_prehash");
|
|
115
|
+
}
|
|
116
|
+
if (!pr.source) {
|
|
117
|
+
throw new Error("atum-escrow: credential is missing a source");
|
|
118
|
+
}
|
|
119
|
+
const maxSourceStr = pr.max_source_amount ?? "0";
|
|
120
|
+
const cap = BigInt(source.amount);
|
|
121
|
+
if (BigInt(maxSourceStr) > cap) {
|
|
122
|
+
throw new Error("atum-escrow: max_source_amount exceeds the source cap");
|
|
123
|
+
}
|
|
124
|
+
const authTerms = (0, import_payment_request_sender_auth2.getChainAdapter)(source.network).recoverAndVerify(
|
|
125
|
+
signed,
|
|
126
|
+
{ network: source.network, asset: source.asset, account: pr.source.account },
|
|
127
|
+
{
|
|
128
|
+
maxSourceAmount: maxSourceStr,
|
|
129
|
+
escrowContract: extra.escrow,
|
|
130
|
+
reserver: extra.reserver,
|
|
131
|
+
releaser: extra.releaser,
|
|
132
|
+
svmSignatureClusterId: extra.svmSignatureClusterId,
|
|
133
|
+
svmSignatureDomainVersion: extra.svmSignatureDomainVersion,
|
|
134
|
+
// Check permit freshness against the merchant's own clock (the same `now` used for
|
|
135
|
+
// deadline ordering/budgets), not the SDK's wall clock — so freshness is consistent
|
|
136
|
+
// with the rest of verify and deterministic under an injected clock.
|
|
137
|
+
nowSec: Math.floor(now() / 1e3)
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
const intentId = intentIdOf(credential.challenge);
|
|
141
|
+
if (intentId === void 0) {
|
|
142
|
+
throw new Error(
|
|
143
|
+
`atum-escrow: the challenge carries no '${INTENT_ID_META_KEY}' metadata, so this payment cannot be de-duplicated and is refused`
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
if (pr.request_id !== chargeRequestId(intentId, pr.source.account)) {
|
|
147
|
+
throw new Error(
|
|
148
|
+
"atum-escrow: request_id is not derived from the challenge's purchase identifier, so a retry of this payment would not de-duplicate"
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const dest = pr.destination?.[0];
|
|
152
|
+
if (!dest) {
|
|
153
|
+
throw new Error("atum-escrow: credential is missing a destination");
|
|
154
|
+
}
|
|
155
|
+
if (!sameAddress(dest.account, extra.destination.address)) {
|
|
156
|
+
throw new Error("atum-escrow: destination account does not match the challenge");
|
|
157
|
+
}
|
|
158
|
+
const expectedDestAsset = assetIdentifier(extra.destination.network, extra.destination.asset);
|
|
159
|
+
const destAssetMatches = namespaceOf(extra.destination.network) === "solana" ? dest.asset_identifier === expectedDestAsset : dest.asset_identifier.toLowerCase() === expectedDestAsset.toLowerCase();
|
|
160
|
+
if (!destAssetMatches) {
|
|
161
|
+
throw new Error("atum-escrow: destination asset does not match the challenge");
|
|
162
|
+
}
|
|
163
|
+
if (pr.fulfillment_amount !== extra.fulfillmentAmount) {
|
|
164
|
+
throw new Error("atum-escrow: fulfillment_amount does not match the challenge");
|
|
165
|
+
}
|
|
166
|
+
const overrides = contractOverridesFromExtra(source.network, extra);
|
|
167
|
+
const expectedQuoteSelector = overrides?.quote_selector ?? extra.reserver;
|
|
168
|
+
const expectedVerifier = overrides?.fulfillment_verifier ?? {
|
|
169
|
+
account: extra.releaser,
|
|
170
|
+
endpoint: extra.fulfillmentVerifierEndpoint
|
|
171
|
+
};
|
|
172
|
+
if (!sameAddress(pr.escrow_contract_address ?? "", extra.escrow)) {
|
|
173
|
+
throw new Error("atum-escrow: escrow_contract_address does not match the challenge");
|
|
174
|
+
}
|
|
175
|
+
if (!sameAddress(pr.quote_selector ?? "", expectedQuoteSelector)) {
|
|
176
|
+
throw new Error("atum-escrow: quote_selector does not match the challenge reserver");
|
|
177
|
+
}
|
|
178
|
+
if (!sameAddress(pr.fulfillment_proxy ?? "", extra.fulfillmentProxy)) {
|
|
179
|
+
throw new Error("atum-escrow: fulfillment_proxy does not match the challenge");
|
|
180
|
+
}
|
|
181
|
+
if (!sameAddress(pr.fulfillment_verifier?.account ?? "", expectedVerifier.account)) {
|
|
182
|
+
throw new Error("atum-escrow: fulfillment_verifier.account does not match the challenge releaser");
|
|
183
|
+
}
|
|
184
|
+
if ((pr.fulfillment_verifier?.endpoint ?? "") !== expectedVerifier.endpoint) {
|
|
185
|
+
throw new Error("atum-escrow: fulfillment_verifier.endpoint does not match the challenge");
|
|
186
|
+
}
|
|
187
|
+
const nowMs = now();
|
|
188
|
+
const quote = Date.parse(pr.quote_deadline);
|
|
189
|
+
const fulfillment = Date.parse(pr.fulfillment_deadline);
|
|
190
|
+
if (!(quote < fulfillment)) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
"atum-escrow: quote_deadline must be before fulfillment_deadline (quote collection has to close before settlement is due)"
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
if (!(nowMs < quote)) {
|
|
196
|
+
throw new Errors2.PaymentActionRequiredError({
|
|
197
|
+
reason: "this authorization's quote window has already closed (quote_deadline is in the past), so it cannot start a payment. To re-attempt a purchase, request a fresh challenge and sign it again, keeping the SAME intent id \u2014 the re-attempt then resolves onto the payment already in flight instead of taking a second one. A stored credential cannot be re-presented: its deadlines are fixed at the moment it was signed"
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
if (quote > nowMs + extra.quoteDeadlineSeconds * 1e3 + DEADLINE_SKEW_TOLERANCE_MS) {
|
|
201
|
+
throw new Error("atum-escrow: quote_deadline exceeds the advertised budget");
|
|
202
|
+
}
|
|
203
|
+
if (fulfillment > nowMs + extra.fulfillmentDeadlineSeconds * 1e3 + DEADLINE_SKEW_TOLERANCE_MS) {
|
|
204
|
+
throw new Error("atum-escrow: fulfillment_deadline exceeds the advertised budget");
|
|
205
|
+
}
|
|
206
|
+
if (namespace !== "solana" && authTerms.deadlineSec * 1e3 < fulfillment) {
|
|
207
|
+
throw new Error("atum-escrow: permit deadline expires before fulfillment_deadline");
|
|
208
|
+
}
|
|
209
|
+
const result = await config.submitter.submit(pr);
|
|
210
|
+
const fc = result.fulfillment_confirmation;
|
|
211
|
+
if (!fc) {
|
|
212
|
+
const terminal = result.status === "failed" || result.status === "cancelled";
|
|
213
|
+
if (terminal) {
|
|
214
|
+
throw new SettlementFailedError({ paymentId: result.payment_id, state: result.status });
|
|
215
|
+
}
|
|
216
|
+
throw new SettlementPendingError({ paymentId: result.payment_id });
|
|
217
|
+
}
|
|
218
|
+
return {
|
|
219
|
+
method: METHOD_NAME,
|
|
220
|
+
status: "success",
|
|
221
|
+
timestamp: fc.fulfillment_timestamp ?? new Date(nowMs).toISOString(),
|
|
222
|
+
reference: fc.destination_tx_hash,
|
|
223
|
+
fulfillmentConfirmation: fc
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function applyMarkupBps(amount, bps) {
|
|
229
|
+
return (BigInt(amount) * BigInt(1e4 + bps) / 10000n).toString();
|
|
230
|
+
}
|
|
231
|
+
function validateCorridor(corridor) {
|
|
232
|
+
if (!Number.isFinite(corridor.quoteDeadlineSeconds) || corridor.quoteDeadlineSeconds <= 0) {
|
|
233
|
+
throw new Error("atum-escrow: quoteDeadlineSeconds must be a positive number of seconds");
|
|
234
|
+
}
|
|
235
|
+
if (!Number.isFinite(corridor.fulfillmentDeadlineSeconds) || corridor.fulfillmentDeadlineSeconds <= 0) {
|
|
236
|
+
throw new Error("atum-escrow: fulfillmentDeadlineSeconds must be a positive number of seconds");
|
|
237
|
+
}
|
|
238
|
+
if (corridor.quoteDeadlineSeconds >= corridor.fulfillmentDeadlineSeconds) {
|
|
239
|
+
throw new Error(
|
|
240
|
+
"atum-escrow: quoteDeadlineSeconds must be strictly less than fulfillmentDeadlineSeconds"
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (!Number.isFinite(corridor.markupBps) || corridor.markupBps < 0) {
|
|
244
|
+
throw new Error("atum-escrow: markupBps must be a non-negative number of basis points");
|
|
245
|
+
}
|
|
246
|
+
if (!corridor.sources || corridor.sources.length === 0) {
|
|
247
|
+
throw new Error("atum-escrow: corridor must configure at least one source");
|
|
248
|
+
}
|
|
249
|
+
for (const src of corridor.sources) {
|
|
250
|
+
for (const field of ["network", "escrow", "reserver", "releaser", "fulfillmentVerifierEndpoint"]) {
|
|
251
|
+
if (!src[field]) {
|
|
252
|
+
throw new Error(`atum-escrow: source ${src.network ?? "?"} is missing '${field}'`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (!src.assets || src.assets.length === 0 || src.assets.some((a) => !a)) {
|
|
256
|
+
throw new Error(`atum-escrow: source ${src.network} must list at least one non-empty asset in 'assets'`);
|
|
257
|
+
}
|
|
258
|
+
if (namespaceOf(src.network) === "tron") {
|
|
259
|
+
(0, import_payment_request_sender_auth.resolveTronPermit2)(src.network);
|
|
260
|
+
}
|
|
261
|
+
if (namespaceOf(src.network) === "solana") {
|
|
262
|
+
if (!src.svmSignatureClusterId || src.svmSignatureDomainVersion == null) {
|
|
263
|
+
throw new Error(
|
|
264
|
+
`atum-escrow: Solana source ${src.network} requires svmSignatureClusterId and svmSignatureDomainVersion`
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
if (corridor.fulfillmentDeadlineSeconds > SOLANA_MAX_FULFILLMENT_DEADLINE_SECONDS) {
|
|
268
|
+
throw new Error(
|
|
269
|
+
`atum-escrow: a corridor with a Solana source must set fulfillmentDeadlineSeconds <= ${SOLANA_MAX_FULFILLMENT_DEADLINE_SECONDS} (Solana deposits expire within the escrow replay window); got ${corridor.fulfillmentDeadlineSeconds}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
function buildChargeRequest(corridor, select, fulfillmentAmount, options) {
|
|
276
|
+
validateCorridor(corridor);
|
|
277
|
+
const src = corridor.sources.find(
|
|
278
|
+
(s) => s.network === select.network && s.assets.some((a) => sameAddress(a, select.asset))
|
|
279
|
+
);
|
|
280
|
+
if (!src) {
|
|
281
|
+
throw new Error(
|
|
282
|
+
`atum-escrow: no source option configured for ${select.network} / ${select.asset}`
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
const selectedAsset = src.assets.find((a) => sameAddress(a, select.asset));
|
|
286
|
+
const isSolana = namespaceOf(src.network) === "solana";
|
|
287
|
+
if (isSolana && options?.issuedAt !== void 0 && !/^[0-9]+$/.test(options.issuedAt)) {
|
|
288
|
+
throw new Error(
|
|
289
|
+
`atum-escrow: issuedAt must be epoch seconds (digits only), got '${options.issuedAt}'`
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
source: {
|
|
294
|
+
network: src.network,
|
|
295
|
+
asset: selectedAsset,
|
|
296
|
+
amount: applyMarkupBps(fulfillmentAmount, corridor.markupBps)
|
|
297
|
+
},
|
|
298
|
+
extra: {
|
|
299
|
+
// The corridor config carries the receive side as `account`; the wire `extra` names it
|
|
300
|
+
// `address` (the x402 scheme field), so map it here.
|
|
301
|
+
destination: {
|
|
302
|
+
network: corridor.destination.network,
|
|
303
|
+
asset: corridor.destination.asset,
|
|
304
|
+
address: corridor.destination.account
|
|
305
|
+
},
|
|
306
|
+
fulfillmentAmount,
|
|
307
|
+
escrow: src.escrow,
|
|
308
|
+
fulfillmentProxy: corridor.fulfillmentProxy,
|
|
309
|
+
reserver: src.reserver,
|
|
310
|
+
releaser: src.releaser,
|
|
311
|
+
fulfillmentVerifierEndpoint: src.fulfillmentVerifierEndpoint,
|
|
312
|
+
quoteDeadlineSeconds: corridor.quoteDeadlineSeconds,
|
|
313
|
+
fulfillmentDeadlineSeconds: corridor.fulfillmentDeadlineSeconds,
|
|
314
|
+
...src.svmSignatureClusterId ? { svmSignatureClusterId: src.svmSignatureClusterId } : {},
|
|
315
|
+
...src.svmSignatureDomainVersion != null ? { svmSignatureDomainVersion: src.svmSignatureDomainVersion } : {},
|
|
316
|
+
...isSolana && options?.issuedAt ? { issuedAt: options.issuedAt } : {}
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
function buildChargeChallenge(corridor, select, fulfillmentAmount, options) {
|
|
321
|
+
if (typeof options.intentId !== "string" || options.intentId === "") {
|
|
322
|
+
throw new Error(
|
|
323
|
+
"atum-escrow: intentId must be a non-empty per-purchase identifier (e.g. an order id); the payer derives the payment's identity from it, so without one a retry would be charged as a second payment"
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
return {
|
|
327
|
+
request: buildChargeRequest(corridor, select, fulfillmentAmount, options),
|
|
328
|
+
meta: { [INTENT_ID_META_KEY]: options.intentId }
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
async function corridorFromDefaults(defaults, params) {
|
|
332
|
+
const [destDefaults, ...sourceDefaults] = await Promise.all([
|
|
333
|
+
defaults.fetchChainDefaults(params.destination.network),
|
|
334
|
+
...params.sources.map((s) => defaults.fetchChainDefaults(s.network))
|
|
335
|
+
]);
|
|
336
|
+
const sources = params.sources.map((s, i) => {
|
|
337
|
+
const d = sourceDefaults[i];
|
|
338
|
+
return {
|
|
339
|
+
network: s.network,
|
|
340
|
+
assets: s.assets,
|
|
341
|
+
escrow: d.escrowContract,
|
|
342
|
+
reserver: d.quoteSelector,
|
|
343
|
+
releaser: d.fulfillmentVerifierAccount,
|
|
344
|
+
fulfillmentVerifierEndpoint: d.fulfillmentVerifierEndpoint,
|
|
345
|
+
...d.svmSignatureClusterId ? { svmSignatureClusterId: d.svmSignatureClusterId } : {},
|
|
346
|
+
...d.svmSignatureDomainVersion != null ? { svmSignatureDomainVersion: d.svmSignatureDomainVersion } : {}
|
|
347
|
+
};
|
|
348
|
+
});
|
|
349
|
+
return {
|
|
350
|
+
destination: params.destination,
|
|
351
|
+
fulfillmentProxy: destDefaults.fulfillmentProxy,
|
|
352
|
+
markupBps: params.markupBps,
|
|
353
|
+
quoteDeadlineSeconds: params.quoteDeadlineSeconds,
|
|
354
|
+
fulfillmentDeadlineSeconds: params.fulfillmentDeadlineSeconds,
|
|
355
|
+
sources
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
export {
|
|
360
|
+
isSettlementPending,
|
|
361
|
+
isSettlementFailed,
|
|
362
|
+
isPaymentRejected,
|
|
363
|
+
SettlementPendingError,
|
|
364
|
+
SettlementFailedError,
|
|
365
|
+
PaymentRejectedError,
|
|
366
|
+
registerServer,
|
|
367
|
+
validateCorridor,
|
|
368
|
+
buildChargeRequest,
|
|
369
|
+
buildChargeChallenge,
|
|
370
|
+
corridorFromDefaults
|
|
371
|
+
};
|