@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
@@ -0,0 +1,352 @@
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/exact-direct/facilitator/index.ts
21
+ var facilitator_exports = {};
22
+ __export(facilitator_exports, {
23
+ ExactDirectAptosFacilitator: () => ExactDirectAptosFacilitator,
24
+ registerExactDirectAptosFacilitator: () => registerExactDirectAptosFacilitator
25
+ });
26
+ module.exports = __toCommonJS(facilitator_exports);
27
+
28
+ // src/constants.ts
29
+ var APTOS_CAIP2_NAMESPACE = "aptos";
30
+ var APTOS_MAINNET_CAIP2 = "aptos:1";
31
+ var APTOS_TESTNET_CAIP2 = "aptos:2";
32
+ var APTOS_DEVNET_CAIP2 = "aptos:149";
33
+ var SCHEME_EXACT_DIRECT = "exact-direct";
34
+ var PRIMARY_FUNGIBLE_STORE_MODULE = "0x1::primary_fungible_store";
35
+ var FA_TRANSFER_FUNCTION = `${PRIMARY_FUNGIBLE_STORE_MODULE}::transfer`;
36
+
37
+ // src/utils.ts
38
+ function isValidAptosAddress(address) {
39
+ if (!address) return false;
40
+ if (!address.startsWith("0x")) return false;
41
+ const hex = address.slice(2);
42
+ if (hex.length === 0 || hex.length > 64) return false;
43
+ return /^[0-9a-fA-F]+$/.test(hex);
44
+ }
45
+ function normalizeAptosAddress(address) {
46
+ if (!address.startsWith("0x")) {
47
+ throw new Error("Aptos address must start with 0x");
48
+ }
49
+ const hex = address.slice(2).toLowerCase();
50
+ return "0x" + hex.padStart(64, "0");
51
+ }
52
+ function compareAddresses(addr1, addr2) {
53
+ try {
54
+ return normalizeAptosAddress(addr1) === normalizeAptosAddress(addr2);
55
+ } catch {
56
+ return false;
57
+ }
58
+ }
59
+ function isValidTxHash(txHash) {
60
+ if (!txHash) return false;
61
+ if (!txHash.startsWith("0x")) return false;
62
+ const hex = txHash.slice(2);
63
+ if (hex.length !== 64) return false;
64
+ return /^[0-9a-fA-F]+$/.test(hex);
65
+ }
66
+ function isAptosNetwork(network) {
67
+ return network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`);
68
+ }
69
+ function parseAssetIdentifier(asset) {
70
+ const parts = asset.split("/");
71
+ if (parts.length !== 2) return null;
72
+ const network = parts[0];
73
+ if (!isAptosNetwork(network)) return null;
74
+ const [assetType, address] = parts[1].split(":");
75
+ if (assetType !== "fa" || !address) return null;
76
+ if (!isValidAptosAddress(address)) return null;
77
+ return { network, metadataAddress: address };
78
+ }
79
+ function extractTransferDetails(tx) {
80
+ if (!tx.success) return null;
81
+ if (!tx.payload || tx.payload.type !== "entry_function_payload") return null;
82
+ const args = tx.payload.arguments;
83
+ if (!args || args.length < 3) return null;
84
+ const metadataAddress = args[0];
85
+ const to = args[1];
86
+ const amount = BigInt(args[2]);
87
+ return {
88
+ from: tx.sender,
89
+ to,
90
+ amount,
91
+ metadataAddress
92
+ };
93
+ }
94
+
95
+ // src/tokens.ts
96
+ var TOKEN_REGISTRY = {
97
+ [APTOS_MAINNET_CAIP2]: [
98
+ {
99
+ metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
100
+ symbol: "USDT",
101
+ name: "Tether USD",
102
+ decimals: 6
103
+ },
104
+ {
105
+ metadataAddress: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
106
+ symbol: "USDC",
107
+ name: "USD Coin",
108
+ decimals: 6
109
+ }
110
+ ],
111
+ [APTOS_TESTNET_CAIP2]: [
112
+ {
113
+ // Testnet USDT (may differ from mainnet)
114
+ metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
115
+ symbol: "USDT",
116
+ name: "Tether USD",
117
+ decimals: 6
118
+ }
119
+ ],
120
+ [APTOS_DEVNET_CAIP2]: []
121
+ };
122
+ function getTokenConfig(network, symbol) {
123
+ const tokens = TOKEN_REGISTRY[network];
124
+ if (!tokens) return void 0;
125
+ return tokens.find(
126
+ (t) => t.symbol.toUpperCase() === symbol.toUpperCase()
127
+ );
128
+ }
129
+ var DEFAULT_TOKEN_SYMBOL = "USDT";
130
+ function getDefaultToken(network) {
131
+ return getTokenConfig(network, DEFAULT_TOKEN_SYMBOL);
132
+ }
133
+
134
+ // src/exact-direct/facilitator/scheme.ts
135
+ var ExactDirectAptosFacilitator = class {
136
+ constructor(signer, config) {
137
+ this.signer = signer;
138
+ this.config = {
139
+ maxTransactionAge: config?.maxTransactionAge ?? 3600,
140
+ usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1e3
141
+ // 24 hours
142
+ };
143
+ this.startCleanupInterval();
144
+ }
145
+ scheme = SCHEME_EXACT_DIRECT;
146
+ caipFamily = `${APTOS_CAIP2_NAMESPACE}:*`;
147
+ config;
148
+ usedTxs = /* @__PURE__ */ new Map();
149
+ /**
150
+ * Get extra data for a supported kind
151
+ */
152
+ getExtra(network) {
153
+ const token = getDefaultToken(network);
154
+ if (!token) {
155
+ return void 0;
156
+ }
157
+ return {
158
+ assetSymbol: token.symbol,
159
+ assetDecimals: token.decimals
160
+ };
161
+ }
162
+ /**
163
+ * Get facilitator signer addresses for a network
164
+ */
165
+ getSigners(network) {
166
+ return this.signer.getAddresses(network);
167
+ }
168
+ /**
169
+ * Verify a payment payload
170
+ */
171
+ async verify(payload, requirements) {
172
+ if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {
173
+ return {
174
+ isValid: false,
175
+ invalidReason: "invalid_scheme"
176
+ };
177
+ }
178
+ if (!isAptosNetwork(payload.accepted.network)) {
179
+ return {
180
+ isValid: false,
181
+ invalidReason: "invalid_network"
182
+ };
183
+ }
184
+ const aptosPayload = payload.payload;
185
+ if (!isValidTxHash(aptosPayload.txHash)) {
186
+ return {
187
+ isValid: false,
188
+ invalidReason: "invalid_tx_hash_format"
189
+ };
190
+ }
191
+ if (this.isTxUsed(aptosPayload.txHash)) {
192
+ return {
193
+ isValid: false,
194
+ invalidReason: "transaction_already_used",
195
+ payer: aptosPayload.from
196
+ };
197
+ }
198
+ try {
199
+ const tx = await this.signer.queryTransaction(aptosPayload.txHash);
200
+ if (!tx) {
201
+ return {
202
+ isValid: false,
203
+ invalidReason: "transaction_not_found",
204
+ payer: aptosPayload.from
205
+ };
206
+ }
207
+ if (!tx.success) {
208
+ return {
209
+ isValid: false,
210
+ invalidReason: `transaction_failed: ${tx.vmStatus}`,
211
+ payer: aptosPayload.from
212
+ };
213
+ }
214
+ if (this.config.maxTransactionAge > 0) {
215
+ const txTimestamp = parseInt(tx.timestamp, 10) / 1e6;
216
+ const now = Date.now() / 1e3;
217
+ const age = now - txTimestamp;
218
+ if (age > this.config.maxTransactionAge) {
219
+ return {
220
+ isValid: false,
221
+ invalidReason: `transaction_too_old: ${Math.round(age)} seconds`,
222
+ payer: aptosPayload.from
223
+ };
224
+ }
225
+ }
226
+ const transferDetails = extractTransferDetails(tx);
227
+ if (!transferDetails) {
228
+ return {
229
+ isValid: false,
230
+ invalidReason: "could_not_extract_transfer_details",
231
+ payer: aptosPayload.from
232
+ };
233
+ }
234
+ const expectedAsset = parseAssetIdentifier(requirements.asset);
235
+ if (!expectedAsset) {
236
+ return {
237
+ isValid: false,
238
+ invalidReason: `invalid_asset_in_requirements: ${requirements.asset}`,
239
+ payer: aptosPayload.from
240
+ };
241
+ }
242
+ if (!compareAddresses(transferDetails.to, requirements.payTo)) {
243
+ return {
244
+ isValid: false,
245
+ invalidReason: `recipient_mismatch: expected ${requirements.payTo}, got ${transferDetails.to}`,
246
+ payer: aptosPayload.from
247
+ };
248
+ }
249
+ if (!compareAddresses(
250
+ transferDetails.metadataAddress,
251
+ expectedAsset.metadataAddress
252
+ )) {
253
+ return {
254
+ isValid: false,
255
+ invalidReason: `token_mismatch: expected ${expectedAsset.metadataAddress}, got ${transferDetails.metadataAddress}`,
256
+ payer: aptosPayload.from
257
+ };
258
+ }
259
+ const expectedAmount = BigInt(requirements.amount);
260
+ if (transferDetails.amount < expectedAmount) {
261
+ return {
262
+ isValid: false,
263
+ invalidReason: `insufficient_amount: expected ${expectedAmount}, got ${transferDetails.amount}`,
264
+ payer: aptosPayload.from
265
+ };
266
+ }
267
+ this.markTxUsed(aptosPayload.txHash);
268
+ return {
269
+ isValid: true,
270
+ payer: transferDetails.from
271
+ };
272
+ } catch (error) {
273
+ return {
274
+ isValid: false,
275
+ invalidReason: `verification_error: ${error instanceof Error ? error.message : String(error)}`,
276
+ payer: aptosPayload.from
277
+ };
278
+ }
279
+ }
280
+ /**
281
+ * Settle a payment (no-op for exact-direct since client already executed)
282
+ */
283
+ async settle(payload, requirements) {
284
+ const verifyResult = await this.verify(payload, requirements);
285
+ if (!verifyResult.isValid) {
286
+ return {
287
+ success: false,
288
+ errorReason: verifyResult.invalidReason || "verification_failed",
289
+ payer: verifyResult.payer,
290
+ transaction: "",
291
+ network: requirements.network
292
+ };
293
+ }
294
+ const aptosPayload = payload.payload;
295
+ return {
296
+ success: true,
297
+ transaction: aptosPayload.txHash,
298
+ network: requirements.network,
299
+ payer: aptosPayload.from
300
+ };
301
+ }
302
+ /**
303
+ * Check if a transaction has been used
304
+ */
305
+ isTxUsed(txHash) {
306
+ return this.usedTxs.has(txHash.toLowerCase());
307
+ }
308
+ /**
309
+ * Mark a transaction as used
310
+ */
311
+ markTxUsed(txHash) {
312
+ this.usedTxs.set(txHash.toLowerCase(), Date.now());
313
+ }
314
+ /**
315
+ * Start the cleanup interval for used transactions
316
+ */
317
+ startCleanupInterval() {
318
+ setInterval(
319
+ () => {
320
+ const cutoff = Date.now() - this.config.usedTxCacheDuration;
321
+ for (const [txHash, usedAt] of this.usedTxs.entries()) {
322
+ if (usedAt < cutoff) {
323
+ this.usedTxs.delete(txHash);
324
+ }
325
+ }
326
+ },
327
+ 60 * 60 * 1e3
328
+ );
329
+ }
330
+ };
331
+
332
+ // src/exact-direct/facilitator/register.ts
333
+ function registerExactDirectAptosFacilitator(facilitator, config) {
334
+ const scheme = new ExactDirectAptosFacilitator(
335
+ config.signer,
336
+ config.schemeConfig
337
+ );
338
+ if (config.networks && config.networks.length > 0) {
339
+ config.networks.forEach((network) => {
340
+ facilitator.register(network, scheme);
341
+ });
342
+ } else {
343
+ facilitator.register("aptos:*", scheme);
344
+ }
345
+ return facilitator;
346
+ }
347
+ // Annotate the CommonJS export names for ESM import in node:
348
+ 0 && (module.exports = {
349
+ ExactDirectAptosFacilitator,
350
+ registerExactDirectAptosFacilitator
351
+ });
352
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/exact-direct/facilitator/index.ts","../../../src/constants.ts","../../../src/utils.ts","../../../src/tokens.ts","../../../src/exact-direct/facilitator/scheme.ts","../../../src/exact-direct/facilitator/register.ts"],"sourcesContent":["/**\n * Aptos Exact-Direct Facilitator Exports\n */\n\nexport {\n ExactDirectAptosFacilitator,\n type ExactDirectAptosFacilitatorConfig,\n} from \"./scheme.js\";\nexport {\n registerExactDirectAptosFacilitator,\n type AptosFacilitatorConfig,\n} from \"./register.js\";\n","/**\n * Aptos Network Constants\n */\n\n// CAIP-2 namespace for Aptos\nexport const APTOS_CAIP2_NAMESPACE = \"aptos\";\n\n// Standard Aptos network identifiers (CAIP-2 format)\nexport const APTOS_MAINNET_CAIP2 = \"aptos:1\";\nexport const APTOS_TESTNET_CAIP2 = \"aptos:2\";\nexport const APTOS_DEVNET_CAIP2 = \"aptos:149\";\n\n// All supported Aptos networks\nexport const APTOS_NETWORKS = [\n APTOS_MAINNET_CAIP2,\n APTOS_TESTNET_CAIP2,\n APTOS_DEVNET_CAIP2,\n] as const;\n\nexport type AptosNetwork = (typeof APTOS_NETWORKS)[number];\n\n// Chain IDs\nexport const APTOS_MAINNET_CHAIN_ID = 1;\nexport const APTOS_TESTNET_CHAIN_ID = 2;\nexport const APTOS_DEVNET_CHAIN_ID = 149;\n\n// RPC endpoints\nexport const DEFAULT_MAINNET_RPC = \"https://fullnode.mainnet.aptoslabs.com/v1\";\nexport const DEFAULT_TESTNET_RPC = \"https://fullnode.testnet.aptoslabs.com/v1\";\nexport const DEFAULT_DEVNET_RPC = \"https://fullnode.devnet.aptoslabs.com/v1\";\n\n// Scheme identifier\nexport const SCHEME_EXACT_DIRECT = \"exact-direct\";\n\n// Fungible Asset module addresses\nexport const PRIMARY_FUNGIBLE_STORE_MODULE = \"0x1::primary_fungible_store\";\nexport const FUNGIBLE_ASSET_MODULE = \"0x1::fungible_asset\";\nexport const APTOS_ACCOUNT_MODULE = \"0x1::aptos_account\";\n\n// Transfer function\nexport const FA_TRANSFER_FUNCTION = `${PRIMARY_FUNGIBLE_STORE_MODULE}::transfer`;\n\n// Default gas configuration\nexport const DEFAULT_MAX_GAS_AMOUNT = 100000n;\nexport const DEFAULT_GAS_UNIT_PRICE = 100n;\n\n// Transaction expiration (in seconds)\nexport const DEFAULT_TX_EXPIRATION_SECONDS = 600; // 10 minutes\n","/**\n * Aptos Utility Functions\n */\n\nimport type { Network } from \"@t402/core/types\";\nimport {\n APTOS_CAIP2_NAMESPACE,\n APTOS_MAINNET_CAIP2,\n APTOS_TESTNET_CAIP2,\n APTOS_DEVNET_CAIP2,\n DEFAULT_MAINNET_RPC,\n DEFAULT_TESTNET_RPC,\n DEFAULT_DEVNET_RPC,\n FA_TRANSFER_FUNCTION,\n} from \"./constants.js\";\nimport type {\n AptosTransactionResult,\n AptosTransactionEvent,\n ParsedFATransfer,\n} from \"./types.js\";\n\n/**\n * Validate Aptos address format\n * Aptos addresses are 64 hex characters (32 bytes) with 0x prefix\n */\nexport function isValidAptosAddress(address: string): boolean {\n if (!address) return false;\n // Must start with 0x\n if (!address.startsWith(\"0x\")) return false;\n // Remove 0x prefix and check hex\n const hex = address.slice(2);\n // Aptos addresses can be 1-64 hex chars (leading zeros may be omitted)\n if (hex.length === 0 || hex.length > 64) return false;\n return /^[0-9a-fA-F]+$/.test(hex);\n}\n\n/**\n * Normalize Aptos address to full 64-character format\n */\nexport function normalizeAptosAddress(address: string): string {\n if (!address.startsWith(\"0x\")) {\n throw new Error(\"Aptos address must start with 0x\");\n }\n const hex = address.slice(2).toLowerCase();\n // Pad to 64 characters\n return \"0x\" + hex.padStart(64, \"0\");\n}\n\n/**\n * Compare two Aptos addresses (case-insensitive, handles short addresses)\n */\nexport function compareAddresses(addr1: string, addr2: string): boolean {\n try {\n return normalizeAptosAddress(addr1) === normalizeAptosAddress(addr2);\n } catch {\n return false;\n }\n}\n\n/**\n * Validate transaction hash format\n */\nexport function isValidTxHash(txHash: string): boolean {\n if (!txHash) return false;\n if (!txHash.startsWith(\"0x\")) return false;\n const hex = txHash.slice(2);\n // Transaction hash is 64 hex characters (32 bytes)\n if (hex.length !== 64) return false;\n return /^[0-9a-fA-F]+$/.test(hex);\n}\n\n/**\n * Get default RPC URL for a network\n */\nexport function getDefaultRpcUrl(network: Network): string {\n switch (network) {\n case APTOS_MAINNET_CAIP2:\n return DEFAULT_MAINNET_RPC;\n case APTOS_TESTNET_CAIP2:\n return DEFAULT_TESTNET_RPC;\n case APTOS_DEVNET_CAIP2:\n return DEFAULT_DEVNET_RPC;\n default:\n throw new Error(`Unknown Aptos network: ${network}`);\n }\n}\n\n/**\n * Check if a network identifier is for Aptos\n */\nexport function isAptosNetwork(network: Network): boolean {\n return network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`);\n}\n\n/**\n * Parse CAIP-19 asset identifier for Aptos\n * Format: aptos:1/fa:0x...\n */\nexport function parseAssetIdentifier(asset: string): {\n network: Network;\n metadataAddress: string;\n} | null {\n const parts = asset.split(\"/\");\n if (parts.length !== 2) return null;\n\n const network = parts[0] as Network;\n if (!isAptosNetwork(network)) return null;\n\n const [assetType, address] = parts[1].split(\":\");\n if (assetType !== \"fa\" || !address) return null;\n\n if (!isValidAptosAddress(address)) return null;\n\n return { network, metadataAddress: address };\n}\n\n/**\n * Create CAIP-19 asset identifier for Aptos FA\n */\nexport function createAssetIdentifier(\n network: Network,\n metadataAddress: string,\n): string {\n return `${network}/fa:${metadataAddress}`;\n}\n\n/**\n * Parse fungible asset transfer from transaction events\n */\nexport function parseFATransferFromEvents(\n events: AptosTransactionEvent[],\n): ParsedFATransfer | null {\n // Look for Withdraw and Deposit events\n const withdrawEvent = events.find(\n (e) =>\n e.type === \"0x1::fungible_asset::Withdraw\" ||\n e.type.includes(\"::fungible_asset::Withdraw\"),\n );\n const depositEvent = events.find(\n (e) =>\n e.type === \"0x1::fungible_asset::Deposit\" ||\n e.type.includes(\"::fungible_asset::Deposit\"),\n );\n\n if (!withdrawEvent || !depositEvent) {\n return null;\n }\n\n // Extract data from events\n const withdrawData = withdrawEvent.data as {\n store?: string;\n amount?: string;\n };\n const depositData = depositEvent.data as {\n store?: string;\n amount?: string;\n };\n\n if (!withdrawData.amount || !depositData.store) {\n return null;\n }\n\n // The from address is the account that owns the withdraw store\n // The to address is the account that owns the deposit store\n // For simplicity, we'll extract from the event guid\n const from = withdrawEvent.guid.accountAddress;\n const to = depositEvent.guid.accountAddress;\n const amount = BigInt(withdrawData.amount);\n\n // Metadata address would need to be extracted from state changes\n // For now, return with empty metadata (to be filled by caller)\n return {\n from,\n to,\n amount,\n metadataAddress: \"\", // Will be filled from transaction details\n };\n}\n\n/**\n * Check if transaction is a FA transfer\n */\nexport function isFATransferTransaction(tx: AptosTransactionResult): boolean {\n if (!tx.payload) return false;\n if (tx.payload.type !== \"entry_function_payload\") return false;\n return (\n tx.payload.function === FA_TRANSFER_FUNCTION ||\n tx.payload.function?.includes(\"primary_fungible_store::transfer\") ||\n false\n );\n}\n\n/**\n * Extract transfer details from transaction\n */\nexport function extractTransferDetails(\n tx: AptosTransactionResult,\n): ParsedFATransfer | null {\n if (!tx.success) return null;\n if (!tx.payload || tx.payload.type !== \"entry_function_payload\") return null;\n\n const args = tx.payload.arguments;\n if (!args || args.length < 3) return null;\n\n // Arguments for primary_fungible_store::transfer:\n // [0] - metadata object address\n // [1] - recipient address\n // [2] - amount\n\n const metadataAddress = args[0] as string;\n const to = args[1] as string;\n const amount = BigInt(args[2] as string);\n\n return {\n from: tx.sender,\n to,\n amount,\n metadataAddress,\n };\n}\n\n/**\n * Format amount with decimals for display\n */\nexport function formatAmount(amount: bigint, decimals: number): string {\n const divisor = BigInt(10 ** decimals);\n const wholePart = amount / divisor;\n const fractionalPart = amount % divisor;\n const paddedFractional = fractionalPart.toString().padStart(decimals, \"0\");\n return `${wholePart}.${paddedFractional}`;\n}\n\n/**\n * Parse amount string to bigint\n */\nexport function parseAmount(amount: string, decimals: number): bigint {\n const [whole, fractional = \"\"] = amount.split(\".\");\n const paddedFractional = fractional.padEnd(decimals, \"0\").slice(0, decimals);\n return BigInt(whole + paddedFractional);\n}\n","/**\n * Aptos Token Registry\n *\n * Token addresses for supported stablecoins on Aptos networks.\n * All tokens use the Fungible Asset (FA) standard.\n */\n\nimport {\n APTOS_MAINNET_CAIP2,\n APTOS_TESTNET_CAIP2,\n APTOS_DEVNET_CAIP2,\n} from \"./constants.js\";\n\n/**\n * Token configuration for Aptos fungible assets\n */\nexport interface TokenConfig {\n /** Fungible Asset metadata address */\n metadataAddress: string;\n /** Token symbol (e.g., \"USDT\", \"USDC\") */\n symbol: string;\n /** Token name */\n name: string;\n /** Decimal places */\n decimals: number;\n}\n\n/**\n * Token registry mapping network -> tokens\n */\nexport const TOKEN_REGISTRY: Record<string, TokenConfig[]> = {\n [APTOS_MAINNET_CAIP2]: [\n {\n metadataAddress:\n \"0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb\",\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n },\n {\n metadataAddress:\n \"0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b\",\n symbol: \"USDC\",\n name: \"USD Coin\",\n decimals: 6,\n },\n ],\n [APTOS_TESTNET_CAIP2]: [\n {\n // Testnet USDT (may differ from mainnet)\n metadataAddress:\n \"0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb\",\n symbol: \"USDT\",\n name: \"Tether USD\",\n decimals: 6,\n },\n ],\n [APTOS_DEVNET_CAIP2]: [],\n};\n\n/**\n * Get token configuration for a specific network and symbol\n */\nexport function getTokenConfig(\n network: string,\n symbol: string,\n): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n return tokens.find(\n (t) => t.symbol.toUpperCase() === symbol.toUpperCase(),\n );\n}\n\n/**\n * Get all supported tokens for a network\n */\nexport function getSupportedTokens(network: string): TokenConfig[] {\n return TOKEN_REGISTRY[network] || [];\n}\n\n/**\n * Check if a token is supported on a network\n */\nexport function isTokenSupported(network: string, symbol: string): boolean {\n return getTokenConfig(network, symbol) !== undefined;\n}\n\n/**\n * Get token by metadata address\n */\nexport function getTokenByAddress(\n network: string,\n metadataAddress: string,\n): TokenConfig | undefined {\n const tokens = TOKEN_REGISTRY[network];\n if (!tokens) return undefined;\n const normalizedAddress = metadataAddress.toLowerCase();\n return tokens.find(\n (t) => t.metadataAddress.toLowerCase() === normalizedAddress,\n );\n}\n\n/**\n * Default token symbol for payments (USDT)\n */\nexport const DEFAULT_TOKEN_SYMBOL = \"USDT\";\n\n/**\n * Get the default token for a network\n */\nexport function getDefaultToken(network: string): TokenConfig | undefined {\n return getTokenConfig(network, DEFAULT_TOKEN_SYMBOL);\n}\n","/**\n * Aptos Exact-Direct Facilitator Scheme\n *\n * Verifies FA transfer transactions and manages replay protection.\n */\n\nimport type {\n SchemeNetworkFacilitator,\n PaymentPayload,\n PaymentRequirements,\n VerifyResponse,\n SettleResponse,\n Network,\n} from \"@t402/core/types\";\nimport { SCHEME_EXACT_DIRECT, APTOS_CAIP2_NAMESPACE } from \"../../constants.js\";\nimport type {\n FacilitatorAptosSigner,\n ExactDirectAptosPayload,\n} from \"../../types.js\";\nimport {\n isValidTxHash,\n compareAddresses,\n parseAssetIdentifier,\n extractTransferDetails,\n isAptosNetwork,\n} from \"../../utils.js\";\nimport { getDefaultToken } from \"../../tokens.js\";\n\n/**\n * Configuration for ExactDirectAptosFacilitator\n */\nexport interface ExactDirectAptosFacilitatorConfig {\n /**\n * Maximum age of transaction in seconds (default: 3600 = 1 hour)\n */\n maxTransactionAge?: number;\n\n /**\n * Duration to cache used transaction hashes (in milliseconds)\n */\n usedTxCacheDuration?: number;\n}\n\n/**\n * Aptos Exact-Direct Facilitator\n *\n * Implements the facilitator-side verification and settlement.\n * For exact-direct, settlement is a no-op since client already executed.\n */\nexport class ExactDirectAptosFacilitator implements SchemeNetworkFacilitator {\n readonly scheme = SCHEME_EXACT_DIRECT;\n readonly caipFamily = `${APTOS_CAIP2_NAMESPACE}:*`;\n\n private readonly config: Required<ExactDirectAptosFacilitatorConfig>;\n private usedTxs: Map<string, number> = new Map();\n\n constructor(\n private readonly signer: FacilitatorAptosSigner,\n config?: ExactDirectAptosFacilitatorConfig,\n ) {\n this.config = {\n maxTransactionAge: config?.maxTransactionAge ?? 3600,\n usedTxCacheDuration: config?.usedTxCacheDuration ?? 24 * 60 * 60 * 1000, // 24 hours\n };\n\n // Start cleanup interval\n this.startCleanupInterval();\n }\n\n /**\n * Get extra data for a supported kind\n */\n getExtra(network: Network): Record<string, unknown> | undefined {\n const token = getDefaultToken(network);\n if (!token) {\n return undefined;\n }\n return {\n assetSymbol: token.symbol,\n assetDecimals: token.decimals,\n };\n }\n\n /**\n * Get facilitator signer addresses for a network\n */\n getSigners(network: Network): string[] {\n return this.signer.getAddresses(network);\n }\n\n /**\n * Verify a payment payload\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n // Validate scheme\n if (payload.accepted.scheme !== SCHEME_EXACT_DIRECT) {\n return {\n isValid: false,\n invalidReason: \"invalid_scheme\",\n };\n }\n\n // Validate network\n if (!isAptosNetwork(payload.accepted.network)) {\n return {\n isValid: false,\n invalidReason: \"invalid_network\",\n };\n }\n\n // Extract Aptos-specific payload\n const aptosPayload = payload.payload as ExactDirectAptosPayload;\n\n // Validate transaction hash format\n if (!isValidTxHash(aptosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"invalid_tx_hash_format\",\n };\n }\n\n // Check for replay attack\n if (this.isTxUsed(aptosPayload.txHash)) {\n return {\n isValid: false,\n invalidReason: \"transaction_already_used\",\n payer: aptosPayload.from,\n };\n }\n\n try {\n // Query transaction\n const tx = await this.signer.queryTransaction(aptosPayload.txHash);\n if (!tx) {\n return {\n isValid: false,\n invalidReason: \"transaction_not_found\",\n payer: aptosPayload.from,\n };\n }\n\n // Verify transaction was successful\n if (!tx.success) {\n return {\n isValid: false,\n invalidReason: `transaction_failed: ${tx.vmStatus}`,\n payer: aptosPayload.from,\n };\n }\n\n // Check transaction age\n if (this.config.maxTransactionAge > 0) {\n const txTimestamp = parseInt(tx.timestamp, 10) / 1000000; // Convert from microseconds\n const now = Date.now() / 1000;\n const age = now - txTimestamp;\n if (age > this.config.maxTransactionAge) {\n return {\n isValid: false,\n invalidReason: `transaction_too_old: ${Math.round(age)} seconds`,\n payer: aptosPayload.from,\n };\n }\n }\n\n // Extract transfer details from transaction\n const transferDetails = extractTransferDetails(tx);\n if (!transferDetails) {\n return {\n isValid: false,\n invalidReason: \"could_not_extract_transfer_details\",\n payer: aptosPayload.from,\n };\n }\n\n // Parse expected asset\n const expectedAsset = parseAssetIdentifier(requirements.asset);\n if (!expectedAsset) {\n return {\n isValid: false,\n invalidReason: `invalid_asset_in_requirements: ${requirements.asset}`,\n payer: aptosPayload.from,\n };\n }\n\n // Verify recipient\n if (!compareAddresses(transferDetails.to, requirements.payTo)) {\n return {\n isValid: false,\n invalidReason: `recipient_mismatch: expected ${requirements.payTo}, got ${transferDetails.to}`,\n payer: aptosPayload.from,\n };\n }\n\n // Verify metadata address (token)\n if (\n !compareAddresses(\n transferDetails.metadataAddress,\n expectedAsset.metadataAddress,\n )\n ) {\n return {\n isValid: false,\n invalidReason: `token_mismatch: expected ${expectedAsset.metadataAddress}, got ${transferDetails.metadataAddress}`,\n payer: aptosPayload.from,\n };\n }\n\n // Verify amount\n const expectedAmount = BigInt(requirements.amount);\n if (transferDetails.amount < expectedAmount) {\n return {\n isValid: false,\n invalidReason: `insufficient_amount: expected ${expectedAmount}, got ${transferDetails.amount}`,\n payer: aptosPayload.from,\n };\n }\n\n // Mark transaction as used\n this.markTxUsed(aptosPayload.txHash);\n\n return {\n isValid: true,\n payer: transferDetails.from,\n };\n } catch (error) {\n return {\n isValid: false,\n invalidReason: `verification_error: ${error instanceof Error ? error.message : String(error)}`,\n payer: aptosPayload.from,\n };\n }\n }\n\n /**\n * Settle a payment (no-op for exact-direct since client already executed)\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n // Verify first\n const verifyResult = await this.verify(payload, requirements);\n\n if (!verifyResult.isValid) {\n return {\n success: false,\n errorReason: verifyResult.invalidReason || \"verification_failed\",\n payer: verifyResult.payer,\n transaction: \"\",\n network: requirements.network,\n };\n }\n\n const aptosPayload = payload.payload as ExactDirectAptosPayload;\n\n // For exact-direct, settlement is already complete\n return {\n success: true,\n transaction: aptosPayload.txHash,\n network: requirements.network,\n payer: aptosPayload.from,\n };\n }\n\n /**\n * Check if a transaction has been used\n */\n private isTxUsed(txHash: string): boolean {\n return this.usedTxs.has(txHash.toLowerCase());\n }\n\n /**\n * Mark a transaction as used\n */\n private markTxUsed(txHash: string): void {\n this.usedTxs.set(txHash.toLowerCase(), Date.now());\n }\n\n /**\n * Start the cleanup interval for used transactions\n */\n private startCleanupInterval(): void {\n setInterval(\n () => {\n const cutoff = Date.now() - this.config.usedTxCacheDuration;\n for (const [txHash, usedAt] of this.usedTxs.entries()) {\n if (usedAt < cutoff) {\n this.usedTxs.delete(txHash);\n }\n }\n },\n 60 * 60 * 1000,\n ); // Cleanup every hour\n }\n}\n\nexport default ExactDirectAptosFacilitator;\n","/**\n * Registration function for Aptos Exact-Direct facilitator\n */\n\nimport { t402Facilitator } from \"@t402/core/facilitator\";\nimport type { Network } from \"@t402/core/types\";\nimport type { FacilitatorAptosSigner } from \"../../types.js\";\nimport {\n ExactDirectAptosFacilitator,\n type ExactDirectAptosFacilitatorConfig,\n} from \"./scheme.js\";\n\n/**\n * Configuration options for registering Aptos schemes to a t402Facilitator\n */\nexport interface AptosFacilitatorConfig {\n /**\n * The Aptos signer for facilitator operations (verify and settle)\n */\n signer: FacilitatorAptosSigner;\n\n /**\n * Optional specific networks to register\n * If not provided, registers wildcard support (aptos:*)\n */\n networks?: Network[];\n\n /**\n * Optional scheme configuration\n */\n schemeConfig?: ExactDirectAptosFacilitatorConfig;\n}\n\n/**\n * Registers Aptos exact-direct payment schemes to a t402Facilitator instance.\n *\n * @param facilitator - The t402Facilitator instance to register schemes to\n * @param config - Configuration for Aptos facilitator registration\n * @returns The facilitator instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactDirectAptosFacilitator } from \"@t402/aptos/exact-direct/facilitator\";\n * import { t402Facilitator } from \"@t402/core/facilitator\";\n *\n * const facilitator = new t402Facilitator();\n * registerExactDirectAptosFacilitator(facilitator, {\n * signer: myAptosSigner,\n * networks: [\"aptos:1\"]\n * });\n * ```\n */\nexport function registerExactDirectAptosFacilitator(\n facilitator: t402Facilitator,\n config: AptosFacilitatorConfig,\n): t402Facilitator {\n const scheme = new ExactDirectAptosFacilitator(\n config.signer,\n config.schemeConfig,\n );\n\n // Register scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach((network) => {\n facilitator.register(network, scheme);\n });\n } else {\n // Register wildcard for all Aptos networks\n facilitator.register(\"aptos:*\", scheme);\n }\n\n return facilitator;\n}\n"],"mappings":"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","names":[]}