@defuse-protocol/nearintents-mpp-sdk 0.0.0 → 0.1.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.
Files changed (48) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/dist/Errors.d.ts +57 -0
  4. package/dist/Errors.d.ts.map +1 -0
  5. package/dist/Errors.js +54 -0
  6. package/dist/Errors.js.map +1 -0
  7. package/dist/Methods.d.ts +44 -0
  8. package/dist/Methods.d.ts.map +1 -0
  9. package/dist/Methods.js +23 -0
  10. package/dist/Methods.js.map +1 -0
  11. package/dist/Types.d.ts +125 -0
  12. package/dist/Types.d.ts.map +1 -0
  13. package/dist/Types.js +195 -0
  14. package/dist/Types.js.map +1 -0
  15. package/dist/client/Charge.d.ts +141 -0
  16. package/dist/client/Charge.d.ts.map +1 -0
  17. package/dist/client/Charge.js +167 -0
  18. package/dist/client/Charge.js.map +1 -0
  19. package/dist/client/index.d.ts +5 -0
  20. package/dist/client/index.d.ts.map +1 -0
  21. package/dist/client/index.js +5 -0
  22. package/dist/client/index.js.map +1 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +5 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/internal/OneClick.d.ts +243 -0
  28. package/dist/internal/OneClick.d.ts.map +1 -0
  29. package/dist/internal/OneClick.js +422 -0
  30. package/dist/internal/OneClick.js.map +1 -0
  31. package/dist/server/Charge.d.ts +241 -0
  32. package/dist/server/Charge.d.ts.map +1 -0
  33. package/dist/server/Charge.js +404 -0
  34. package/dist/server/Charge.js.map +1 -0
  35. package/dist/server/index.d.ts +5 -0
  36. package/dist/server/index.d.ts.map +1 -0
  37. package/dist/server/index.js +5 -0
  38. package/dist/server/index.js.map +1 -0
  39. package/package.json +87 -9
  40. package/src/Errors.ts +86 -0
  41. package/src/Methods.ts +24 -0
  42. package/src/Types.ts +256 -0
  43. package/src/client/Charge.ts +268 -0
  44. package/src/client/index.ts +4 -0
  45. package/src/index.ts +4 -0
  46. package/src/internal/OneClick.ts +634 -0
  47. package/src/server/Charge.ts +621 -0
  48. package/src/server/index.ts +4 -0
