@t402/aptos 2.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.
Files changed (42) hide show
  1. package/README.md +171 -0
  2. package/dist/exact-direct/client/index.d.cts +91 -0
  3. package/dist/exact-direct/client/index.d.ts +91 -0
  4. package/dist/exact-direct/client/index.js +203 -0
  5. package/dist/exact-direct/client/index.js.map +1 -0
  6. package/dist/exact-direct/client/index.mjs +175 -0
  7. package/dist/exact-direct/client/index.mjs.map +1 -0
  8. package/dist/exact-direct/facilitator/index.d.cts +110 -0
  9. package/dist/exact-direct/facilitator/index.d.ts +110 -0
  10. package/dist/exact-direct/facilitator/index.js +352 -0
  11. package/dist/exact-direct/facilitator/index.js.map +1 -0
  12. package/dist/exact-direct/facilitator/index.mjs +324 -0
  13. package/dist/exact-direct/facilitator/index.mjs.map +1 -0
  14. package/dist/exact-direct/server/index.d.cts +106 -0
  15. package/dist/exact-direct/server/index.d.ts +106 -0
  16. package/dist/exact-direct/server/index.js +220 -0
  17. package/dist/exact-direct/server/index.js.map +1 -0
  18. package/dist/exact-direct/server/index.mjs +192 -0
  19. package/dist/exact-direct/server/index.mjs.map +1 -0
  20. package/dist/index.d.cts +145 -0
  21. package/dist/index.d.ts +145 -0
  22. package/dist/index.js +759 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/index.mjs +687 -0
  25. package/dist/index.mjs.map +1 -0
  26. package/dist/types-kOweBf4U.d.cts +149 -0
  27. package/dist/types-kOweBf4U.d.ts +149 -0
  28. package/package.json +100 -0
  29. package/src/constants.ts +48 -0
  30. package/src/exact-direct/client/index.ts +12 -0
  31. package/src/exact-direct/client/register.ts +83 -0
  32. package/src/exact-direct/client/scheme.ts +148 -0
  33. package/src/exact-direct/facilitator/index.ts +12 -0
  34. package/src/exact-direct/facilitator/register.ts +74 -0
  35. package/src/exact-direct/facilitator/scheme.ts +300 -0
  36. package/src/exact-direct/server/index.ts +12 -0
  37. package/src/exact-direct/server/register.ts +65 -0
  38. package/src/exact-direct/server/scheme.ts +196 -0
  39. package/src/index.ts +58 -0
  40. package/src/tokens.ts +114 -0
  41. package/src/types.ts +174 -0
  42. package/src/utils.ts +240 -0
