@atumlabs/mppx-atum-escrow 0.2.2 → 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/dist/client.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as zod_v4_core from 'zod/v4/core';
2
2
  import * as z from 'zod/mini';
3
3
  import { Signer } from 'ethers';
4
- import { S as SenderSigner, f as SenderSignerOptions, h as SolanaClusterUnixTimeReader } from './internal-DzEGXm14.js';
5
- export { A as AtumEscrowChallenge, a as AtumEscrowCredential, C as ChargeCredentialPayload, c as ChargeRequest, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, M as METHOD_NAME, g as atumEscrowChargeMethod } from './internal-DzEGXm14.js';
4
+ import { S as SenderSigner, g as SenderSignerOptions, i as SolanaClusterUnixTimeReader } from './internal-9tB7y-A7.js';
5
+ export { A as AtumEscrowChallenge, a as AtumEscrowCredential, C as ChargeCredentialPayload, c as ChargeRequest, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, f as INTENT_ID_META_KEY, M as METHOD_NAME, h as atumEscrowChargeMethod } from './internal-9tB7y-A7.js';
6
6
  import { Method } from 'mppx';
7
7
  export { PaymentRequest } from './generated/index.js';
8
8
 
@@ -38,16 +38,18 @@ interface AtumEscrowClientConfig {
38
38
  * built through the payment-gateway client's request builder, so the same call handles
39
39
  * EVM, Tron, and Solana sources.
40
40
  *
41
- * Idempotency: for EVM and Tron sources the deposit nonce (and the `request_id`) are
42
- * derived deterministically from the challenge id, so even if a caller rebuilds the
43
- * credential for the same challenge the escrow admits at most one deposit — the reused
44
- * nonce reverts the second on-chain. This holds only when the merchant issues a stable,
45
- * per-intent challenge id: set `opaque` to a per-payment identifier (e.g. an order id),
46
- * reused on retry of that intent, and keep `expires` stable or absent per intent (both feed
47
- * the challenge-id HMAC). Solana sources use a replay-window nonce rather than a
48
- * deterministic one and rely on the gateway's content-keyed dedup (the request id, and
49
- * thus the payment id, are still derived deterministically from the challenge id).
50
- * Building once and resubmitting the identical bytes remains the simplest safe pattern.
41
+ * Idempotency: the `request_id` is derived from the challenge's per-intent identifier (see
42
+ * {@link INTENT_ID_META_KEY}) via the shared sender_auth SDK, and `preparePaymentRequest` then
43
+ * derives the deposit nonce from that `request_id` on every chain. So rebuilding the credential
44
+ * for the same purchase reproduces the same payment identity, and the gateway de-duplicates the
45
+ * retry onto the original payment instead of charging twice. On EVM/Tron the reused Permit2
46
+ * nonce is a second, on-chain backstop (the duplicate deposit reverts); on Solana the replay
47
+ * nonce only guards a ~128s window, so there the gateway's `request_id` dedup is the durable
48
+ * protection.
49
+ *
50
+ * A challenge that carries no such identifier cannot be paid safely, so this client refuses it
51
+ * rather than falling back to something per-attempt. See
52
+ * {@link ../server!buildChargeChallenge | buildChargeChallenge} for the merchant side.
51
53
  *
52
54
  * @param config - the payer's signer, source account, and options.
53
55
  */