@@ -0,0 +1,404 @@
1
+ import { Errors, Method, Store } from 'mppx';
2
+ import { SettlementFailedError, SettlementTimeoutError, SettlementUnavailableError, } from '../Errors.js';
3
+ import * as OneClick from '../internal/OneClick.js';
4
+ import * as Methods from '../Methods.js';
5
+ import * as Types from '../Types.js';
6
+ /**
7
+ * Creates a `nearintents` charge method for usage on the server.
8
+ *
9
+ * Each 402 challenge carries a unique single-use 1Click deposit address as
10
+ * `recipient` (minted via a wet `EXACT_OUTPUT` quote and cached with early
11
+ * refresh so the challenge `expires` always precedes the quote deadline).
12
+ * Verification confirms the client's deposit by 1Click status observation,
13
+ * drives the swap to a terminal state, and issues the extended receipt on
14
+ * `SUCCESS`.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { Mppx } from 'mppx/server'
19
+ * import { nearintents } from '@defuse-protocol/nearintents-mpp-sdk/server'
20
+ *
21
+ * const mppx = Mppx.create({
22
+ * secretKey: process.env.MPP_SECRET_KEY!,
23
+ * methods: [
24
+ * nearintents.charge({
25
+ * originAsset: 'eip155:42161/erc20:0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
26
+ * destinationAsset: 'near:mainnet/nep141:1720…33a1',
27
+ * destinationRecipient: 'merchant.near',
28
+ * refundTo: '0x2527D02599Ba641c19FEa793cD0F9a6e8457C317',
29
+ * amountOut: '1000000',
30
+ * oneClick: { jwt: process.env.ONE_CLICK_JWT },
31
+ * }),
32
+ * ],
33
+ * })
34
+ * ```
35
+ */
36
+ export function charge(parameters) {
37
+ const { amountOut: defaultAmountOut, description, destinationAsset, destinationRecipient, externalId, oneClick = {}, originAsset,
38
+ // Distribution-channel attribution: every 1Click swap minted by this
39
+ // payment method carries the "mpp" referral (mirrors the x402 gateway).
40
+ referral = 'mpp', refundTo, slippageTolerance = 100, } = parameters;
41
+ // Merchant observability: settlement progress is reported as structured
42
+ // events (the library never logs). A throwing handler must not affect
43
+ // payment processing.
44
+ const emit = (event) => {
45
+ try {
46
+ parameters.onEvent?.(event);
47
+ }
48
+ catch {
49
+ // Observer errors are the observer's problem.
50
+ }
51
+ };
52
+ // Fail fast on malformed merchant config (throws at construction time).
53
+ const originNetwork = Types.chainOf(originAsset);
54
+ const destinationNetwork = Types.chainOf(destinationAsset);
55
+ const expiresWindowMs = (parameters.expiresWindow ?? 300) * 1000;
56
+ const quoteDeadlineBufferMs = (parameters.quoteDeadlineBuffer ?? 900) * 1000;
57
+ const pollIntervalMs = parameters.pollInterval ?? 2000;
58
+ const store = Store.from((parameters.store ?? Store.memory()), { keyPrefix: parameters.storeKeyPrefix ?? '' });
59
+ // Token list is fetched lazily and re-fetched once on an unresolved asset
60
+ // (the list evolves); a persistent miss is a merchant-config error.
61
+ let assetMapPromise;
62
+ function getAssetMap(refresh = false) {
63
+ if (!assetMapPromise || refresh) {
64
+ assetMapPromise = OneClick.getTokens(oneClick)
65
+ .then((tokens) => OneClick.createAssetMap(tokens, oneClick))
66
+ .catch((error) => {
67
+ assetMapPromise = undefined;
68
+ throw error;
69
+ });
70
+ }
71
+ return assetMapPromise;
72
+ }
73
+ async function resolveAssetId(caip19Id) {
74
+ let assetId = (await getAssetMap()).toAssetId(caip19Id);
75
+ if (!assetId)
76
+ assetId = (await getAssetMap(true)).toAssetId(caip19Id);
77
+ if (!assetId)
78
+ throw new Error(`nearintents-mpp-sdk: asset "${caip19Id}" is not on the 1Click token list — check the merchant configuration (or extend oneClick.networks).`);
79
+ return assetId;
80
+ }
81
+ const depositKey = (address) => `nearintents-mpp-sdk:deposit:${address}`;
82
+ const quoteKey = (identity) => `nearintents-mpp-sdk:quote:${identity}`;
83
+ const hashKey = (hash) => `nearintents-mpp-sdk:hash:${hash.toLowerCase()}`;
84
+ function identityOf(amountOut) {
85
+ return [
86
+ originAsset,
87
+ destinationAsset,
88
+ amountOut,
89
+ destinationRecipient,
90
+ refundTo,
91
+ slippageTolerance,
92
+ referral,
93
+ ].join('|');
94
+ }
95
+ /**
96
+ * Returns the route's active canonical request, minting a fresh 1Click
97
+ * quote when there is none — or when the cached one is stale (early
98
+ * refresh: a quote is stale once `now + expiresWindow > quote deadline`,
99
+ * so the challenge `expires` always precedes the active quote's deadline).
100
+ */
101
+ async function resolveActiveRequest(amountOut) {
102
+ const identity = identityOf(amountOut);
103
+ const pointer = await store.get(quoteKey(identity));
104
+ if (pointer && pointer.identity === identity) {
105
+ const deposit = await store.get(depositKey(pointer.depositAddress));
106
+ if (deposit &&
107
+ deposit.state === 'active' &&
108
+ deposit.identity === identity &&
109
+ Date.parse(deposit.deadline) > Date.now() + expiresWindowMs) {
110
+ emit({ type: 'quote.reused', depositAddress: deposit.request.recipient });
111
+ return deposit.request;
112
+ }
113
+ }
114
+ const [originAssetId, destinationAssetId] = await Promise.all([
115
+ resolveAssetId(originAsset),
116
+ resolveAssetId(destinationAsset),
117
+ ]);
118
+ const requestedDeadline = new Date(Date.now() + expiresWindowMs + quoteDeadlineBufferMs).toISOString();
119
+ const { quote } = await OneClick.quote(oneClick, {
120
+ originAsset: originAssetId,
121
+ destinationAsset: destinationAssetId,
122
+ amountOut,
123
+ recipient: destinationRecipient,
124
+ refundTo,
125
+ slippageTolerance,
126
+ deadline: requestedDeadline,
127
+ referral,
128
+ });
129
+ // Spec §Expiry: `expires` MUST be at or before the quote deadline. The
130
+ // backend's deadline is authoritative; if it cannot cover the route's
131
+ // static expires window, the route is misconfigured — fail loud.
132
+ if (Date.parse(quote.deadline) <= Date.now() + expiresWindowMs)
133
+ throw new Error(`nearintents-mpp-sdk: 1Click quote deadline (${quote.deadline}) does not cover the route's expires window (${expiresWindowMs / 1000}s) — lower expiresWindow or raise quoteDeadlineBuffer.`);
134
+ const request = {
135
+ amount: quote.amountIn,
136
+ currency: originAsset,
137
+ recipient: quote.depositAddress,
138
+ ...(description !== undefined && { description }),
139
+ ...(externalId !== undefined && { externalId }),
140
+ methodDetails: {
141
+ originNetwork,
142
+ destinationNetwork,
143
+ destinationAsset,
144
+ destinationRecipient,
145
+ amountOut,
146
+ minAmountIn: quote.minAmountIn,
147
+ depositMemo: quote.depositMemo ?? null,
148
+ slippageTolerance,
149
+ timeEstimate: quote.timeEstimate,
150
+ refundTo,
151
+ settlementBackend: Types.settlementBackend,
152
+ credentialTypes: [...Types.credentialTypes],
153
+ },
154
+ };
155
+ await store.put(depositKey(quote.depositAddress), {
156
+ identity,
157
+ request,
158
+ deadline: quote.deadline,
159
+ timeEstimate: quote.timeEstimate,
160
+ depositMemo: quote.depositMemo ?? null,
161
+ state: 'active',
162
+ });
163
+ await store.put(quoteKey(identity), { identity, depositAddress: quote.depositAddress });
164
+ emit({
165
+ type: 'quote.minted',
166
+ depositAddress: quote.depositAddress,
167
+ amountIn: quote.amountIn,
168
+ minAmountIn: quote.minAmountIn,
169
+ amountOut,
170
+ deadline: quote.deadline,
171
+ timeEstimate: quote.timeEstimate,
172
+ });
173
+ return request;
174
+ }
175
+ /** Marks a deposit spent and drops the cache pointer so the next 402 mints fresh. */
176
+ async function retireDeposit(depositAddress, identity) {
177
+ await store.update(depositKey(depositAddress), (current) => {
178
+ if (!current)
179
+ return { op: 'noop', result: undefined };
180
+ return { op: 'set', value: { ...current, state: 'settled' }, result: undefined };
181
+ });
182
+ await store.update(quoteKey(identity), (current) => {
183
+ if (current?.depositAddress !== depositAddress)
184
+ return { op: 'noop', result: undefined };
185
+ return { op: 'delete', result: undefined };
186
+ });
187
+ }
188
+ /** Atomically claims `hash` as in-flight. Expired leases are reclaimable. */
189
+ async function claimHash(hash, leaseUntil) {
190
+ return store.update(hashKey(hash), (current) => {
191
+ if (current?.state === 'consumed')
192
+ return { op: 'noop', result: 'consumed' };
193
+ if (current?.state === 'inflight' && current.leaseUntil > Date.now())
194
+ return { op: 'noop', result: 'inflight' };
195
+ return { op: 'set', value: { state: 'inflight', leaseUntil }, result: 'claimed' };
196
+ });
197
+ }
198
+ return Method.toServer(Methods.charge, {
199
+ // Valid canonical placeholder — replaced by the request hook on every
200
+ // real path; only the fallback challenge (request hook threw a
201
+ // PaymentError) ever serializes it.
202
+ defaults: {
203
+ amount: '0',
204
+ currency: originAsset,
205
+ recipient: 'unavailable',
206
+ ...(description !== undefined && { description }),
207
+ ...(externalId !== undefined && { externalId }),
208
+ methodDetails: {
209
+ originNetwork,
210
+ destinationNetwork,
211
+ destinationAsset,
212
+ destinationRecipient,
213
+ amountOut: defaultAmountOut ?? '0',
214
+ minAmountIn: '0',
215
+ depositMemo: null,
216
+ slippageTolerance,
217
+ refundTo,
218
+ settlementBackend: Types.settlementBackend,
219
+ credentialTypes: [...Types.credentialTypes],
220
+ },
221
+ },
222
+ // Spec §Challenge Binding: the deposit address, amount, and source asset
223
+ // are challenge-specific. Binding them means a rotated quote yields a
224
+ // binding mismatch → 402 with a fresh challenge (the client-recovery flow).
225
+ stableBinding(request) {
226
+ const { amount, currency, methodDetails, recipient } = request;
227
+ return { amount, currency, originNetwork: methodDetails.originNetwork, recipient };
228
+ },
229
+ async request({ credential, request }) {
230
+ const amountOut = request.methodDetails?.amountOut ??
231
+ defaultAmountOut;
232
+ if (!amountOut || amountOut === '0')
233
+ throw new Error('nearintents-mpp-sdk: amountOut is required — set it in charge({ amountOut }) or per route via methodDetails.amountOut.');
234
+ // Credential-bearing request: resolve the quote the challenge was
235
+ // minted from (store lookup keyed by deposit address) — never mint a
236
+ // quote for a credential. Note the echoed challenge is NOT yet
237
+ // HMAC-verified here; the lookup returns OUR stored request, so a
238
+ // forged recipient can at most cause a cache-limited quote refresh.
239
+ if (credential) {
240
+ const recipient = credential.challenge.request?.recipient;
241
+ if (typeof recipient === 'string' && recipient) {
242
+ const deposit = await store.get(depositKey(recipient));
243
+ if (deposit &&
244
+ deposit.state === 'active' &&
245
+ deposit.identity === identityOf(amountOut) &&
246
+ Date.parse(deposit.deadline) > Date.now())
247
+ return deposit.request;
248
+ }
249
+ // Unknown, spent, or expired deposit address: fall through to the
250
+ // current active quote. The stableBinding mismatch then yields a 402
251
+ // carrying this fresh challenge — the spec's client-recovery flow.
252
+ }
253
+ return resolveActiveRequest(amountOut);
254
+ },
255
+ async verify({ credential, request }) {
256
+ const { challenge } = credential;
257
+ const resolved = (() => {
258
+ const parsed = Methods.charge.schema.request.safeParse(request);
259
+ if (parsed.success)
260
+ return parsed.data;
261
+ return request;
262
+ })();
263
+ const payload = credential.payload;
264
+ if (payload.type !== 'hash')
265
+ throw new Errors.InvalidPayloadError({ reason: 'only "hash" credentials are accepted' });
266
+ const hash = payload.hash;
267
+ // Spec §Verification step 4: the deposit address must correspond to an
268
+ // active, non-expired, non-settled quote in the server's state.
269
+ const recipient = resolved.recipient;
270
+ const deposit = await store.get(depositKey(recipient));
271
+ if (!deposit)
272
+ throw new Errors.InvalidChallengeError({
273
+ id: challenge.id,
274
+ reason: 'no active quote for this deposit address',
275
+ });
276
+ if (deposit.state === 'settled')
277
+ throw new Errors.InvalidChallengeError({
278
+ id: challenge.id,
279
+ reason: 'the quote for this deposit address is already settled',
280
+ });
281
+ if (Date.parse(deposit.deadline) <= Date.now())
282
+ throw new Errors.PaymentExpiredError({ expires: deposit.deadline });
283
+ const settlementTimeoutMs = (parameters.settlementTimeout ?? deposit.timeEstimate + 120) * 1000;
284
+ // Spec §Verification step 5 / §Replay: claim the hash in-flight
285
+ // atomically; consume permanently only on a terminal settlement state.
286
+ // The lease covers the settlement budget so a crashed settlement never
287
+ // strands a legitimate retry.
288
+ const claim = await claimHash(hash, Date.now() + settlementTimeoutMs + 60_000);
289
+ if (claim === 'consumed')
290
+ throw new Errors.VerificationFailedError({
291
+ reason: 'transaction hash has already been used',
292
+ });
293
+ if (claim === 'inflight')
294
+ throw new Errors.VerificationFailedError({
295
+ reason: 'settlement for this transaction hash is already in progress',
296
+ });
297
+ let hashOutcome = 'release';
298
+ try {
299
+ // Spec §Settlement step 1: notify the backend (optional accelerator;
300
+ // status observation below is authoritative, so failures are benign).
301
+ const accepted = await OneClick.submitDeposit(oneClick, {
302
+ txHash: hash,
303
+ depositAddress: recipient,
304
+ ...(deposit.depositMemo !== null && { memo: deposit.depositMemo }),
305
+ }).then(() => true, () => false);
306
+ emit({ type: 'deposit.submitted', depositAddress: recipient, originTxHash: hash, accepted });
307
+ // Spec §Settlement step 2 + §Verification step 3: poll to a terminal
308
+ // status; the backend detecting a qualifying deposit at `recipient`
309
+ // IS the deposit confirmation (status-observation mode).
310
+ const status = await OneClick.pollToTerminal(oneClick, {
311
+ depositAddress: recipient,
312
+ ...(deposit.depositMemo !== null && { depositMemo: deposit.depositMemo }),
313
+ timeoutMs: settlementTimeoutMs,
314
+ intervalMs: pollIntervalMs,
315
+ onStatus: (observed) => emit({ type: 'settlement.status', depositAddress: recipient, status: observed }),
316
+ });
317
+ // Any terminal state spends the quote and its deposit address —
318
+ // including SUCCESS whose observed deposits don't match the presented
319
+ // hash (below). Retiring here, before that match check, is deliberate:
320
+ // once the backend reaches SUCCESS the deposit is delivered, so the
321
+ // quote MUST leave rotation regardless of which credential presented
322
+ // it. Deferring the retire until after a match check would strand a
323
+ // backend-settled deposit as "active" in the store, and a later
324
+ // cache hit could hand a fresh payer an already-spent deposit address.
325
+ await retireDeposit(recipient, deposit.identity);
326
+ emit({
327
+ type: 'settlement.terminal',
328
+ depositAddress: recipient,
329
+ originTxHash: hash,
330
+ status: status.status,
331
+ ...(OneClick.destinationTxHash(status) !== undefined && {
332
+ destinationTxHash: OneClick.destinationTxHash(status),
333
+ }),
334
+ });
335
+ if (status.status === 'SUCCESS') {
336
+ // Deposit confirmation: the presented hash must be among the
337
+ // origin-chain transactions the backend observed for this address.
338
+ if (!OneClick.matchesOriginTx(status, hash))
339
+ throw new Errors.VerificationFailedError({
340
+ reason: 'the presented transaction hash is not among the deposits observed for this address',
341
+ });
342
+ hashOutcome = 'consume';
343
+ const reference = OneClick.destinationTxHash(status) ?? status.swapDetails?.nearTxHashes?.[0];
344
+ // The merchant has been paid at this point; a missing reference is
345
+ // a backend anomaly worth failing loudly on (500), not a 402.
346
+ if (!reference)
347
+ throw new Error(`nearintents-mpp-sdk: swap for ${recipient} reached SUCCESS but reported no settlement transaction hash.`);
348
+ const receipt = Types.toReceipt({
349
+ challengeId: challenge.id,
350
+ reference,
351
+ originTxHash: hash,
352
+ destinationNetwork: resolved.methodDetails.destinationNetwork,
353
+ ...(resolved.externalId !== undefined && { externalId: resolved.externalId }),
354
+ });
355
+ emit({
356
+ type: 'receipt.issued',
357
+ challengeId: challenge.id,
358
+ depositAddress: recipient,
359
+ originTxHash: hash,
360
+ reference,
361
+ });
362
+ return receipt;
363
+ }
364
+ // Non-success terminal (FAILED/REFUNDED/INCOMPLETE_DEPOSIT): the
365
+ // deposit is refunded to refundTo and the hash can never deliver —
366
+ // consume it. The client recovers with a fresh challenge.
367
+ hashOutcome = 'consume';
368
+ throw (OneClick.terminalError(status) ??
369
+ new SettlementFailedError({ reason: `unexpected terminal status ${status.status}` }));
370
+ }
371
+ catch (error) {
372
+ // Backend unavailability / settlement timeout: 5xx, never
373
+ // verification-failed; do not settle, release the claim so the same
374
+ // credential can be re-presented.
375
+ if (error instanceof OneClick.OneClickUnavailableError) {
376
+ emit({
377
+ type: 'settlement.suspended',
378
+ depositAddress: recipient,
379
+ originTxHash: hash,
380
+ reason: 'unavailable',
381
+ });
382
+ throw new SettlementUnavailableError({ reason: error.message });
383
+ }
384
+ if (error instanceof OneClick.PollTimeoutError) {
385
+ emit({
386
+ type: 'settlement.suspended',
387
+ depositAddress: recipient,
388
+ originTxHash: hash,
389
+ reason: 'timeout',
390
+ });
391
+ throw new SettlementTimeoutError({ timeoutMs: settlementTimeoutMs });
392
+ }
393
+ throw error;
394
+ }
395
+ finally {
396
+ if (hashOutcome === 'consume')
397
+ await store.put(hashKey(hash), { state: 'consumed' });
398
+ else
399
+ await store.delete(hashKey(hash));
400
+ }
401
+ },
402
+ });
403
+ }
404
+ //# sourceMappingURL=Charge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Charge.js","sourceRoot":"","sources":["../../src/server/Charge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * as Errors from '../Errors.js';
2
+ export * as Methods from '../Methods.js';
3
+ export * as Types from '../Types.js';
4
+ export * as nearintents from './Charge.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AACpC,OAAO,KAAK,WAAW,MAAM,aAAa,CAAA"}
@@ -0,0 +1,5 @@
1
+ export * as Errors from '../Errors.js';
2
+ export * as Methods from '../Methods.js';
3
+ export * as Types from '../Types.js';
4
+ export * as nearintents from './Charge.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,cAAc,CAAA;AACtC,OAAO,KAAK,OAAO,MAAM,eAAe,CAAA;AACxC,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AACpC,OAAO,KAAK,WAAW,MAAM,aAAa,CAAA"}
package/package.json CHANGED
@@ -1,12 +1,90 @@
1
1
  {
2
2
  "name": "@defuse-protocol/nearintents-mpp-sdk",
3
- "version": "0.0.0",
4
- "description": "",
5
- "main": "index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1"
3
+ "version": "0.1.1",
4
+ "description": "Reference implementation of the `nearintents` payment method for MPP (Machine Payments Protocol) — cross-chain HTTP 402 payments settled by NEAR Intents. Extends mppx.",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "license": "MIT",
8
+ "publishConfig": {
9
+ "access": "public",
10
+ "provenance": true
11
+ },
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/defuse-protocol/nearintents-mpp-sdk.git"
15
+ },
16
+ "homepage": "https://github.com/defuse-protocol/nearintents-mpp-sdk#readme",
17
+ "bugs": {
18
+ "url": "https://github.com/defuse-protocol/nearintents-mpp-sdk/issues"
19
+ },
20
+ "keywords": [
21
+ "mpp",
22
+ "machine-payments",
23
+ "http-402",
24
+ "payments",
25
+ "near",
26
+ "near-intents",
27
+ "cross-chain",
28
+ "typescript"
29
+ ],
30
+ "files": [
31
+ "dist",
32
+ "src",
33
+ "!src/**/*.test.ts"
34
+ ],
35
+ "main": "./dist/index.js",
36
+ "exports": {
37
+ ".": {
38
+ "types": "./dist/index.d.ts",
39
+ "default": "./dist/index.js"
40
+ },
41
+ "./client": {
42
+ "types": "./dist/client/index.d.ts",
43
+ "default": "./dist/client/index.js"
44
+ },
45
+ "./server": {
46
+ "types": "./dist/server/index.d.ts",
47
+ "default": "./dist/server/index.js"
48
+ }
49
+ },
50
+ "engines": {
51
+ "node": ">=20"
8
52
  },