package/dist/index.js ADDED
@@ -0,0 +1,759 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ APTOS_ACCOUNT_MODULE: () => APTOS_ACCOUNT_MODULE,
24
+ APTOS_CAIP2_NAMESPACE: () => APTOS_CAIP2_NAMESPACE,
25
+ APTOS_DEVNET_CAIP2: () => APTOS_DEVNET_CAIP2,
26
+ APTOS_DEVNET_CHAIN_ID: () => APTOS_DEVNET_CHAIN_ID,
27
+ APTOS_MAINNET_CAIP2: () => APTOS_MAINNET_CAIP2,
28
+ APTOS_MAINNET_CHAIN_ID: () => APTOS_MAINNET_CHAIN_ID,
29
+ APTOS_NETWORKS: () => APTOS_NETWORKS,
30
+ APTOS_TESTNET_CAIP2: () => APTOS_TESTNET_CAIP2,
31
+ APTOS_TESTNET_CHAIN_ID: () => APTOS_TESTNET_CHAIN_ID,
32
+ DEFAULT_DEVNET_RPC: () => DEFAULT_DEVNET_RPC,
33
+ DEFAULT_GAS_UNIT_PRICE: () => DEFAULT_GAS_UNIT_PRICE,
34
+ DEFAULT_MAINNET_RPC: () => DEFAULT_MAINNET_RPC,
35
+ DEFAULT_MAX_GAS_AMOUNT: () => DEFAULT_MAX_GAS_AMOUNT,
36
+ DEFAULT_TESTNET_RPC: () => DEFAULT_TESTNET_RPC,
37
+ DEFAULT_TOKEN_SYMBOL: () => DEFAULT_TOKEN_SYMBOL,
38
+ DEFAULT_TX_EXPIRATION_SECONDS: () => DEFAULT_TX_EXPIRATION_SECONDS,
39
+ ExactDirectAptosClient: () => ExactDirectAptosClient,
40
+ ExactDirectAptosFacilitator: () => ExactDirectAptosFacilitator,
41
+ ExactDirectAptosServer: () => ExactDirectAptosServer,
42
+ FA_TRANSFER_FUNCTION: () => FA_TRANSFER_FUNCTION,
43
+ FUNGIBLE_ASSET_MODULE: () => FUNGIBLE_ASSET_MODULE,
44
+ PRIMARY_FUNGIBLE_STORE_MODULE: () => PRIMARY_FUNGIBLE_STORE_MODULE,
45
+ SCHEME_EXACT_DIRECT: () => SCHEME_EXACT_DIRECT,
46
+ TOKEN_REGISTRY: () => TOKEN_REGISTRY,
47
+ compareAddresses: () => compareAddresses,
48
+ createAssetIdentifier: () => createAssetIdentifier,
49
+ extractChainId: () => extractChainId,
50
+ extractTransferDetails: () => extractTransferDetails,
51
+ formatAmount: () => formatAmount,
52
+ getDefaultRpcUrl: () => getDefaultRpcUrl,
53
+ getDefaultToken: () => getDefaultToken,
54
+ getSupportedTokens: () => getSupportedTokens,
55
+ getTokenByAddress: () => getTokenByAddress,
56
+ getTokenConfig: () => getTokenConfig,
57
+ isAptosNetwork: () => isAptosNetwork,
58
+ isFATransferTransaction: () => isFATransferTransaction,
59
+ isTokenSupported: () => isTokenSupported,
60
+ isValidAptosAddress: () => isValidAptosAddress,
61
+ isValidTxHash: () => isValidTxHash,
62
+ normalizeAptosAddress: () => normalizeAptosAddress,
63
+ parseAmount: () => parseAmount,
64
+ parseAssetIdentifier: () => parseAssetIdentifier,
65
+ parseFATransferFromEvents: () => parseFATransferFromEvents,
66
+ registerExactDirectAptosClient: () => registerExactDirectAptosClient,
67
+ registerExactDirectAptosFacilitator: () => registerExactDirectAptosFacilitator,
68
+ registerExactDirectAptosServer: () => registerExactDirectAptosServer
69
+ });
70
+ module.exports = __toCommonJS(src_exports);
71
+
72
+ // src/constants.ts
73
+ var APTOS_CAIP2_NAMESPACE = "aptos";
74
+ var APTOS_MAINNET_CAIP2 = "aptos:1";
75
+ var APTOS_TESTNET_CAIP2 = "aptos:2";
76
+ var APTOS_DEVNET_CAIP2 = "aptos:149";
77
+ var APTOS_NETWORKS = [
78
+ APTOS_MAINNET_CAIP2,
79
+ APTOS_TESTNET_CAIP2,
80
+ APTOS_DEVNET_CAIP2
81
+ ];
82
+ var APTOS_MAINNET_CHAIN_ID = 1;
83
+ var APTOS_TESTNET_CHAIN_ID = 2;
84
+ var APTOS_DEVNET_CHAIN_ID = 149;
85
+ var DEFAULT_MAINNET_RPC = "https://fullnode.mainnet.aptoslabs.com/v1";
86
+ var DEFAULT_TESTNET_RPC = "https://fullnode.testnet.aptoslabs.com/v1";
87
+ var DEFAULT_DEVNET_RPC = "https://fullnode.devnet.aptoslabs.com/v1";
88
+ var SCHEME_EXACT_DIRECT = "exact-direct";
89
+ var PRIMARY_FUNGIBLE_STORE_MODULE = "0x1::primary_fungible_store";
90
+ var FUNGIBLE_ASSET_MODULE = "0x1::fungible_asset";
91
+ var APTOS_ACCOUNT_MODULE = "0x1::aptos_account";
92
+ var FA_TRANSFER_FUNCTION = `${PRIMARY_FUNGIBLE_STORE_MODULE}::transfer`;
93
+ var DEFAULT_MAX_GAS_AMOUNT = 100000n;
94
+ var DEFAULT_GAS_UNIT_PRICE = 100n;
95
+ var DEFAULT_TX_EXPIRATION_SECONDS = 600;
96
+
97
+ // src/types.ts
98
+ function extractChainId(network) {
99
+ const parts = network.split(":");
100
+ if (parts.length !== 2 || parts[0] !== "aptos") {
101
+ throw new Error(`Invalid Aptos network identifier: ${network}`);
102
+ }
103
+ const chainId = parseInt(parts[1], 10);
104
+ if (isNaN(chainId)) {
105
+ throw new Error(`Invalid chain ID in network identifier: ${network}`);
106
+ }
107
+ return chainId;
108
+ }
109
+
110
+ // src/tokens.ts
111
+ var TOKEN_REGISTRY = {
112
+ [APTOS_MAINNET_CAIP2]: [
113
+ {
114
+ metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
115
+ symbol: "USDT",
116
+ name: "Tether USD",
117
+ decimals: 6
118
+ },
119
+ {
120
+ metadataAddress: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
121
+ symbol: "USDC",
122
+ name: "USD Coin",
123
+ decimals: 6
124
+ }
125
+ ],
126
+ [APTOS_TESTNET_CAIP2]: [
127
+ {
128
+ // Testnet USDT (may differ from mainnet)
129
+ metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
130
+ symbol: "USDT",
131
+ name: "Tether USD",
132
+ decimals: 6
133
+ }
134
+ ],
135
+ [APTOS_DEVNET_CAIP2]: []
136
+ };
137
+ function getTokenConfig(network, symbol) {
138
+ const tokens = TOKEN_REGISTRY[network];
139
+ if (!tokens) return void 0;
140
+ return tokens.find(
141
+ (t) => t.symbol.toUpperCase() === symbol.toUpperCase()
142
+ );
143
+ }
144
+ function getSupportedTokens(network) {
145
+ return TOKEN_REGISTRY[network] || [];
146
+ }
147
+ function isTokenSupported(network, symbol) {
148
+ return getTokenConfig(network, symbol) !== void 0;
149
+ }
150
+ function getTokenByAddress(network, metadataAddress) {
151
+ const tokens = TOKEN_REGISTRY[network];
152
+ if (!tokens) return void 0;
153
+ const normalizedAddress = metadataAddress.toLowerCase();
154
+ return tokens.find(
155
+ (t) => t.metadataAddress.toLowerCase() === normalizedAddress
156
+ );
157
+ }
158
+ var DEFAULT_TOKEN_SYMBOL = "USDT";
159
+ function getDefaultToken(network) {
160
+ return getTokenConfig(network, DEFAULT_TOKEN_SYMBOL);
161
+ }
162
+
163
+ // src/utils.ts
164
+ function isValidAptosAddress(address) {
165
+ if (!address) return false;
166
+ if (!address.startsWith("0x")) return false;
167
+ const hex = address.slice(2);
168
+ if (hex.length === 0 || hex.length > 64) return false;
169
+ return /^[0-9a-fA-F]+$/.test(hex);
170
+ }
171
+ function normalizeAptosAddress(address) {
172
+ if (!address.startsWith("0x")) {
173
+ throw new Error("Aptos address must start with 0x");
174
+ }
175
+ const hex = address.slice(2).toLowerCase();
176
+ return "0x" + hex.padStart(64, "0");
177
+ }
178
+ function compareAddresses(addr1, addr2) {
179
+ try {
180
+ return normalizeAptosAddress(addr1) === normalizeAptosAddress(addr2);
181
+ } catch {
182
+ return false;
183
+ }
184
+ }
185
+ function isValidTxHash(txHash) {
186
+ if (!txHash) return false;
187
+ if (!txHash.startsWith("0x")) return false;
188
+ const hex = txHash.slice(2);
189
+ if (hex.length !== 64) return false;
190
+ return /^[0-9a-fA-F]+$/.test(hex);
191
+ }
192
+ function getDefaultRpcUrl(network) {
193
+ switch (network) {
194
+ case APTOS_MAINNET_CAIP2:
195
+ return DEFAULT_MAINNET_RPC;
196
+ case APTOS_TESTNET_CAIP2:
197
+ return DEFAULT_TESTNET_RPC;
198
+ case APTOS_DEVNET_CAIP2:
199
+ return DEFAULT_DEVNET_RPC;
200
+ default:
201
+ throw new Error(`Unknown Aptos network: ${network}`);
202
+ }
203
+ }
204
+ function isAptosNetwork(network) {
205
+ return network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`);
206
+ }
207
+ function parseAssetIdentifier(asset) {
208
+ const parts = asset.split("/");
209
+ if (parts.length !== 2) return null;
210
+ const network = parts[0];
211
+ if (!isAptosNetwork(network)) return null;
212
+ const [assetType, address] = parts[1].split(":");
213
+ if (assetType !== "fa" || !address) return null;
214
+ if (!isValidAptosAddress(address)) return null;
215
+ return { network, metadataAddress: address };
216
+ }
217
+ function createAssetIdentifier(network, metadataAddress) {
218
+ return `${network}/fa:${metadataAddress}`;
219
+ }
220
+ function parseFATransferFromEvents(events) {
221
+ const withdrawEvent = events.find(
222
+ (e) => e.type === "0x1::fungible_asset::Withdraw" || e.type.includes("::fungible_asset::Withdraw")
223
+ );
224
+ const depositEvent = events.find(
225
+ (e) => e.type === "0x1::fungible_asset::Deposit" || e.type.includes("::fungible_asset::Deposit")
226
+ );
227
+ if (!withdrawEvent || !depositEvent) {
228
+ return null;
229
+ }
230
+ const withdrawData = withdrawEvent.data;
231
+ const depositData = depositEvent.data;
232
+ if (!withdrawData.amount || !depositData.store) {
233
+ return null;
234
+ }
235
+ const from = withdrawEvent.guid.accountAddress;
236
+ const to = depositEvent.guid.accountAddress;
237
+ const amount = BigInt(withdrawData.amount);
238
+ return {
239
+ from,
240
+ to,
241
+ amount,
242
+ metadataAddress: ""
243
+ // Will be filled from transaction details
244
+ };
245
+ }
246
+ function isFATransferTransaction(tx) {
247
+ if (!tx.payload) return false;
248
+ if (tx.payload.type !== "entry_function_payload") return false;
249
+ return tx.payload.function === FA_TRANSFER_FUNCTION || tx.payload.function?.includes("primary_fungible_store::transfer") || false;
250
+ }
251
+ function extractTransferDetails(tx) {
252
+ if (!tx.success) return null;
253
+ if (!tx.payload || tx.payload.type !== "entry_function_payload") return null;
254
+ const args = tx.payload.arguments;
255
+ if (!args || args.length < 3) return null;
256
+ const metadataAddress = args[0];
257
+ const to = args[1];
258
+ const amount = BigInt(args[2]);
259
+ return {
260
+ from: tx.sender,
261
+ to,
262
+ amount,
263
+ metadataAddress
264
+ };
265
+ }
266
+ function formatAmount(amount, decimals) {
267
+ const divisor = BigInt(10 ** decimals);
268
+ const wholePart = amount / divisor;
269
+ const fractionalPart = amount % divisor;
270
+ const paddedFractional = fractionalPart.toString().padStart(decimals, "0");
271
+ return `${wholePart}.${paddedFractional}`;
272
+ }
273
+ function parseAmount(amount, decimals) {
274
+ const [whole, fractional = ""] = amount.split(".");
275
+ const paddedFractional = fractional.padEnd(decimals, "0").slice(0, decimals);
276
+ return BigInt(whole + paddedFractional);
277
+ }
278
+
279
+ // src/exact-direct/client/scheme.ts
280
+ var ExactDirectAptosClient = class {
281
+ constructor(signer, config = {}) {
282
+ this.signer = signer;
283
+ void config;
284
+ }
285
+ scheme = SCHEME_EXACT_DIRECT;
286
+ /**
287
+ * Create a payment payload by executing the transfer
288
+ */
289
+ async createPaymentPayload(t402Version, paymentRequirements) {
290
+ this.validateRequirements(paymentRequirements);
291
+ const from = await this.signer.getAddress();
292
+ const assetInfo = parseAssetIdentifier(paymentRequirements.asset);
293
+ if (!assetInfo) {
294
+ throw new Error(`Invalid asset identifier: ${paymentRequirements.asset}`);
295
+ }
296
+ const amount = BigInt(paymentRequirements.amount);
297
+ const balance = await this.signer.getBalance(assetInfo.metadataAddress);
298
+ if (balance < amount) {
299
+ throw new Error(
300
+ `Insufficient balance: have ${balance}, need ${amount}`
301
+ );
302
+ }
303
+ const txHash = await this.signer.transfer(
304
+ paymentRequirements.payTo,
305
+ assetInfo.metadataAddress,
306
+ amount
307
+ );
308
+ const payload = {
309
+ txHash,
310
+ from,
311
+ to: paymentRequirements.payTo,
312
+ amount: paymentRequirements.amount,
313
+ metadataAddress: assetInfo.metadataAddress
314
+ };
315
+ return {
316
+ t402Version,
317
+ payload
318
+ };
319
+ }
320
+ /**
321
+ * Validate payment requirements
322
+ */
323
+ validateRequirements(requirements) {
324
+ if (requirements.scheme !== SCHEME_EXACT_DIRECT) {
325
+ throw new Error(
326
+ `Invalid scheme: expected ${SCHEME_EXACT_DIRECT}, got ${requirements.scheme}`
327
+ );
328
+ }
329
+ if (!requirements.network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`)) {
330
+ throw new Error(`Invalid network: ${requirements.network}`);
331
+ }
332
+ if (!isValidAptosAddress(requirements.payTo)) {
333
+ throw new Error(`Invalid payTo address: ${requirements.payTo}`);
334
+ }
335
+ const amount = BigInt(requirements.amount);
336
+ if (amount <= 0n) {
337
+ throw new Error(`Invalid amount: ${requirements.amount}`);
338
+ }
339
+ const assetInfo = parseAssetIdentifier(requirements.asset);
340
+ if (!assetInfo) {
341
+ throw new Error(`Invalid asset: ${requirements.asset}`);
342
+ }
343
+ const tokenConfig = getTokenConfig(requirements.network, "USDT");
344
+ if (tokenConfig && !compareAddresses(tokenConfig.metadataAddress, assetInfo.metadataAddress)) {
345
+ console.warn(
346
+ `Using non-standard token: ${assetInfo.metadataAddress}`
347
+ );
348
+ }
349
+ }
350
+ };
351
+
352
+ // src/exact-direct/client/register.ts
353
+ function registerExactDirectAptosClient(client, config) {
354
+ const scheme = new ExactDirectAptosClient(config.signer, config.schemeConfig);
355
+ if (config.networks && config.networks.length > 0) {
356
+ config.networks.forEach((network) => {
357
+ client.register(network, scheme);
358
+ });
359
+ } else {
360
+ client.register("aptos:*", scheme);
361
+ }
362
+ if (config.policies) {
363
+ config.policies.forEach((policy) => {
364
+ client.registerPolicy(policy);
365
+ });
366
+ }
367
+ return client;
368
+ }
369
+
370
+ // src/exact-direct/server/scheme.ts
371
+ var ExactDirectAptosServer = class {
372
+ scheme = SCHEME_EXACT_DIRECT;
373
+ moneyParsers = [];
374
+ config;
375
+ constructor(config = {}) {
376
+ this.config = config;
377
+ }
378
+ /**
379
+ * Register a custom money parser in the parser chain.
380
+ */
381
+ registerMoneyParser(parser) {
382
+ this.moneyParsers.push(parser);
383
+ return this;
384
+ }
385
+ /**
386
+ * Parse price into Aptos-specific amount
387
+ */
388
+ async parsePrice(price, network) {
389
+ if (!isAptosNetwork(network)) {
390
+ throw new Error(`Invalid Aptos network: ${network}`);
391
+ }
392
+ if (typeof price === "object" && price !== null && "amount" in price) {
393
+ if (!price.asset) {
394
+ throw new Error(`Asset address must be specified for AssetAmount on network ${network}`);
395
+ }
396
+ return {
397
+ amount: price.amount,
398
+ asset: price.asset,
399
+ extra: price.extra || {}
400
+ };
401
+ }
402
+ const amount = this.parseMoneyToDecimal(price);
403
+ for (const parser of this.moneyParsers) {
404
+ const result = await parser(amount, network);
405
+ if (result !== null) {
406
+ return result;
407
+ }
408
+ }
409
+ return this.defaultMoneyConversion(amount, network);
410
+ }
411
+ /**
412
+ * Enhance payment requirements with Aptos-specific details
413
+ */
414
+ async enhancePaymentRequirements(paymentRequirements, supportedKind, facilitatorExtensions) {
415
+ void facilitatorExtensions;
416
+ const extra = { ...paymentRequirements.extra };
417
+ if (supportedKind.extra?.assetSymbol) {
418
+ extra.assetSymbol = supportedKind.extra.assetSymbol;
419
+ }
420
+ if (supportedKind.extra?.assetDecimals) {
421
+ extra.assetDecimals = supportedKind.extra.assetDecimals;
422
+ }
423
+ return {
424
+ ...paymentRequirements,
425
+ extra
426
+ };
427
+ }
428
+ /**
429
+ * Parse Money (string | number) to a decimal number.
430
+ */
431
+ parseMoneyToDecimal(money) {
432
+ if (typeof money === "number") {
433
+ return money;
434
+ }
435
+ const cleanMoney = money.replace(/^\$/, "").trim();
436
+ const amount = parseFloat(cleanMoney);
437
+ if (isNaN(amount)) {
438
+ throw new Error(`Invalid money format: ${money}`);
439
+ }
440
+ return amount;
441
+ }
442
+ /**
443
+ * Default money conversion implementation.
444
+ */
445
+ defaultMoneyConversion(amount, network) {
446
+ const token = this.getDefaultAsset(network);
447
+ const tokenAmount = parseAmount(amount.toString(), token.decimals);
448
+ return {
449
+ amount: tokenAmount.toString(),
450
+ asset: createAssetIdentifier(network, token.metadataAddress),
451
+ extra: {
452
+ symbol: token.symbol,
453
+ name: token.name,
454
+ decimals: token.decimals
455
+ }
456
+ };
457
+ }
458
+ /**
459
+ * Get the default asset info for a network.
460
+ */
461
+ getDefaultAsset(network) {
462
+ if (this.config.preferredToken) {
463
+ const preferred = getTokenConfig(network, this.config.preferredToken);
464
+ if (preferred) return preferred;
465
+ }
466
+ const defaultToken = getDefaultToken(network);
467
+ if (defaultToken) return defaultToken;
468
+ throw new Error(`No tokens configured for network ${network}`);
469
+ }
470
+ /**
471
+ * Get all supported networks
472
+ */
473
+ static getSupportedNetworks() {
474
+ return Object.keys(TOKEN_REGISTRY);
475
+ }
476
+ /**
477
+ * Check if a network is supported
478
+ */
479
+ static isNetworkSupported(network) {
480
+ return network in TOKEN_REGISTRY;
481
+ }
482
+ };
483
+
484
+ // src/exact-direct/server/register.ts
485
+ function registerExactDirectAptosServer(server, config = {}) {
486
+ const scheme = new ExactDirectAptosServer(config.schemeConfig);
487
+ if (config.networks && config.networks.length > 0) {
488
+ config.networks.forEach((network) => {
489
+ server.register(network, scheme);
490
+ });
491
+ } else {
492
+ server.register("aptos:*", scheme);
493
+ }
494
+ return server;
495
+ }
496
+
497
+ // src/exact-direct/facilitator/scheme.ts
498
+ var ExactDirectAptosFacilitator = class {
499
+ constructor(signer, config) {
500
+ this.signer = signer;
501
+ this.config = {
502
+ maxTransactionAge: config?.maxTransactionAge ?? 3600,
503
+ usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1e3
504
+ // 24 hours
505
+ };
506
+ this.startCleanupInterval();
507
+ }
508
+ scheme = SCHEME_EXACT_DIRECT;
509
+ caipFamily = `${APTOS_CAIP2_NAMESPACE}:*`;
510
+ config;
511
+ usedTxs = /* @__PURE__ */ new Map();
512
+ /**
513
+ * Get extra data for a supported kind
514
+ */
515
+ getExtra(network) {
516
+ const token = getDefaultToken(network);
517
+ if (!token) {
518
+ return void 0;
519
+ }
520
+ return {
521
+ assetSymbol: token.symbol,
522
+ assetDecimals: token.decimals
523
+ };
524
+ }
525
+ /**
526
+ * Get facilitator signer addresses for a network
527
+ */
528
+ getSigners(network) {
529
+ return this.signer.getAddresses(network);
530
+ }
531
+ /**
532
+ * Verify a payment payload
533
+ */
534
+ async verify(payload, requirements) {
535
+ if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {
536
+ return {
537
+ isValid: false,
538
+ invalidReason: "invalid_scheme"
539
+ };
540
+ }
541
+ if (!isAptosNetwork(payload.accepted.network)) {
542
+ return {
543
+ isValid: false,
544
+ invalidReason: "invalid_network"
545
+ };
546
+ }
547
+ const aptosPayload = payload.payload;
548
+ if (!isValidTxHash(aptosPayload.txHash)) {
549
+ return {
550
+ isValid: false,
551
+ invalidReason: "invalid_tx_hash_format"
552
+ };
553
+ }
554
+ if (this.isTxUsed(aptosPayload.txHash)) {
555
+ return {
556
+ isValid: false,
557
+ invalidReason: "transaction_already_used",
558
+ payer: aptosPayload.from
559
+ };
560
+ }
561
+ try {
562
+ const tx = await this.signer.queryTransaction(aptosPayload.txHash);
563
+ if (!tx) {
564
+ return {
565
+ isValid: false,
566
+ invalidReason: "transaction_not_found",
567
+ payer: aptosPayload.from
568
+ };
569
+ }
570
+ if (!tx.success) {
571
+ return {
572
+ isValid: false,
573
+ invalidReason: `transaction_failed: ${tx.vmStatus}`,
574
+ payer: aptosPayload.from
575
+ };
576
+ }
577
+ if (this.config.maxTransactionAge > 0) {
578
+ const txTimestamp = parseInt(tx.timestamp, 10) / 1e6;
579
+ const now = Date.now() / 1e3;
580
+ const age = now - txTimestamp;
581
+ if (age > this.config.maxTransactionAge) {
582
+ return {
583
+ isValid: false,
584
+ invalidReason: `transaction_too_old: ${Math.round(age)} seconds`,
585
+ payer: aptosPayload.from
586
+ };
587
+ }
588
+ }
589
+ const transferDetails = extractTransferDetails(tx);
590
+ if (!transferDetails) {
591
+ return {
592
+ isValid: false,
593
+ invalidReason: "could_not_extract_transfer_details",
594
+ payer: aptosPayload.from
595
+ };
596
+ }
597
+ const expectedAsset = parseAssetIdentifier(requirements.asset);
598
+ if (!expectedAsset) {
599
+ return {
600
+ isValid: false,
601
+ invalidReason: `invalid_asset_in_requirements: ${requirements.asset}`,
602
+ payer: aptosPayload.from
603
+ };
604
+ }
605
+ if (!compareAddresses(transferDetails.to, requirements.payTo)) {
606
+ return {
607
+ isValid: false,
608
+ invalidReason: `recipient_mismatch: expected ${requirements.payTo}, got ${transferDetails.to}`,
609
+ payer: aptosPayload.from
610
+ };
611
+ }
612
+ if (!compareAddresses(
613
+ transferDetails.metadataAddress,
614
+ expectedAsset.metadataAddress
615
+ )) {
616
+ return {
617
+ isValid: false,
618
+ invalidReason: `token_mismatch: expected ${expectedAsset.metadataAddress}, got ${transferDetails.metadataAddress}`,
619
+ payer: aptosPayload.from
620
+ };
621
+ }
622
+ const expectedAmount = BigInt(requirements.amount);
623
+ if (transferDetails.amount < expectedAmount) {
624
+ return {
625
+ isValid: false,
626
+ invalidReason: `insufficient_amount: expected ${expectedAmount}, got ${transferDetails.amount}`,
627
+ payer: aptosPayload.from
628
+ };
629
+ }
630
+ this.markTxUsed(aptosPayload.txHash);
631
+ return {
632
+ isValid: true,
633
+ payer: transferDetails.from
634
+ };
635
+ } catch (error) {
636
+ return {
637
+ isValid: false,
638
+ invalidReason: `verification_error: ${error instanceof Error ? error.message : String(error)}`,
639
+ payer: aptosPayload.from
640
+ };
641
+ }
642
+ }
643
+ /**
644
+ * Settle a payment (no-op for exact-direct since client already executed)
645
+ */
646
+ async settle(payload, requirements) {
647
+ const verifyResult = await this.verify(payload, requirements);
648
+ if (!verifyResult.isValid) {
649
+ return {
650
+ success: false,
651
+ errorReason: verifyResult.invalidReason || "verification_failed",
652
+ payer: verifyResult.payer,
653
+ transaction: "",
654
+ network: requirements.network
655
+ };
656
+ }
657
+ const aptosPayload = payload.payload;
658
+ return {
659
+ success: true,
660
+ transaction: aptosPayload.txHash,
661
+ network: requirements.network,
662
+ payer: aptosPayload.from
663
+ };
664
+ }
665
+ /**
666
+ * Check if a transaction has been used
667
+ */
668
+ isTxUsed(txHash) {
669
+ return this.usedTxs.has(txHash.toLowerCase());
670
+ }
671
+ /**
672
+ * Mark a transaction as used
673
+ */
674
+ markTxUsed(txHash) {
675
+ this.usedTxs.set(txHash.toLowerCase(), Date.now());
676
+ }
677
+ /**
678
+ * Start the cleanup interval for used transactions
679
+ */
680
+ startCleanupInterval() {
681
+ setInterval(
682
+ () => {
683
+ const cutoff = Date.now() - this.config.usedTxCacheDuration;
684
+ for (const [txHash, usedAt] of this.usedTxs.entries()) {
685
+ if (usedAt < cutoff) {
686
+ this.usedTxs.delete(txHash);
687
+ }
688
+ }
689
+ },
690
+ 60 * 60 * 1e3
691
+ );
692
+ }
693
+ };
694
+
695
+ // src/exact-direct/facilitator/register.ts
696
+ function registerExactDirectAptosFacilitator(facilitator, config) {
697
+ const scheme = new ExactDirectAptosFacilitator(
698
+ config.signer,
699
+ config.schemeConfig
700
+ );
701
+ if (config.networks && config.networks.length > 0) {
702
+ config.networks.forEach((network) => {
703
+ facilitator.register(network, scheme);
704
+ });
705
+ } else {
706
+ facilitator.register("aptos:*", scheme);
707
+ }
708
+ return facilitator;
709
+ }
710
+ // Annotate the CommonJS export names for ESM import in node:
711
+ 0 && (module.exports = {
712
+ APTOS_ACCOUNT_MODULE,
713
+ APTOS_CAIP2_NAMESPACE,
714
+ APTOS_DEVNET_CAIP2,
715
+ APTOS_DEVNET_CHAIN_ID,
716
+ APTOS_MAINNET_CAIP2,
717
+ APTOS_MAINNET_CHAIN_ID,
718
+ APTOS_NETWORKS,
719
+ APTOS_TESTNET_CAIP2,
720
+ APTOS_TESTNET_CHAIN_ID,
721
+ DEFAULT_DEVNET_RPC,
722
+ DEFAULT_GAS_UNIT_PRICE,
723
+ DEFAULT_MAINNET_RPC,
724
+ DEFAULT_MAX_GAS_AMOUNT,
725
+ DEFAULT_TESTNET_RPC,
726
+ DEFAULT_TOKEN_SYMBOL,
727
+ DEFAULT_TX_EXPIRATION_SECONDS,
728
+ ExactDirectAptosClient,
729
+ ExactDirectAptosFacilitator,
730
+ ExactDirectAptosServer,
731
+ FA_TRANSFER_FUNCTION,
732
+ FUNGIBLE_ASSET_MODULE,
733
+ PRIMARY_FUNGIBLE_STORE_MODULE,
734
+ SCHEME_EXACT_DIRECT,
735
+ TOKEN_REGISTRY,
736
+ compareAddresses,
737
+ createAssetIdentifier,
738
+ extractChainId,
739
+ extractTransferDetails,
740
+ formatAmount,
741
+ getDefaultRpcUrl,
742
+ getDefaultToken,
743
+ getSupportedTokens,
744
+ getTokenByAddress,
745
+ getTokenConfig,
746
+ isAptosNetwork,
747
+ isFATransferTransaction,
748
+ isTokenSupported,
749
+ isValidAptosAddress,
750
+ isValidTxHash,
751
+ normalizeAptosAddress,
752
+ parseAmount,
753
+ parseAssetIdentifier,
754
+ parseFATransferFromEvents,
755
+ registerExactDirectAptosClient,
756
+ registerExactDirectAptosFacilitator,
757
+ registerExactDirectAptosServer
758
+ });
759
+ //# sourceMappingURL=index.js.map