package/dist/client.js CHANGED
@@ -8,18 +8,20 @@ import { createRequire as __atumCreateRequire } from 'module'; const require = _
8
8
  import {
9
9
  ensureSourceApproval,
10
10
  registerClient
11
- } from "./chunk-IPZJXELQ.js";
11
+ } from "./chunk-ZFA5SSUP.js";
12
12
  import {
13
13
  ChargeRequestSchema,
14
14
  CredentialPayloadSchema,
15
15
  INTENT,
16
+ INTENT_ID_META_KEY,
16
17
  METHOD_NAME,
17
18
  atumEscrowChargeMethod
18
- } from "./chunk-4P34CLTO.js";
19
+ } from "./chunk-Z3AUNEU5.js";
19
20
  export {
20
21
  ChargeRequestSchema,
21
22
  CredentialPayloadSchema,
22
23
  INTENT,
24
+ INTENT_ID_META_KEY,
23
25
  METHOD_NAME,
24
26
  atumEscrowChargeMethod,
25
27
  ensureSourceApproval,
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- export { A as AtumEscrowChallenge, a as AtumEscrowCredential, b as AtumEscrowRequest, C as ChargeCredentialPayload, c as ChargeRequest, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, M as METHOD_NAME, S as SenderSigner, f as SenderSignerOptions, g as atumEscrowChargeMethod } from './internal-DzEGXm14.js';
1
+ export { A as AtumEscrowChallenge, a as AtumEscrowCredential, b as AtumEscrowRequest, C as ChargeCredentialPayload, c as ChargeRequest, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, f as INTENT_ID_META_KEY, M as METHOD_NAME, S as SenderSigner, g as SenderSignerOptions, h as atumEscrowChargeMethod } from './internal-9tB7y-A7.js';
2
2
  export { AtumEscrowClientConfig, EnsureApprovalResult, ensureSourceApproval, registerClient } from './client.js';
3
- export { AtumEscrowCorridor, AtumEscrowReceipt, AtumEscrowServerConfig, AtumEscrowSource, ChainDefaultsSource, FulfillmentConfirmation, PaymentSubmitter, buildChargeRequest, corridorFromDefaults, registerServer, validateCorridor } from './server.js';
3
+ export { AtumEscrowCorridor, AtumEscrowReceipt, AtumEscrowServerConfig, AtumEscrowSource, ChainDefaultsSource, ChargeChallenge, FulfillmentConfirmation, PaymentRejectedError, PaymentSettlementStatus, PaymentSubmitResult, PaymentSubmitter, SettlementErrorDetails, SettlementFailedError, SettlementPendingError, buildChargeChallenge, buildChargeRequest, corridorFromDefaults, isPaymentRejected, isSettlementFailed, isSettlementPending, registerServer, validateCorridor } from './server.js';
4
4
  export { PaymentRequest } from './generated/index.js';
5
5
  import 'zod/mini';
6
6
  import 'mppx';
package/dist/index.js CHANGED
@@ -8,29 +8,45 @@ import { createRequire as __atumCreateRequire } from 'module'; const require = _
8
8
  import {
9
9
  ensureSourceApproval,
10
10
  registerClient
11
- } from "./chunk-IPZJXELQ.js";
11
+ } from "./chunk-ZFA5SSUP.js";
12
12
  import {
13
+ PaymentRejectedError,
14
+ SettlementFailedError,
15
+ SettlementPendingError,
16
+ buildChargeChallenge,
13
17
  buildChargeRequest,
14
18
  corridorFromDefaults,
19
+ isPaymentRejected,
20
+ isSettlementFailed,
21
+ isSettlementPending,
15
22
  registerServer,
16
23
  validateCorridor
17
- } from "./chunk-NEM3HEZW.js";
24
+ } from "./chunk-4YD6566T.js";
18
25
  import {
19
26
  ChargeRequestSchema,
20
27
  CredentialPayloadSchema,
21
28
  INTENT,
29
+ INTENT_ID_META_KEY,
22
30
  METHOD_NAME,
23
31
  atumEscrowChargeMethod
24
- } from "./chunk-4P34CLTO.js";
32
+ } from "./chunk-Z3AUNEU5.js";
25
33
  export {
26
34
  ChargeRequestSchema,
27
35
  CredentialPayloadSchema,
28
36
  INTENT,
37
+ INTENT_ID_META_KEY,
29
38
  METHOD_NAME,
39
+ PaymentRejectedError,
40
+ SettlementFailedError,
41
+ SettlementPendingError,
30
42
  atumEscrowChargeMethod,
43
+ buildChargeChallenge,
31
44
  buildChargeRequest,
32
45
  corridorFromDefaults,
33
46
  ensureSourceApproval,
47
+ isPaymentRejected,
48
+ isSettlementFailed,
49
+ isSettlementPending,
34
50
  registerClient,
35
51
  registerServer,
36
52
  validateCorridor
@@ -245,6 +245,24 @@ interface AtumEscrowExtra {
245
245
  declare const METHOD_NAME = "atum-escrow";
246
246
  /** The MPP intent this method implements. */
247
247
  declare const INTENT = "charge";
248
+ /**
249
+ * Challenge-metadata key carrying the merchant's per-intent payment identifier.
250
+ *
251
+ * The payer derives the payment's `request_id` from this value, and the gateway
252
+ * de-duplicates on that `request_id`. So the key's lifetime defines what counts as "the same
253
+ * payment": one value per thing being bought, reused on every retry of that purchase, never
254
+ * shared between two purchases.
255
+ *
256
+ * It rides in challenge metadata rather than in the charge request because it identifies the
257
+ * purchase, not its terms — two sequential orders for the same item have identical terms and
258
+ * must still be two payments. Metadata is covered by the challenge-id HMAC, so a payer cannot
259
+ * substitute another intent's identifier to have a second purchase resolve onto an
260
+ * already-settled payment.
261
+ *
262
+ * Prefixed to keep it distinct from a merchant's own metadata and from the framework's
263
+ * reserved keys.
264
+ */
265
+ declare const INTENT_ID_META_KEY = "atumIntentId";
248
266
  /**
249
267
  * Schema for the `charge` challenge request — the method-specific data a merchant
250
268
  * publishes in an MPP `402` challenge. It describes what the merchant receives and the
@@ -344,4 +362,4 @@ declare const atumEscrowChargeMethod: {
344
362
  };
345
363
  };
346
364
 
347
- export { type AtumEscrowChallenge as A, type ChargeCredentialPayload as C, INTENT as I, METHOD_NAME as M, type SenderSigner as S, type AtumEscrowCredential as a, type AtumEscrowRequest as b, type ChargeRequest as c, ChargeRequestSchema as d, CredentialPayloadSchema as e, type SenderSignerOptions as f, atumEscrowChargeMethod as g, type SolanaClusterUnixTimeReader as h, type ChainDefaults as i };
365
+ export { type AtumEscrowChallenge as A, type ChargeCredentialPayload as C, INTENT as I, METHOD_NAME as M, type SenderSigner as S, type AtumEscrowCredential as a, type AtumEscrowRequest as b, type ChargeRequest as c, ChargeRequestSchema as d, CredentialPayloadSchema as e, INTENT_ID_META_KEY as f, type SenderSignerOptions as g, atumEscrowChargeMethod as h, type SolanaClusterUnixTimeReader as i, type ChainDefaults as j };
package/dist/server.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import * as zod_v4_core from 'zod/v4/core';
2
2
  import * as z from 'zod/mini';
3
- import { i as ChainDefaults, c as ChargeRequest } from './internal-DzEGXm14.js';
4
- export { A as AtumEscrowChallenge, a as AtumEscrowCredential, C as ChargeCredentialPayload, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, M as METHOD_NAME, g as atumEscrowChargeMethod } from './internal-DzEGXm14.js';
5
- import { Receipt, Method } from 'mppx';
3
+ import { j as ChainDefaults, c as ChargeRequest } from './internal-9tB7y-A7.js';
4
+ export { A as AtumEscrowChallenge, a as AtumEscrowCredential, C as ChargeCredentialPayload, d as ChargeRequestSchema, e as CredentialPayloadSchema, I as INTENT, f as INTENT_ID_META_KEY, M as METHOD_NAME, h as atumEscrowChargeMethod } from './internal-9tB7y-A7.js';
5
+ import { Errors, Receipt, Method } from 'mppx';
6
6
  import { PaymentRequest } from './generated/index.js';
7
7
  export { PaymentRequest } from './generated/index.js';
8
8
 
@@ -53,6 +53,131 @@ interface FulfillmentConfirmation {
53
53
  destination_block_number?: number;
54
54
  }
55
55
 
56
+ /**
57
+ * Settlement outcomes that are not a receipt.
58
+ *
59
+ * MPP models a completed payment and nothing else: a receipt's status is the literal
60
+ * `"success"`, so a payment that has not settled cannot be expressed as one and has to leave
61
+ * `verify()` as a throw. What matters is that the two non-success outcomes stay
62
+ * distinguishable, because they call for opposite responses:
63
+ *
64
+ * - {@link SettlementPendingError} — the payment is still settling. Retrying the SAME purchase
65
+ * is safe and is how the payer collects the result: the identifier it derives from resolves to
66
+ * this same payment, so the gateway returns the original rather than charging again.
67
+ * - {@link SettlementFailedError} — the payment reached a terminal failure. Retrying the same
68
+ * purchase resolves to the dead payment forever, so recovering means starting a NEW purchase
69
+ * under a new identifier.
70
+ *
71
+ * Both carry the gateway's payment id when one was issued, so a merchant can reconcile the
72
+ * attempt against the gateway without parsing a message.
73
+ *
74
+ * Both extend the framework's error types, so a merchant that does not distinguish them still
75
+ * gets the standard `402` + problem-details response.
76
+ *
77
+ * @packageDocumentation
78
+ */
79
+
80
+ /** Fields shared by both settlement outcomes. */
81
+ interface SettlementErrorDetails {
82
+ /** The gateway's payment id, when the payment was accepted and given one. */
83
+ readonly paymentId: string | undefined;
84
+ }
85
+ /** True if the payment is still settling — a retry of the same purchase is safe. */
86
+ declare function isSettlementPending(err: unknown): err is SettlementPendingError;
87
+ /** True if the payment reached a terminal failure — the same purchase can never settle. */
88
+ declare function isSettlementFailed(err: unknown): err is SettlementFailedError;
89
+ /** True if the gateway refused the request outright — nothing was charged. */
90
+ declare function isPaymentRejected(err: unknown): err is PaymentRejectedError;
91
+ /**
92
+ * The payment was accepted but had not settled when the merchant's synchronous window closed.
93
+ *
94
+ * Not a failure: the payment is in flight. Re-attempting the same purchase is safe — it resolves to
95
+ * this payment and returns its result once settled.
96
+ *
97
+ * **What re-attempting means.** Run the purchase again: request a fresh challenge and sign it again,
98
+ * keeping the same intent id. The intent id is what makes the re-attempt resolve onto the payment
99
+ * already in flight rather than taking a second one, so it must not change — while everything
100
+ * time-bound about the authorization must, because the deadlines are absolute timestamps fixed when
101
+ * it was signed. A stored credential therefore cannot simply be presented a second time; once its
102
+ * quote window has closed it is refused, and on Solana the deposit authorization carries its own
103
+ * replay window that expires with it.
104
+ *
105
+ * A payment-enabled `fetch` does this for the caller, since each attempt fetches a new challenge.
106
+ * Code that drives the client directly has to rebuild.
107
+ */
108
+ declare class SettlementPendingError extends Errors.PaymentActionRequiredError implements SettlementErrorDetails {
109
+ /** Discriminant; test it with {@link isSettlementPending}. */
110
+ readonly isSettlementPending: true;
111
+ readonly paymentId: string | undefined;
112
+ constructor(options?: {
113
+ paymentId?: string | undefined;
114
+ });
115
+ /**
116
+ * Adds `paymentId` as its own field, not just interpolated into `detail`'s prose. A merchant
117
+ * catching this in-process already has `.paymentId`; a real cross-network payer only ever
118
+ * sees this JSON body, and without a dedicated field would have to parse it out of a sentence
119
+ * to reconcile the attempt against the gateway. The return type is declared (not left to
120
+ * inference) so a TypeScript merchant that re-serializes through the base type still sees
121
+ * `paymentId` in intellisense.
122
+ */
123
+ toProblemDetails(challengeId?: string): Errors.PaymentError.ProblemDetails & {
124
+ paymentId?: string;
125
+ };
126
+ }
127
+ /**
128
+ * The payment reached a terminal failure state and will not settle.
129
+ *
130
+ * A retry of the same purchase cannot recover it: that purchase's identifier now resolves to
131
+ * this failed payment. Recovering means a new purchase under a new identifier.
132
+ */
133
+ declare class SettlementFailedError extends Errors.VerificationFailedError implements SettlementErrorDetails {
134
+ /** Discriminant; test it with {@link isSettlementFailed}. */
135
+ readonly isSettlementFailed: true;
136
+ readonly paymentId: string | undefined;
137
+ /** The terminal state the gateway reported. */
138
+ readonly state: string;
139
+ constructor(options: {
140
+ paymentId?: string | undefined;
141
+ state: string;
142
+ });
143
+ /**
144
+ * Adds `paymentId` and `state` as their own fields, not just interpolated into `detail`'s
145
+ * prose — see {@link SettlementPendingError.toProblemDetails} for why a payer needs this on
146
+ * the wire, not only a same-process merchant. Return type declared for the same reason: so a
147
+ * TypeScript merchant sees `paymentId`/`state` in intellisense, not only at runtime.
148
+ */
149
+ toProblemDetails(challengeId?: string): Errors.PaymentError.ProblemDetails & {
150
+ paymentId?: string;
151
+ state: string;
152
+ };
153
+ }
154
+ /**
155
+ * The gateway refused the payment outright — it never entered settlement.
156
+ *
157
+ * Distinct from {@link SettlementFailedError}: nothing was charged and nothing is in flight, so
158
+ * the fault is in the request and fixing it makes the same purchase payable. The most common
159
+ * cause is reusing one purchase identifier for two different sets of terms, which the gateway
160
+ * rejects rather than silently resolving to the first payment.
161
+ *
162
+ * Thrown by a {@link ../server!PaymentSubmitter | PaymentSubmitter} — the submitter owns the
163
+ * gateway call, so it is the only place that can tell a refusal (the request was rejected) from
164
+ * a transport or server failure (the outcome is unknown, and reporting it as a refusal would
165
+ * invite a second payment). Classify on the response status rather than on the body, so an
166
+ * intermediary that rewrites the error payload cannot turn a refusal into an unknown outcome.
167
+ * Raising it preserves the gateway's error code through to the payer instead of flattening every
168
+ * cause into one generic verification failure.
169
+ */
170
+ declare class PaymentRejectedError extends Errors.BadRequestError {
171
+ /** Discriminant; test it with {@link isPaymentRejected}. */
172
+ readonly isPaymentRejected: true;
173
+ /** The gateway's error code, for programmatic handling. */
174
+ readonly code: string;
175
+ constructor(options: {
176
+ code: string;
177
+ detail: string;
178
+ });
179
+ }
180
+
56
181
  /** One source chain/token the merchant accepts payment from. */
57
182
  interface AtumEscrowSource {
58
183
  /** CAIP-2 source chain id (e.g. `eip155:8453`, `tron:mainnet`, `solana:<genesis>`). */
@@ -95,15 +220,37 @@ interface AtumEscrowCorridor {
95
220
  /** Accepted source options; selected per charge by `(network, asset)`. */
96
221
  sources: AtumEscrowSource[];
97
222
  }
223
+ /** Lifecycle state the gateway reports for a payment. */
224
+ type PaymentSettlementStatus = "pending" | "completed" | "failed" | "cancelled";
225
+ /** What a {@link PaymentSubmitter} resolves with. */
226
+ interface PaymentSubmitResult {
227
+ /** The gateway's payment id. Present whenever the payment was accepted. */
228
+ payment_id?: string;
229
+ /**
230
+ * The payment's state. When absent, an unsettled payment is treated as still in flight —
231
+ * the conservative reading, since calling an in-flight payment failed would tell the payer to
232
+ * start a second one.
233
+ */
234
+ status?: PaymentSettlementStatus;
235
+ /** The settlement confirmation, present once the payment has completed. */
236
+ fulfillment_confirmation?: FulfillmentConfirmation;
237
+ }
98
238
  /**
99
239
  * Submits a signed payment request to the Atum Payment Gateway and resolves with the
100
240
  * settlement result. Satisfied by an adapter over `@atum-labs/payment-gateway-client`.
241
+ *
242
+ * Submit and return what the gateway said; do not poll for completion inside the submitter.
243
+ * A payment that outlives the gateway's synchronous window surfaces to the payer as
244
+ * {@link SettlementPendingError}, and the payer's retry of the same purchase is what collects the
245
+ * result — the gateway resolves that retry to the same payment. Polling inside the submitter
246
+ * instead holds the merchant's request open for the full settlement window and hides the pending
247
+ * state that makes the retry safe.
248
+ *
249
+ * Throw {@link PaymentRejectedError} when the gateway refuses the request, so the refusal keeps
250
+ * its code. Any other throw is treated as an unknown outcome.
101
251
  */
102
252
  interface PaymentSubmitter {
103
- submit(request: PaymentRequest): Promise<{
104
- payment_id?: string;
105
- fulfillment_confirmation?: FulfillmentConfirmation;
106
- }>;
253
+ submit(request: PaymentRequest): Promise<PaymentSubmitResult>;
107
254
  }
108
255
  /** Configuration for the merchant side of the method. */
109
256
  interface AtumEscrowServerConfig {
@@ -182,10 +329,16 @@ declare function registerServer(config: AtumEscrowServerConfig): Method.Server<{
182
329
  */
183
330
  declare function validateCorridor(corridor: AtumEscrowCorridor): void;
184
331
  /**
185
- * Build the `charge` challenge request for a specific source option from a corridor. The
186
- * merchant uses this to construct the 402 challenge; the source cap is
187
- * `fulfillmentAmount + markup`, quoted in the source token. The corridor is validated
188
- * first, so a misconfiguration fails here rather than at signing time.
332
+ * Build the `charge` challenge request for a specific source option from a corridor — the
333
+ * payment terms alone. The source cap is `fulfillmentAmount + markup`, quoted in the source
334
+ * token. The corridor is validated first, so a misconfiguration fails here rather than at
335
+ * signing time.
336
+ *
337
+ * Prefer {@link buildChargeChallenge}, which pairs these terms with the per-purchase identifier
338
+ * the payer requires. A challenge built from this function alone carries no such identifier and
339
+ * the payer's client refuses it — at signing time, not at build time, so code that calls this
340
+ * directly and worked before only surfaces the problem when a real payer's client refuses the
341
+ * payment. Reach for it directly only when supplying the per-purchase metadata by hand.
189
342
  *
190
343
  * @param corridor - the corridor to serve.
191
344
  * @param select - which configured source to fund from, by `(network, asset)`.
@@ -205,6 +358,62 @@ declare function buildChargeRequest(corridor: AtumEscrowCorridor, select: {
205
358
  }, fulfillmentAmount: string, options?: {
206
359
  issuedAt?: string;
207
360
  }): ChargeRequest;
361
+ /**
362
+ * A charge challenge's two halves, ready to hand to the framework.
363
+ *
364
+ * They are separate because the framework keeps them separate: `request` is the
365
+ * method-specific payment terms, `meta` is challenge metadata. Both are covered by the
366
+ * challenge-id HMAC, but nesting the metadata inside the request would bury the purchase
367
+ * identifier in the terms blob where the payer does not look for it — so this type keeps them in
368
+ * the shape the framework expects.
369
+ */
370
+ interface ChargeChallenge {
371
+ /** The method-specific charge request (the payment terms). */
372
+ request: ChargeRequest;
373
+ /** Challenge metadata carrying the per-intent identifier. */
374
+ meta: Record<string, string>;
375
+ }
376
+ /**
377
+ * Build a charge challenge for a specific source option from a corridor.
378
+ *
379
+ * This is the entry point a merchant should use: it pairs the payment terms with the per-purchase
380
+ * identifier the payer needs to make the payment retry-safe. A challenge built without that
381
+ * identifier is refused by the payer's client rather than paid unsafely.
382
+ *
383
+ * Pass the result straight through to the framework:
384
+ *
385
+ * ```ts
386
+ * const { request, meta } = buildChargeChallenge(corridor, source, amount, { intentId: order.id })
387
+ *
388
+ * // Route-handler style:
389
+ * mppx.compose(['atum-escrow/charge', { ...request, meta }])(input)
390
+ *
391
+ * // Or building the challenge directly:
392
+ * Challenge.fromMethod(atumEscrowChargeMethod, { request, meta, realm, secretKey })
393
+ * ```
394
+ *
395
+ * @param corridor - the corridor to serve.
396
+ * @param select - which configured source to fund from, by `(network, asset)`.
397
+ * @param fulfillmentAmount - exact amount the merchant receives, atomic units of the
398
+ * destination token.
399
+ * @param options.intentId - identifies the thing being bought. Use the merchant's own order,
400
+ * invoice, or cart identifier: one value per purchase, the SAME value every time that purchase
401
+ * is re-offered or retried, and never shared between two purchases. The payer derives the
402
+ * payment's identity from it and the gateway de-duplicates on that, so its lifetime is what
403
+ * decides whether a retry is recognized (a value that changes per attempt causes a second
404
+ * charge) and whether two purchases stay distinct (a value shared between them leaves the
405
+ * second unpaid). Do not derive it from the terms: two orders for the same item have identical
406
+ * terms.
407
+ * @param options.issuedAt - Solana-source only; see {@link buildChargeRequest}.
408
+ * @throws if `intentId` is empty, or the corridor/source selection is invalid.
409
+ */
410
+ declare function buildChargeChallenge(corridor: AtumEscrowCorridor, select: {
411
+ network: string;
412
+ asset: string;
413
+ }, fulfillmentAmount: string, options: {
414
+ intentId: string;
415
+ issuedAt?: string;
416
+ }): ChargeChallenge;
208
417
  /** The minimal defaults source `corridorFromDefaults` needs; satisfied by the gateway client. */
209
418
  interface ChainDefaultsSource {
210
419
  fetchChainDefaults(chainId: string): Promise<ChainDefaults>;
@@ -235,4 +444,4 @@ declare function corridorFromDefaults(defaults: ChainDefaultsSource, params: {
235
444
  fulfillmentDeadlineSeconds: number;
236
445
  }): Promise<AtumEscrowCorridor>;
237
446
 
238
- export { type AtumEscrowCorridor, type AtumEscrowReceipt, type AtumEscrowServerConfig, type AtumEscrowSource, type ChainDefaultsSource, ChargeRequest, type FulfillmentConfirmation, type PaymentSubmitter, buildChargeRequest, corridorFromDefaults, registerServer, validateCorridor };
447
+ export { type AtumEscrowCorridor, type AtumEscrowReceipt, type AtumEscrowServerConfig, type AtumEscrowSource, type ChainDefaultsSource, type ChargeChallenge, ChargeRequest, type FulfillmentConfirmation, PaymentRejectedError, type PaymentSettlementStatus, type PaymentSubmitResult, type PaymentSubmitter, type SettlementErrorDetails, SettlementFailedError, SettlementPendingError, buildChargeChallenge, buildChargeRequest, corridorFromDefaults, isPaymentRejected, isSettlementFailed, isSettlementPending, registerServer, validateCorridor };
package/dist/server.js CHANGED
@@ -6,26 +6,42 @@
6
6
  */
7
7
  import { createRequire as __atumCreateRequire } from 'module'; const require = __atumCreateRequire(import.meta.url);
8
8
  import {
9
+ PaymentRejectedError,
10
+ SettlementFailedError,
11
+ SettlementPendingError,
12
+ buildChargeChallenge,
9
13
  buildChargeRequest,
10
14
  corridorFromDefaults,
15
+ isPaymentRejected,
16
+ isSettlementFailed,
17
+ isSettlementPending,
11
18
  registerServer,
12
19
  validateCorridor
13
- } from "./chunk-NEM3HEZW.js";
20
+ } from "./chunk-4YD6566T.js";
14
21
  import {
15
22
  ChargeRequestSchema,
16
23
  CredentialPayloadSchema,
17
24
  INTENT,
25
+ INTENT_ID_META_KEY,
18
26
  METHOD_NAME,
19
27
  atumEscrowChargeMethod
20
- } from "./chunk-4P34CLTO.js";
28
+ } from "./chunk-Z3AUNEU5.js";
21
29
  export {
22
30
  ChargeRequestSchema,
23
31
  CredentialPayloadSchema,
24
32
  INTENT,
33
+ INTENT_ID_META_KEY,
25
34
  METHOD_NAME,
35
+ PaymentRejectedError,
36
+ SettlementFailedError,
37
+ SettlementPendingError,
26
38
  atumEscrowChargeMethod,
39
+ buildChargeChallenge,
27
40
  buildChargeRequest,
28
41
  corridorFromDefaults,
42
+ isPaymentRejected,
43
+ isSettlementFailed,
44
+ isSettlementPending,
29
45
  registerServer,
30
46
  validateCorridor
31
47
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atumlabs/mppx-atum-escrow",
3
- "version": "0.2.2",
3
+ "version": "0.3.0",
4
4
  "description": "Atum cross-chain escrow payment method for the Machine Payments Protocol (MPP).",
5
5
  "author": "Atum Labs, Inc.",
6
6
  "license": "SEE LICENSE IN LICENSE",