9
- "keywords": [],
10
- "author": "",
11
- "license": "ISC"
12
- }
53
+ "dependencies": {
54
+ "zod": "^4.4.3"
55
+ },
56
+ "peerDependencies": {
57
+ "mppx": "0.8.13",
58
+ "viem": "^2.0.0"
59
+ },
60
+ "peerDependenciesMeta": {
61
+ "viem": {
62
+ "optional": true
63
+ }
64
+ },
65
+ "devDependencies": {
66
+ "@biomejs/biome": "^2.5.4",
67
+ "@changesets/cli": "^2.31.1",
68
+ "@types/node": "^26.1.1",
69
+ "mppx": "0.8.13",
70
+ "tsx": "^4.23.1",
71
+ "typescript": "~6.0.3",
72
+ "viem": "^2.55.4",
73
+ "vitest": "^4.1.10"
74
+ },
75
+ "scripts": {
76
+ "build": "tsc -p tsconfig.build.json",
77
+ "changeset": "changeset",
78
+ "check": "pnpm check:types && pnpm lint && pnpm test",
79
+ "check:types": "tsc --noEmit",
80
+ "demo:app": "pnpm -C demo/app dev",
81
+ "demo:build": "pnpm -C demo/app install && pnpm -C demo/app build",
82
+ "demo:server": "tsx --env-file-if-exists=.env demo/server/index.ts",
83
+ "example:client": "tsx --env-file-if-exists=.env examples/client.ts",
84
+ "example:server": "tsx --env-file-if-exists=.env examples/server.ts",
85
+ "lint": "biome check .",
86
+ "lint:fix": "biome check --write .",
87
+ "release": "pnpm build && changeset publish",
88
+ "test": "vitest run"
89
+ }
90
+ }
package/src/Errors.ts ADDED
@@ -0,0 +1,86 @@
1
+ import { Errors } from 'mppx'
2
+
3
+ /**
4
+ * The deposit was verified but the cross-chain swap did not complete
5
+ * (1Click terminal status `FAILED` or `REFUNDED`). The deposit is refunded to
6
+ * `methodDetails.refundTo`; the client recovers with a fresh challenge.
7
+ *
8
+ * Additional error code registered by the `nearintents` spec (§Error Codes).
9
+ */
10
+ export class SettlementFailedError extends Errors.PaymentError {
11
+ override readonly name = 'SettlementFailedError'
12
+ readonly title = 'Settlement Failed'
13
+ override readonly status: number = 402
14
+ readonly type = 'https://paymentauth.org/problems/settlement-failed'
15
+
16
+ constructor(options: SettlementFailedError.Options = {}) {
17
+ const { reason } = options
18
+ super(
19
+ reason
20
+ ? `Settlement failed: ${reason}.`
21
+ : 'Settlement failed: the cross-chain swap did not complete; the deposit is refunded to the refund address.',
22
+ )
23
+ }
24
+ }
25
+
26
+ export declare namespace SettlementFailedError {
27
+ type Options = {
28
+ /** Reason settlement failed (e.g. the 1Click refund reason). */
29
+ reason?: string | undefined
30
+ }
31
+ }
32
+
33
+ /**
34
+ * The 1Click backend was unreachable during a required check. Per the spec
35
+ * (§Verification), this MUST surface as an HTTP 5xx — never as
36
+ * `verification-failed` — and the credential MUST NOT be settled or consumed.
37
+ * The client retries the same credential once the backend recovers.
38
+ */
39
+ export class SettlementUnavailableError extends Errors.PaymentError {
40
+ override readonly name = 'SettlementUnavailableError'
41
+ readonly title = 'Settlement Backend Unavailable'
42
+ override readonly status: number = 503
43
+ readonly type = 'https://paymentauth.org/problems/server-error'
44
+
45
+ constructor(options: SettlementUnavailableError.Options = {}) {
46
+ const { reason } = options
47
+ super(
48
+ reason
49
+ ? `Settlement backend unavailable: ${reason}.`
50
+ : 'Settlement backend unavailable; retry the same credential later.',
51
+ )
52
+ }
53
+ }
54
+
55
+ export declare namespace SettlementUnavailableError {
56
+ type Options = {
57
+ reason?: string | undefined
58
+ }
59
+ }
60
+
61
+ /**
62
+ * Settlement did not reach a terminal state within the server's time budget.
63
+ * The swap may still complete; the credential is NOT consumed, so the client
64
+ * can re-present the same credential later (or wait for the refund path).
65
+ */
66
+ export class SettlementTimeoutError extends Errors.PaymentError {
67
+ override readonly name = 'SettlementTimeoutError'
68
+ readonly title = 'Settlement Timeout'
69
+ override readonly status: number = 504
70
+ readonly type = 'https://paymentauth.org/problems/server-error'
71
+
72
+ constructor(options: SettlementTimeoutError.Options = {}) {
73
+ const { timeoutMs } = options
74
+ super(
75
+ `Settlement did not reach a terminal state${
76
+ timeoutMs !== undefined ? ` within ${timeoutMs}ms` : ''
77
+ }; re-present the same credential later.`,
78
+ )
79
+ }
80
+ }
81
+
82
+ export declare namespace SettlementTimeoutError {
83
+ type Options = {
84
+ timeoutMs?: number | undefined
85
+ }
86
+ }
package/src/Methods.ts ADDED
@@ -0,0 +1,24 @@
1
+ import { Method } from 'mppx'
2
+
3
+ import * as Types from './Types.js'
4
+
5
+ /**
6
+ * NEAR Intents charge method — shared schema used by both server and client.
7
+ *
8
+ * The challenge `request` carries the origin-chain leg the client must pay
9
+ * (`recipient` is a unique single-use 1Click deposit address) plus the
10
+ * merchant's destination leg in `methodDetails`. The credential payload is
11
+ * the client's confirmed origin-chain deposit transaction hash (push mode).
12
+ *
13
+ * Spec: docs/spec/draft-nearintents-charge-00.md
14
+ */
15
+ export const charge = Method.from({
16
+ name: Types.paymentMethod,
17
+ intent: Types.chargeIntent,
18
+ schema: {
19
+ credential: {
20
+ payload: Types.HashPayloadSchema,
21
+ },
22
+ request: Types.ChargeRequestSchema,
23
+ },
24
+ })