@atumlabs/mppx-atum-escrow 0.1.1 → 0.2.2
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 +32 -0
- package/README.md +1 -1
- package/dist/chunk-4P34CLTO.js +2587 -0
- package/dist/{chunk-2MWWLU75.js → chunk-IPZJXELQ.js} +1396 -1528
- package/dist/chunk-NEM3HEZW.js +253 -0
- package/dist/client.d.ts +9 -6
- package/dist/client.js +2 -2
- package/dist/index.d.ts +18 -17
- package/dist/index.js +3 -3
- package/dist/internal-DzEGXm14.d.ts +347 -0
- package/dist/server.d.ts +16 -8
- package/dist/server.js +2 -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,347 @@
|
|
|
1
|
+
import * as z from 'zod/mini';
|
|
2
|
+
import { PaymentRequest } from './generated/index.js';
|
|
3
|
+
import { Challenge, Credential } from 'mppx';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* A message that has been cryptographically signed to prove authorization.
|
|
7
|
+
* The signature proves you control the wallet that's sending funds.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
type SignedMessage = {
|
|
11
|
+
/**
|
|
12
|
+
* The data that was signed. Format depends on the blockchain:
|
|
13
|
+
* - EVM: Hex-encoded message hash (with 0x prefix)
|
|
14
|
+
* - Solana: Base64 encoded message
|
|
15
|
+
* - Tron: Hex-encoded message hash (possibly without 0x prefix)
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
message: string;
|
|
19
|
+
/**
|
|
20
|
+
* Optional: If 'message' contains a hash, this field contains the original data
|
|
21
|
+
* before it was hashed. Useful for verification and debugging.
|
|
22
|
+
*
|
|
23
|
+
*/
|
|
24
|
+
message_prehash?: string;
|
|
25
|
+
/**
|
|
26
|
+
* The cryptographic signature proving you authorized this message.
|
|
27
|
+
* Format varies by blockchain (hex for EVM/Tron, base58 for Solana).
|
|
28
|
+
*
|
|
29
|
+
*/
|
|
30
|
+
signature: string;
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Chain defaults returned by the payment gateway /defaults endpoint.
|
|
35
|
+
*/
|
|
36
|
+
interface ChainDefaults {
|
|
37
|
+
escrowContract: string;
|
|
38
|
+
quoteSelector: string;
|
|
39
|
+
fulfillmentVerifierAccount: string;
|
|
40
|
+
fulfillmentVerifierEndpoint: string;
|
|
41
|
+
fulfillmentProxy: string;
|
|
42
|
+
permit2Contract?: string;
|
|
43
|
+
/**
|
|
44
|
+
* V3 Solana escrow domain-separation fields, surfaced by payment-gw
|
|
45
|
+
* `/defaults` for Solana source chains. Used to build the EscrowDomain that the
|
|
46
|
+
* V3 deposit hash binds to. Absent for EVM/Tron.
|
|
47
|
+
*/
|
|
48
|
+
svmSignatureClusterId?: string;
|
|
49
|
+
svmSignatureDomainVersion?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
interface Logger {
|
|
53
|
+
debug(obj: unknown, msg?: string): void;
|
|
54
|
+
info(obj: unknown, msg?: string): void;
|
|
55
|
+
warn(obj: unknown, msg?: string): void;
|
|
56
|
+
error(obj: unknown, msg?: string): void;
|
|
57
|
+
child(bindings: Record<string, unknown>): Logger;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface Counter {
|
|
61
|
+
add(value: number, attributes?: Record<string, unknown>): void;
|
|
62
|
+
}
|
|
63
|
+
interface Histogram {
|
|
64
|
+
record(value: number, attributes?: Record<string, unknown>): void;
|
|
65
|
+
}
|
|
66
|
+
interface InstrumentOptions {
|
|
67
|
+
description?: string;
|
|
68
|
+
unit?: string;
|
|
69
|
+
}
|
|
70
|
+
interface Meter {
|
|
71
|
+
createCounter(name: string, options?: InstrumentOptions): Counter;
|
|
72
|
+
createHistogram(name: string, options?: InstrumentOptions): Histogram;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Resolves the `issued_at` timestamp for a Solana deposit authorization from the
|
|
77
|
+
* cluster's on-chain clock instead of the local wall clock.
|
|
78
|
+
*
|
|
79
|
+
* The escrow validates `now_sec >= issued_at` against Solana's `Clock` sysvar
|
|
80
|
+
* (crates/replay/src/check.rs). That on-chain clock is global consensus and only
|
|
81
|
+
* moves forward, so a value read at build time is a safe lower bound at
|
|
82
|
+
* settlement, which removes the `Escrow_FutureTransaction` failure that a raw
|
|
83
|
+
* `Date.now()` (client wall clock, possibly ahead of the lagging cluster clock)
|
|
84
|
+
* can trigger.
|
|
85
|
+
*
|
|
86
|
+
* The read is best-effort: on any failure, timeout, or unresolved RPC it falls
|
|
87
|
+
* back to `Date.now()` minus a skew buffer, so a flaky public endpoint degrades
|
|
88
|
+
* to the previous behavior rather than blocking the payment.
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
/** Reads the cluster's on-chain unix timestamp (seconds) from an RPC endpoint. */
|
|
92
|
+
type SolanaClusterUnixTimeReader = (rpcUrl: string, timeoutMs: number) => Promise<bigint>;
|
|
93
|
+
|
|
94
|
+
/** Result of signing a sender_auth message. */
|
|
95
|
+
interface SenderSignature {
|
|
96
|
+
/** 0x-prefixed signature hex (65-byte secp256k1 for EVM/Tron, 64-byte ed25519 for Solana). */
|
|
97
|
+
signature: string;
|
|
98
|
+
/**
|
|
99
|
+
* base58 signer public key for non-recoverable schemes (Solana), attached to
|
|
100
|
+
* the signed message's payload.delegate_signer. Absent for EVM/Tron, whose
|
|
101
|
+
* secp256k1 signatures are recoverable.
|
|
102
|
+
*/
|
|
103
|
+
delegateSigner?: string;
|
|
104
|
+
}
|
|
105
|
+
/** Signs a single sender_auth signed message for a payment request. */
|
|
106
|
+
interface SenderSigner {
|
|
107
|
+
sign(signedMessage: SignedMessage): Promise<SenderSignature>;
|
|
108
|
+
}
|
|
109
|
+
/** Turnkey provider configuration (shared by the SDK and the CLI env loader). */
|
|
110
|
+
interface TurnkeyConfig {
|
|
111
|
+
organizationId: string;
|
|
112
|
+
walletId: string;
|
|
113
|
+
apiPublicKey: string;
|
|
114
|
+
apiPrivateKey: string;
|
|
115
|
+
/**
|
|
116
|
+
* Chain-native address the signer is expected to resolve to. Verified against
|
|
117
|
+
* the address Turnkey returns at initialize(); a mismatch fails fast rather
|
|
118
|
+
* than signing as the wrong depositor.
|
|
119
|
+
*/
|
|
120
|
+
pinnedAddress?: string;
|
|
121
|
+
/**
|
|
122
|
+
* Optional observability threaded to the Turnkey network path (default noop).
|
|
123
|
+
* SDK consumers can wire their own logger and meter; the CLI leaves them unset.
|
|
124
|
+
*/
|
|
125
|
+
logger?: Logger;
|
|
126
|
+
meter?: Meter;
|
|
127
|
+
}
|
|
128
|
+
/** Options selecting a sender-signing provider. Defaults to the private-key provider. */
|
|
129
|
+
type SenderSignerOptions = {
|
|
130
|
+
provider?: 'raw';
|
|
131
|
+
privateKey: string;
|
|
132
|
+
pinnedAddress?: string;
|
|
133
|
+
} | ({
|
|
134
|
+
provider: 'turnkey';
|
|
135
|
+
} & TurnkeyConfig);
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* This file was automatically generated by json-schema-to-typescript.
|
|
139
|
+
* DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file,
|
|
140
|
+
* and run json-schema-to-typescript to regenerate this file.
|
|
141
|
+
*/
|
|
142
|
+
/**
|
|
143
|
+
* The MPP `charge` challenge request — the method-specific `request` blob inside an mppx Challenge. It carries the source option the payer funds from plus the destination/corridor block (the reused `extra`). MPP has no x402 `accepts[]` envelope, so the source option that x402 carried at the `accepts[]` top level rides here alongside `extra`. One source option per challenge; a 402 may advertise several challenges to offer several source options.
|
|
144
|
+
*/
|
|
145
|
+
interface AtumEscrowRequest {
|
|
146
|
+
/**
|
|
147
|
+
* The source chain/token/cap the payer funds from.
|
|
148
|
+
*/
|
|
149
|
+
source: {
|
|
150
|
+
/**
|
|
151
|
+
* CAIP-2 source chain id (e.g. eip155:8453).
|
|
152
|
+
*/
|
|
153
|
+
network: string;
|
|
154
|
+
/**
|
|
155
|
+
* Source token address (EVM hex or base58, per the source chain).
|
|
156
|
+
*/
|
|
157
|
+
asset: string;
|
|
158
|
+
/**
|
|
159
|
+
* Source spend cap (fulfillmentAmount + markup), in atomic token units — the authoritative `max_source_amount` the payer signs.
|
|
160
|
+
*/
|
|
161
|
+
amount: string;
|
|
162
|
+
};
|
|
163
|
+
extra: AtumEscrowExtra;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* The `extra.atum` object carried inside an atum-escrow x402 PaymentRequirements entry (accepts[]): the merchant's receive-side plus the contract/role addresses and deadline budgets. Scheme-specific data the standard x402 `extra` bag treats as opaque, so it is owned here and shared by all role mechanisms. Addresses are chain-general: an EVM `0x`-hex address (20 bytes) or a base58-encoded address (Solana/Tron), per the field's CAIP-2 chain.
|
|
167
|
+
*/
|
|
168
|
+
interface AtumEscrowExtra {
|
|
169
|
+
/**
|
|
170
|
+
* Where the merchant receives (CAIP-2 chain, token, address).
|
|
171
|
+
*/
|
|
172
|
+
destination: {
|
|
173
|
+
/**
|
|
174
|
+
* CAIP-2 destination chain id (e.g. eip155:42161).
|
|
175
|
+
*/
|
|
176
|
+
network: string;
|
|
177
|
+
/**
|
|
178
|
+
* Destination token contract address (EVM hex or base58, per the destination chain).
|
|
179
|
+
*/
|
|
180
|
+
asset: string;
|
|
181
|
+
/**
|
|
182
|
+
* Merchant receive address (EVM hex or base58, per the destination chain).
|
|
183
|
+
*/
|
|
184
|
+
address: string;
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Exact amount the merchant receives, in atomic token units.
|
|
188
|
+
*/
|
|
189
|
+
fulfillmentAmount: string;
|
|
190
|
+
/**
|
|
191
|
+
* Source-chain escrow contract (the x402 payTo); EVM hex or base58, per the source chain.
|
|
192
|
+
*/
|
|
193
|
+
escrow: string;
|
|
194
|
+
/**
|
|
195
|
+
* Destination-chain fulfillment proxy contract (EVM hex or base58, per the destination chain).
|
|
196
|
+
*/
|
|
197
|
+
fulfillmentProxy: string;
|
|
198
|
+
/**
|
|
199
|
+
* Atum reserver role address (escrow deposit witness); EVM hex or base58, per the source chain.
|
|
200
|
+
*/
|
|
201
|
+
reserver: string;
|
|
202
|
+
/**
|
|
203
|
+
* Atum releaser role address (escrow deposit witness); EVM hex or base58, per the source chain.
|
|
204
|
+
*/
|
|
205
|
+
releaser: string;
|
|
206
|
+
/**
|
|
207
|
+
* Source-chain fulfillment-verifier endpoint the payment request carries. The verifier account and the quote_selector are the releaser and reserver respectively (the network derives the deposit witness roles from them), so only the endpoint is not otherwise present in this object.
|
|
208
|
+
*/
|
|
209
|
+
fulfillmentVerifierEndpoint: string;
|
|
210
|
+
/**
|
|
211
|
+
* Recommended quote-deadline budget in seconds, relative to signing time.
|
|
212
|
+
*/
|
|
213
|
+
quoteDeadlineSeconds: number;
|
|
214
|
+
/**
|
|
215
|
+
* Recommended fulfillment-deadline budget in seconds, relative to signing time.
|
|
216
|
+
*/
|
|
217
|
+
fulfillmentDeadlineSeconds: number;
|
|
218
|
+
/**
|
|
219
|
+
* Solana source only: cluster name used to build the 32-byte cluster_id in the V3 escrow signature domain. Optional; the facilitator requires it for a Solana source.
|
|
220
|
+
*/
|
|
221
|
+
svmSignatureClusterId?: string;
|
|
222
|
+
/**
|
|
223
|
+
* Solana source only: escrow signature-domain version (V3 domain separation). Optional; required for a Solana source.
|
|
224
|
+
*/
|
|
225
|
+
svmSignatureDomainVersion?: number;
|
|
226
|
+
/**
|
|
227
|
+
* Solana source only: merchant-stamped issue time in epoch seconds. The merchant reads the cluster clock so the client makes no RPC and the 402 stays self-contained. Optional; required for a Solana source.
|
|
228
|
+
*/
|
|
229
|
+
issuedAt?: string;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Shared internals for the Atum escrow MPP method: the wire schemas, the method
|
|
234
|
+
* definition, the shared types, and the pure chain/address helpers used by both
|
|
235
|
+
* the payer ({@link ./client}) and merchant ({@link ./server}) sides.
|
|
236
|
+
*
|
|
237
|
+
* This module is not a public entry point — consumers import from the package
|
|
238
|
+
* root, `/client`, or `/server`. The helpers here are exported only so the
|
|
239
|
+
* client and server modules can share them.
|
|
240
|
+
*
|
|
241
|
+
* @internal
|
|
242
|
+
*/
|
|
243
|
+
|
|
244
|
+
/** The method name advertised in MPP challenges and credentials. */
|
|
245
|
+
declare const METHOD_NAME = "atum-escrow";
|
|
246
|
+
/** The MPP intent this method implements. */
|
|
247
|
+
declare const INTENT = "charge";
|
|
248
|
+
/**
|
|
249
|
+
* Schema for the `charge` challenge request — the method-specific data a merchant
|
|
250
|
+
* publishes in an MPP `402` challenge. It describes what the merchant receives and the
|
|
251
|
+
* source option the payer may fund from, so the payer can build the payment offline.
|
|
252
|
+
*/
|
|
253
|
+
declare const ChargeRequestSchema: z.ZodMiniObject<{
|
|
254
|
+
source: z.ZodMiniObject<{
|
|
255
|
+
network: z.ZodMiniString<string>;
|
|
256
|
+
asset: z.ZodMiniString<string>;
|
|
257
|
+
amount: z.ZodMiniString<string>;
|
|
258
|
+
}, z.core.$strip>;
|
|
259
|
+
extra: z.ZodMiniObject<{
|
|
260
|
+
destination: z.ZodMiniObject<{
|
|
261
|
+
network: z.ZodMiniString<string>;
|
|
262
|
+
asset: z.ZodMiniString<string>;
|
|
263
|
+
address: z.ZodMiniString<string>;
|
|
264
|
+
}, z.core.$strip>;
|
|
265
|
+
fulfillmentAmount: z.ZodMiniString<string>;
|
|
266
|
+
escrow: z.ZodMiniString<string>;
|
|
267
|
+
fulfillmentProxy: z.ZodMiniString<string>;
|
|
268
|
+
reserver: z.ZodMiniString<string>;
|
|
269
|
+
releaser: z.ZodMiniString<string>;
|
|
270
|
+
fulfillmentVerifierEndpoint: z.ZodMiniString<string>;
|
|
271
|
+
quoteDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
272
|
+
fulfillmentDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
273
|
+
svmSignatureClusterId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
274
|
+
svmSignatureDomainVersion: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
275
|
+
issuedAt: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
276
|
+
}, z.core.$strip>;
|
|
277
|
+
}, z.core.$strip>;
|
|
278
|
+
/**
|
|
279
|
+
* Schema for the `charge` credential payload — the signed payment the payer returns in
|
|
280
|
+
* the MPP credential. It carries the Atum payment request; the request's signatures and
|
|
281
|
+
* terms are verified in full during server verification and by the Atum Payment Gateway,
|
|
282
|
+
* so this envelope validates only that the request is present.
|
|
283
|
+
*/
|
|
284
|
+
declare const CredentialPayloadSchema: z.ZodMiniObject<{
|
|
285
|
+
paymentRequest: z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>;
|
|
286
|
+
}, z.core.$strip>;
|
|
287
|
+
/**
|
|
288
|
+
* The `charge` challenge request — the canonical `AtumEscrowRequest` shape (source option
|
|
289
|
+
* + the destination/corridor `extra`). The runtime schema above is verified against this
|
|
290
|
+
* type at compile time (below), so the validator and the canonical schema cannot drift.
|
|
291
|
+
*/
|
|
292
|
+
type ChargeRequest = AtumEscrowRequest;
|
|
293
|
+
/** The `charge` credential payload, carrying the signed Atum payment request. */
|
|
294
|
+
interface ChargeCredentialPayload {
|
|
295
|
+
/** The signed Atum payment request: source/destination, amounts, and authorizations. */
|
|
296
|
+
paymentRequest: PaymentRequest;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* The MPP challenge for this method. Uses the schema's inferred type for the request
|
|
300
|
+
* (equal to {@link ChargeRequest} by the compile-time guard above, and compatible with
|
|
301
|
+
* the framework's `Record<string, unknown>` request constraint).
|
|
302
|
+
*/
|
|
303
|
+
type AtumEscrowChallenge = Challenge.Challenge<z.infer<typeof ChargeRequestSchema>, "charge", "atum-escrow">;
|
|
304
|
+
/** The MPP credential for this method. */
|
|
305
|
+
type AtumEscrowCredential = Credential.Credential<ChargeCredentialPayload, AtumEscrowChallenge>;
|
|
306
|
+
/**
|
|
307
|
+
* The base `atum-escrow` charge method. Extend it with `registerClient` on the payer side
|
|
308
|
+
* and `registerServer` on the merchant side.
|
|
309
|
+
*/
|
|
310
|
+
declare const atumEscrowChargeMethod: {
|
|
311
|
+
readonly name: "atum-escrow";
|
|
312
|
+
readonly intent: "charge";
|
|
313
|
+
readonly schema: {
|
|
314
|
+
readonly request: z.ZodMiniObject<{
|
|
315
|
+
source: z.ZodMiniObject<{
|
|
316
|
+
network: z.ZodMiniString<string>;
|
|
317
|
+
asset: z.ZodMiniString<string>;
|
|
318
|
+
amount: z.ZodMiniString<string>;
|
|
319
|
+
}, z.core.$strip>;
|
|
320
|
+
extra: z.ZodMiniObject<{
|
|
321
|
+
destination: z.ZodMiniObject<{
|
|
322
|
+
network: z.ZodMiniString<string>;
|
|
323
|
+
asset: z.ZodMiniString<string>;
|
|
324
|
+
address: z.ZodMiniString<string>;
|
|
325
|
+
}, z.core.$strip>;
|
|
326
|
+
fulfillmentAmount: z.ZodMiniString<string>;
|
|
327
|
+
escrow: z.ZodMiniString<string>;
|
|
328
|
+
fulfillmentProxy: z.ZodMiniString<string>;
|
|
329
|
+
reserver: z.ZodMiniString<string>;
|
|
330
|
+
releaser: z.ZodMiniString<string>;
|
|
331
|
+
fulfillmentVerifierEndpoint: z.ZodMiniString<string>;
|
|
332
|
+
quoteDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
333
|
+
fulfillmentDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
334
|
+
svmSignatureClusterId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
335
|
+
svmSignatureDomainVersion: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
336
|
+
issuedAt: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
337
|
+
}, z.core.$strip>;
|
|
338
|
+
}, z.core.$strip>;
|
|
339
|
+
readonly credential: {
|
|
340
|
+
readonly payload: z.ZodMiniObject<{
|
|
341
|
+
paymentRequest: z.ZodMiniRecord<z.ZodMiniString<string>, z.ZodMiniUnknown>;
|
|
342
|
+
}, z.core.$strip>;
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
};
|
|
346
|
+
|
|
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 };
|
package/dist/server.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as zod_v4_core from 'zod/v4/core';
|
|
2
2
|
import * as z from 'zod/mini';
|
|
3
|
-
import {
|
|
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-
|
|
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
5
|
import { Receipt, Method } from 'mppx';
|
|
6
|
+
import { PaymentRequest } from './generated/index.js';
|
|
7
|
+
export { PaymentRequest } from './generated/index.js';
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* This file was automatically generated by json-schema-to-typescript.
|
|
@@ -69,8 +71,6 @@ interface AtumEscrowSource {
|
|
|
69
71
|
releaser: string;
|
|
70
72
|
/** Source-chain endpoint used to verify fulfillment. */
|
|
71
73
|
fulfillmentVerifierEndpoint: string;
|
|
72
|
-
/** Tron-only: the Permit2 contract the deposit is signed against. Defaults to the known address for the cluster when omitted. */
|
|
73
|
-
permit2?: string;
|
|
74
74
|
/** Solana-only: cluster id that domain-separates the deposit authorization. */
|
|
75
75
|
svmSignatureClusterId?: string;
|
|
76
76
|
/** Solana-only: signature domain version that domain-separates the deposit authorization. */
|
|
@@ -151,7 +151,7 @@ declare function registerServer(config: AtumEscrowServerConfig): Method.Server<{
|
|
|
151
151
|
destination: z.ZodMiniObject<{
|
|
152
152
|
network: z.ZodMiniString<string>;
|
|
153
153
|
asset: z.ZodMiniString<string>;
|
|
154
|
-
|
|
154
|
+
address: z.ZodMiniString<string>;
|
|
155
155
|
}, zod_v4_core.$strip>;
|
|
156
156
|
fulfillmentAmount: z.ZodMiniString<string>;
|
|
157
157
|
escrow: z.ZodMiniString<string>;
|
|
@@ -161,9 +161,9 @@ declare function registerServer(config: AtumEscrowServerConfig): Method.Server<{
|
|
|
161
161
|
fulfillmentVerifierEndpoint: z.ZodMiniString<string>;
|
|
162
162
|
quoteDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
163
163
|
fulfillmentDeadlineSeconds: z.ZodMiniNumber<number>;
|
|
164
|
-
permit2: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
165
164
|
svmSignatureClusterId: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
166
165
|
svmSignatureDomainVersion: z.ZodMiniOptional<z.ZodMiniNumber<number>>;
|
|
166
|
+
issuedAt: z.ZodMiniOptional<z.ZodMiniString<string>>;
|
|
167
167
|
}, zod_v4_core.$strip>;
|
|
168
168
|
}, zod_v4_core.$strip>;
|
|
169
169
|
readonly credential: {
|
|
@@ -191,12 +191,20 @@ declare function validateCorridor(corridor: AtumEscrowCorridor): void;
|
|
|
191
191
|
* @param select - which configured source to fund from, by `(network, asset)`.
|
|
192
192
|
* @param fulfillmentAmount - exact amount the merchant receives, atomic units of the
|
|
193
193
|
* destination token. Set per charge so one registration serves any price.
|
|
194
|
+
* @param options.issuedAt - Solana-source only: the merchant's cluster-clock reading (epoch
|
|
195
|
+
* seconds) to stamp into `extra.issuedAt`, so the payer's client builds the deposit fully
|
|
196
|
+
* offline (no RPC). Omit to let the client stamp `issued_at` from its own clock at signing
|
|
197
|
+
* time — which keeps the full replay window; a merchant-stamped value anchors the window
|
|
198
|
+
* earlier (at 402-build time), so only set it when the client genuinely cannot read a clock.
|
|
199
|
+
* Ignored for EVM/Tron sources.
|
|
194
200
|
* @throws if no source option matches `select`, or the corridor is invalid.
|
|
195
201
|
*/
|
|
196
202
|
declare function buildChargeRequest(corridor: AtumEscrowCorridor, select: {
|
|
197
203
|
network: string;
|
|
198
204
|
asset: string;
|
|
199
|
-
}, fulfillmentAmount: string
|
|
205
|
+
}, fulfillmentAmount: string, options?: {
|
|
206
|
+
issuedAt?: string;
|
|
207
|
+
}): ChargeRequest;
|
|
200
208
|
/** The minimal defaults source `corridorFromDefaults` needs; satisfied by the gateway client. */
|
|
201
209
|
interface ChainDefaultsSource {
|
|
202
210
|
fetchChainDefaults(chainId: string): Promise<ChainDefaults>;
|
|
@@ -227,4 +235,4 @@ declare function corridorFromDefaults(defaults: ChainDefaultsSource, params: {
|
|
|
227
235
|
fulfillmentDeadlineSeconds: number;
|
|
228
236
|
}): Promise<AtumEscrowCorridor>;
|
|
229
237
|
|
|
230
|
-
export { type AtumEscrowCorridor, type AtumEscrowReceipt, type AtumEscrowServerConfig, type AtumEscrowSource, type ChainDefaultsSource, ChargeRequest, type FulfillmentConfirmation,
|
|
238
|
+
export { type AtumEscrowCorridor, type AtumEscrowReceipt, type AtumEscrowServerConfig, type AtumEscrowSource, type ChainDefaultsSource, ChargeRequest, type FulfillmentConfirmation, type PaymentSubmitter, buildChargeRequest, corridorFromDefaults, registerServer, validateCorridor };
|
package/dist/server.js
CHANGED
|
@@ -10,14 +10,14 @@ import {
|
|
|
10
10
|
corridorFromDefaults,
|
|
11
11
|
registerServer,
|
|
12
12
|
validateCorridor
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NEM3HEZW.js";
|
|
14
14
|
import {
|
|
15
15
|
ChargeRequestSchema,
|
|
16
16
|
CredentialPayloadSchema,
|
|
17
17
|
INTENT,
|
|
18
18
|
METHOD_NAME,
|
|
19
19
|
atumEscrowChargeMethod
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-4P34CLTO.js";
|
|
21
21
|
export {
|
|
22
22
|
ChargeRequestSchema,
|
|
23
23
|
CredentialPayloadSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atumlabs/mppx-atum-escrow",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.2",
|
|
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",
|
|
@@ -49,17 +49,18 @@
|
|
|
49
49
|
"files": [
|
|
50
50
|
"dist/**/*",
|
|
51
51
|
"README.md",
|
|
52
|
+
"CHANGELOG.md",
|
|
52
53
|
"LICENSE",
|
|
53
54
|
"THIRD-PARTY-NOTICES.txt"
|
|
54
55
|
],
|
|
55
56
|
"scripts": {
|
|
56
|
-
"prebuild:deps": "node -e \"const {existsSync}=require('fs');for(const p of ['../contracts/evm/escrow-encoding/typescript/tsconfig.json','../contracts/tvm/escrow-encoding/typescript/tsconfig.json','../contracts/svm/escrow-encoding/typescript/tsconfig.json','../schemas/apis/
|
|
57
|
-
"build:deps": "tsc -p ../contracts/evm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/tvm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/svm/escrow-encoding/typescript/tsconfig.json && tsc -p ../schemas/apis/
|
|
57
|
+
"prebuild:deps": "node -e \"const {existsSync}=require('fs');for(const p of ['../contracts/evm/escrow-encoding/typescript/tsconfig.json','../contracts/tvm/escrow-encoding/typescript/tsconfig.json','../contracts/svm/escrow-encoding/typescript/tsconfig.json','../schemas/apis/x402/v1/bindings/typescript/tsconfig.json','../schemas/apis/fulfillment-confirmation/v1/bindings/typescript/tsconfig.json','../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/tsconfig.json']){if(!existsSync(p)){console.error('bundled sibling not found at '+p+'. Is this checked out inside the protocol monorepo?');process.exit(1)}}if(!existsSync('../payment-gateway-client/dist/index.js')){console.error('@atum-labs/payment-gateway-client is not built. Run its build first (pnpm --filter @atum-labs/payment-gateway-client build).');process.exit(1)}\"",
|
|
58
|
+
"build:deps": "tsc -p ../contracts/evm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/tvm/escrow-encoding/typescript/tsconfig.json && tsc -p ../contracts/svm/escrow-encoding/typescript/tsconfig.json && tsc -p ../schemas/apis/x402/v1/bindings/typescript/tsconfig.json && tsc -p ../schemas/apis/fulfillment-confirmation/v1/bindings/typescript/tsconfig.json && tsc -p ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/tsconfig.json",
|
|
58
59
|
"build": "pnpm run build:deps && tsup && node scripts/stamp-entry-headers.mjs",
|
|
59
60
|
"typecheck": "pnpm run build:deps && tsc --noEmit",
|
|
60
61
|
"pretest": "pnpm run build:deps",
|
|
61
62
|
"test": "vitest run",
|
|
62
|
-
"clean": "rm -rf dist ../contracts/evm/escrow-encoding/typescript/dist ../contracts/tvm/escrow-encoding/typescript/dist ../contracts/svm/escrow-encoding/typescript/dist ../schemas/apis/
|
|
63
|
+
"clean": "rm -rf dist ../contracts/evm/escrow-encoding/typescript/dist ../contracts/tvm/escrow-encoding/typescript/dist ../contracts/svm/escrow-encoding/typescript/dist ../schemas/apis/x402/v1/bindings/typescript/dist ../schemas/apis/fulfillment-confirmation/v1/bindings/typescript/dist ../schemas/declarations/PaymentRequest/v1/bindings/typescript/sender-auth/dist",
|
|
63
64
|
"check:publishable": "node scripts/check-publishable.mjs",
|
|
64
65
|
"gen:notices": "node scripts/gen-third-party-notices.mjs",
|
|
65
66
|
"prepare": "pnpm run build",
|
|
@@ -80,6 +81,8 @@
|
|
|
80
81
|
"@atum-labs/evm-escrow-encoding": "workspace:*",
|
|
81
82
|
"@atum-labs/fulfillment-confirmation": "workspace:*",
|
|
82
83
|
"@atum-labs/payment-gateway-client": "workspace:*",
|
|
84
|
+
"@atum-labs/payment-request-sender-auth": "workspace:*",
|
|
85
|
+
"@atum-labs/publish-guard": "workspace:*",
|
|
83
86
|
"@atum-labs/schema-declarations": "workspace:*",
|
|
84
87
|
"@atum-labs/solana-escrow-encoding": "workspace:*",
|
|
85
88
|
"@atum-labs/tvm-escrow-encoding": "workspace:*",
|
package/dist/chunk-L62WG2VU.js
DELETED
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
import { createRequire as __atumCreateRequire } from 'module'; const require = __atumCreateRequire(import.meta.url);
|
|
2
|
-
import {
|
|
3
|
-
__toESM,
|
|
4
|
-
assetIdentifier,
|
|
5
|
-
atumEscrowChargeMethod,
|
|
6
|
-
chainDefaultsFromExtra,
|
|
7
|
-
namespaceOf,
|
|
8
|
-
require_dist,
|
|
9
|
-
require_dist2
|
|
10
|
-
} from "./chunk-2MWWLU75.js";
|
|
11
|
-
|
|
12
|
-
// src/client.ts
|
|
13
|
-
var import_evm_escrow_encoding = __toESM(require_dist(), 1);
|
|
14
|
-
var import_payment_gateway_client = __toESM(require_dist2(), 1);
|
|
15
|
-
import { keccak256, toUtf8Bytes, Contract, MaxUint256 } from "ethers";
|
|
16
|
-
import { Credential, Method } from "mppx";
|
|
17
|
-
function registerClient(config) {
|
|
18
|
-
const now = config.now ?? (() => Date.now());
|
|
19
|
-
const gateway = new import_payment_gateway_client.PaymentGatewayClient();
|
|
20
|
-
return Method.toClient(atumEscrowChargeMethod, {
|
|
21
|
-
async createCredential({ challenge }) {
|
|
22
|
-
const { source, extra } = challenge.request;
|
|
23
|
-
const namespace = namespaceOf(source.network);
|
|
24
|
-
const account = config.account;
|
|
25
|
-
const nowMs = now();
|
|
26
|
-
if (!(extra.quoteDeadlineSeconds > 0 && extra.quoteDeadlineSeconds < extra.fulfillmentDeadlineSeconds)) {
|
|
27
|
-
throw new Error(
|
|
28
|
-
`atum-escrow: deadline ordering violated (now < quote_deadline < fulfillment_deadline); quoteDeadlineSeconds=${extra.quoteDeadlineSeconds}, fulfillmentDeadlineSeconds=${extra.fulfillmentDeadlineSeconds}`
|
|
29
|
-
);
|
|
30
|
-
}
|
|
31
|
-
const anchorAccount = namespace === "eip155" ? account.toLowerCase() : account;
|
|
32
|
-
const idempotencyAnchor = keccak256(
|
|
33
|
-
toUtf8Bytes(`atum-escrow:${challenge.id}:${anchorAccount}`)
|
|
34
|
-
);
|
|
35
|
-
const requestId = `req_mpp_${idempotencyAnchor.slice(2, 26)}`;
|
|
36
|
-
const sourceDefaults = chainDefaultsFromExtra(extra, source.network);
|
|
37
|
-
const sourceAssetId = assetIdentifier(source.network, source.asset);
|
|
38
|
-
const isSolana = namespace === "solana";
|
|
39
|
-
const paymentRequestGw = await gateway.preparePaymentRequest({
|
|
40
|
-
depositor: account,
|
|
41
|
-
fulfillmentAmount: extra.fulfillmentAmount,
|
|
42
|
-
sourceAsset: sourceAssetId,
|
|
43
|
-
destinationAccount: extra.destination.account,
|
|
44
|
-
destinationAsset: assetIdentifier(extra.destination.network, extra.destination.asset),
|
|
45
|
-
// Sign the full advertised cap. The payer MAY sign a lower value, but that only
|
|
46
|
-
// lowers its own escrow lock and risks the auction not clearing; the full cap is
|
|
47
|
-
// the safe default and never affects the receive side.
|
|
48
|
-
maxSourceAmount: source.amount,
|
|
49
|
-
requestId,
|
|
50
|
-
quoteDeadlineSeconds: extra.quoteDeadlineSeconds,
|
|
51
|
-
fulfillmentDeadlineSeconds: extra.fulfillmentDeadlineSeconds,
|
|
52
|
-
now: () => nowMs,
|
|
53
|
-
resolvedDefaults: {
|
|
54
|
-
source: sourceDefaults,
|
|
55
|
-
destination: { fulfillmentProxy: extra.fulfillmentProxy }
|
|
56
|
-
},
|
|
57
|
-
// EVM/Tron: thread the deterministic nonce, and keep the deposit deadline at least
|
|
58
|
-
// as late as the fulfillment deadline. The adapter floors the relative deadline, so
|
|
59
|
-
// +1s guards against truncating below fulfillment_deadline.
|
|
60
|
-
...isSolana ? {
|
|
61
|
-
// Solana stamps issued_at from the (injectable) clock and derives its own
|
|
62
|
-
// replay-window deadline; the offline build reads the client clock.
|
|
63
|
-
solanaRpcUrl: "atum-escrow:offline",
|
|
64
|
-
solanaClockReader: config.solanaClockReader ?? (async () => BigInt(Math.floor(nowMs / 1e3)))
|
|
65
|
-
} : {
|
|
66
|
-
nonce: BigInt(idempotencyAnchor),
|
|
67
|
-
// Keep the deposit deadline at least as late as fulfillment. The adapter
|
|
68
|
-
// floors its relative deadline, so round the budget up and add a second to
|
|
69
|
-
// guard against truncating below fulfillment_deadline (and to keep an
|
|
70
|
-
// integer, since the adapter derives a bigint from it).
|
|
71
|
-
deadlineSeconds: Math.ceil(extra.fulfillmentDeadlineSeconds) + 1
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
const signer = buildSenderSigner(source.network, config.signer, account);
|
|
75
|
-
await (0, import_payment_gateway_client.signPaymentRequest)(paymentRequestGw, signer);
|
|
76
|
-
const paymentRequest = paymentRequestGw;
|
|
77
|
-
return Credential.serialize({
|
|
78
|
-
challenge,
|
|
79
|
-
payload: { paymentRequest },
|
|
80
|
-
source: `did:pkh:${source.network}:${anchorAccount}`
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
function isSenderSigner(signer) {
|
|
86
|
-
return typeof signer.sign === "function";
|
|
87
|
-
}
|
|
88
|
-
function buildSenderSigner(network, signer, account) {
|
|
89
|
-
if (isSenderSigner(signer)) {
|
|
90
|
-
return signer;
|
|
91
|
-
}
|
|
92
|
-
if (signer.provider === "turnkey") {
|
|
93
|
-
throw new Error(
|
|
94
|
-
"atum-escrow: construct a Turnkey SenderSigner with the payment-gateway client and pass it as `signer`"
|
|
95
|
-
);
|
|
96
|
-
}
|
|
97
|
-
return (0, import_payment_gateway_client.createSenderSigner)(network, {
|
|
98
|
-
provider: "raw",
|
|
99
|
-
privateKey: signer.privateKey,
|
|
100
|
-
pinnedAddress: signer.pinnedAddress ?? account
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
104
|
-
"function allowance(address owner, address spender) view returns (uint256)",
|
|
105
|
-
"function approve(address spender, uint256 amount) returns (bool)"
|
|
106
|
-
];
|
|
107
|
-
async function ensureSourceApproval(params) {
|
|
108
|
-
if (namespaceOf(params.network) === "solana") {
|
|
109
|
-
return { alreadySufficient: true };
|
|
110
|
-
}
|
|
111
|
-
const spender = params.spender ?? (namespaceOf(params.network) === "eip155" ? import_evm_escrow_encoding.PERMIT2_CONTRACT_ADDRESS : void 0);
|
|
112
|
-
if (!spender) {
|
|
113
|
-
throw new Error(
|
|
114
|
-
`atum-escrow: a spender (Permit2 address) is required to approve on ${params.network}`
|
|
115
|
-
);
|
|
116
|
-
}
|
|
117
|
-
const erc20 = new Contract(params.token, ERC20_ALLOWANCE_ABI, params.signer);
|
|
118
|
-
const current = await erc20.allowance(params.owner, spender);
|
|
119
|
-
const sufficient = params.requiredAllowance !== void 0 ? current >= params.requiredAllowance : current >= MaxUint256;
|
|
120
|
-
if (sufficient) {
|
|
121
|
-
return { alreadySufficient: true };
|
|
122
|
-
}
|
|
123
|
-
const tx = await erc20.approve(spender, MaxUint256);
|
|
124
|
-
await tx.wait?.();
|
|
125
|
-
return { alreadySufficient: false, txHash: tx.hash };
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export {
|
|
129
|
-
registerClient,
|
|
130
|
-
ensureSourceApproval
|
|
131
|
-
};
|