@x402/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 (35) hide show
  1. package/README.md +74 -0
  2. package/dist/cjs/exact/client/index.d.ts +29 -0
  3. package/dist/cjs/exact/client/index.js +141 -0
  4. package/dist/cjs/exact/client/index.js.map +1 -0
  5. package/dist/cjs/exact/facilitator/index.d.ts +52 -0
  6. package/dist/cjs/exact/facilitator/index.js +373 -0
  7. package/dist/cjs/exact/facilitator/index.js.map +1 -0
  8. package/dist/cjs/exact/server/index.d.ts +67 -0
  9. package/dist/cjs/exact/server/index.js +143 -0
  10. package/dist/cjs/exact/server/index.js.map +1 -0
  11. package/dist/cjs/index.d.ts +116 -0
  12. package/dist/cjs/index.js +269 -0
  13. package/dist/cjs/index.js.map +1 -0
  14. package/dist/cjs/signer-DPT9P1NX.d.ts +59 -0
  15. package/dist/cjs/signer-DfwN1I5I.d.ts +59 -0
  16. package/dist/esm/chunk-6BMAMLXJ.mjs +93 -0
  17. package/dist/esm/chunk-6BMAMLXJ.mjs.map +1 -0
  18. package/dist/esm/chunk-D4UVBSUH.mjs +53 -0
  19. package/dist/esm/chunk-D4UVBSUH.mjs.map +1 -0
  20. package/dist/esm/chunk-FG4ANPDN.mjs +46 -0
  21. package/dist/esm/chunk-FG4ANPDN.mjs.map +1 -0
  22. package/dist/esm/exact/client/index.d.mts +29 -0
  23. package/dist/esm/exact/client/index.mjs +9 -0
  24. package/dist/esm/exact/client/index.mjs.map +1 -0
  25. package/dist/esm/exact/facilitator/index.d.mts +52 -0
  26. package/dist/esm/exact/facilitator/index.mjs +294 -0
  27. package/dist/esm/exact/facilitator/index.mjs.map +1 -0
  28. package/dist/esm/exact/server/index.d.mts +67 -0
  29. package/dist/esm/exact/server/index.mjs +116 -0
  30. package/dist/esm/exact/server/index.mjs.map +1 -0
  31. package/dist/esm/index.d.mts +116 -0
  32. package/dist/esm/index.mjs +105 -0
  33. package/dist/esm/index.mjs.map +1 -0
  34. package/dist/esm/signer-DPT9P1NX.d.mts +59 -0
  35. package/package.json +95 -0
@@ -0,0 +1,53 @@
1
+ import {
2
+ getAptosNetwork,
3
+ getAptosRpcUrl
4
+ } from "./chunk-FG4ANPDN.mjs";
5
+
6
+ // src/utils.ts
7
+ import {
8
+ Deserializer,
9
+ SimpleTransaction,
10
+ AccountAuthenticator,
11
+ Aptos,
12
+ AptosConfig
13
+ } from "@aptos-labs/ts-sdk";
14
+ function deserializeAptosPayment(transactionBase64) {
15
+ const decoded = Buffer.from(transactionBase64, "base64").toString("utf8");
16
+ const parsed = JSON.parse(decoded);
17
+ const transactionBytes = Uint8Array.from(parsed.transaction);
18
+ const transaction = SimpleTransaction.deserialize(new Deserializer(transactionBytes));
19
+ const authBytes = Uint8Array.from(parsed.senderAuthenticator);
20
+ const senderAuthenticator = AccountAuthenticator.deserialize(new Deserializer(authBytes));
21
+ if (!isEntryFunctionPayload(transaction.rawTransaction.payload)) {
22
+ return { transaction, senderAuthenticator };
23
+ }
24
+ const entryFunction = transaction.rawTransaction.payload.entryFunction;
25
+ return { transaction, senderAuthenticator, entryFunction };
26
+ }
27
+ function isEntryFunctionPayload(payload) {
28
+ return "entryFunction" in payload;
29
+ }
30
+ function createAptosClient(network, rpcUrl) {
31
+ const aptosNetwork = getAptosNetwork(network);
32
+ const fullnodeUrl = rpcUrl || getAptosRpcUrl(aptosNetwork);
33
+ const config = new AptosConfig({
34
+ network: aptosNetwork,
35
+ fullnode: fullnodeUrl
36
+ });
37
+ return new Aptos(config);
38
+ }
39
+ function encodeAptosPayload(transactionBytes, authenticatorBytes) {
40
+ const payload = {
41
+ transaction: Array.from(transactionBytes),
42
+ senderAuthenticator: Array.from(authenticatorBytes)
43
+ };
44
+ return Buffer.from(JSON.stringify(payload)).toString("base64");
45
+ }
46
+
47
+ export {
48
+ deserializeAptosPayment,
49
+ isEntryFunctionPayload,
50
+ createAptosClient,
51
+ encodeAptosPayload
52
+ };
53
+ //# sourceMappingURL=chunk-D4UVBSUH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils.ts"],"sourcesContent":["import {\n Deserializer,\n SimpleTransaction,\n AccountAuthenticator,\n TransactionPayloadEntryFunction,\n TransactionPayload,\n EntryFunction,\n Aptos,\n AptosConfig,\n} from \"@aptos-labs/ts-sdk\";\nimport type { DecodedAptosPayload } from \"./types\";\nimport { getAptosNetwork, getAptosRpcUrl } from \"./constants\";\n\n/**\n * Deserialize an Aptos transaction and authenticator from the payment payload.\n *\n * @param transactionBase64 - The base64 encoded transaction payload\n * @returns The deserialized transaction and authenticator\n */\nexport function deserializeAptosPayment(transactionBase64: string): {\n transaction: SimpleTransaction;\n senderAuthenticator: AccountAuthenticator;\n entryFunction?: EntryFunction;\n} {\n // Decode the base64 payload\n const decoded = Buffer.from(transactionBase64, \"base64\").toString(\"utf8\");\n const parsed: DecodedAptosPayload = JSON.parse(decoded);\n\n // Deserialize the transaction bytes\n const transactionBytes = Uint8Array.from(parsed.transaction);\n const transaction = SimpleTransaction.deserialize(new Deserializer(transactionBytes));\n\n // Deserialize the authenticator bytes\n const authBytes = Uint8Array.from(parsed.senderAuthenticator);\n const senderAuthenticator = AccountAuthenticator.deserialize(new Deserializer(authBytes));\n\n // Only Entry Function transactions are supported\n if (!isEntryFunctionPayload(transaction.rawTransaction.payload)) {\n return { transaction, senderAuthenticator };\n }\n\n const entryFunction = transaction.rawTransaction.payload.entryFunction;\n\n return { transaction, senderAuthenticator, entryFunction };\n}\n\n/**\n * Checks if it's an entry function payload.\n *\n * @param payload - The payload to check\n * @returns True if it's an entry function payload\n */\nexport function isEntryFunctionPayload(\n payload: TransactionPayload,\n): payload is TransactionPayloadEntryFunction {\n return \"entryFunction\" in payload;\n}\n\n/**\n * Create an Aptos SDK client for the given network\n *\n * @param network - CAIP-2 network identifier (e.g., \"aptos:1\")\n * @param rpcUrl - Optional custom RPC URL\n * @returns Aptos SDK client\n */\nexport function createAptosClient(network: string, rpcUrl?: string): Aptos {\n const aptosNetwork = getAptosNetwork(network);\n const fullnodeUrl = rpcUrl || getAptosRpcUrl(aptosNetwork);\n\n const config = new AptosConfig({\n network: aptosNetwork,\n fullnode: fullnodeUrl,\n });\n\n return new Aptos(config);\n}\n\n/**\n * Encode an Aptos payment payload to base64\n *\n * @param transactionBytes - The serialized transaction bytes\n * @param authenticatorBytes - The serialized authenticator bytes\n * @returns Base64 encoded payload\n */\nexport function encodeAptosPayload(\n transactionBytes: Uint8Array,\n authenticatorBytes: Uint8Array,\n): string {\n const payload: DecodedAptosPayload = {\n transaction: Array.from(transactionBytes),\n senderAuthenticator: Array.from(authenticatorBytes),\n };\n return Buffer.from(JSON.stringify(payload)).toString(\"base64\");\n}\n"],"mappings":";;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAIA;AAAA,EACA;AAAA,OACK;AAUA,SAAS,wBAAwB,mBAItC;AAEA,QAAM,UAAU,OAAO,KAAK,mBAAmB,QAAQ,EAAE,SAAS,MAAM;AACxE,QAAM,SAA8B,KAAK,MAAM,OAAO;AAGtD,QAAM,mBAAmB,WAAW,KAAK,OAAO,WAAW;AAC3D,QAAM,cAAc,kBAAkB,YAAY,IAAI,aAAa,gBAAgB,CAAC;AAGpF,QAAM,YAAY,WAAW,KAAK,OAAO,mBAAmB;AAC5D,QAAM,sBAAsB,qBAAqB,YAAY,IAAI,aAAa,SAAS,CAAC;AAGxF,MAAI,CAAC,uBAAuB,YAAY,eAAe,OAAO,GAAG;AAC/D,WAAO,EAAE,aAAa,oBAAoB;AAAA,EAC5C;AAEA,QAAM,gBAAgB,YAAY,eAAe,QAAQ;AAEzD,SAAO,EAAE,aAAa,qBAAqB,cAAc;AAC3D;AAQO,SAAS,uBACd,SAC4C;AAC5C,SAAO,mBAAmB;AAC5B;AASO,SAAS,kBAAkB,SAAiB,QAAwB;AACzE,QAAM,eAAe,gBAAgB,OAAO;AAC5C,QAAM,cAAc,UAAU,eAAe,YAAY;AAEzD,QAAM,SAAS,IAAI,YAAY;AAAA,IAC7B,SAAS;AAAA,IACT,UAAU;AAAA,EACZ,CAAC;AAED,SAAO,IAAI,MAAM,MAAM;AACzB;AASO,SAAS,mBACd,kBACA,oBACQ;AACR,QAAM,UAA+B;AAAA,IACnC,aAAa,MAAM,KAAK,gBAAgB;AAAA,IACxC,qBAAqB,MAAM,KAAK,kBAAkB;AAAA,EACpD;AACA,SAAO,OAAO,KAAK,KAAK,UAAU,OAAO,CAAC,EAAE,SAAS,QAAQ;AAC/D;","names":[]}
@@ -0,0 +1,46 @@
1
+ // src/constants.ts
2
+ import { Network, NetworkToNodeAPI } from "@aptos-labs/ts-sdk";
3
+ var APTOS_MAINNET_CAIP2 = "aptos:1";
4
+ var APTOS_TESTNET_CAIP2 = "aptos:2";
5
+ var APTOS_ADDRESS_REGEX = /^0x[a-fA-F0-9]{64}$/;
6
+ var TRANSFER_FUNCTION = "0x1::primary_fungible_store::transfer";
7
+ var MAX_GAS_AMOUNT = 500000n;
8
+ function getAptosChainId(network) {
9
+ switch (network) {
10
+ case APTOS_MAINNET_CAIP2:
11
+ return 1;
12
+ case APTOS_TESTNET_CAIP2:
13
+ return 2;
14
+ default:
15
+ throw new Error(`Unsupported Aptos network: ${network}`);
16
+ }
17
+ }
18
+ var USDC_MAINNET_FA = "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b";
19
+ var USDC_TESTNET_FA = "0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832";
20
+ function getAptosNetwork(network) {
21
+ switch (network) {
22
+ case APTOS_MAINNET_CAIP2:
23
+ return Network.MAINNET;
24
+ case APTOS_TESTNET_CAIP2:
25
+ return Network.TESTNET;
26
+ default:
27
+ throw new Error(`Unsupported Aptos network: ${network}`);
28
+ }
29
+ }
30
+ function getAptosRpcUrl(network) {
31
+ return NetworkToNodeAPI[network];
32
+ }
33
+
34
+ export {
35
+ APTOS_MAINNET_CAIP2,
36
+ APTOS_TESTNET_CAIP2,
37
+ APTOS_ADDRESS_REGEX,
38
+ TRANSFER_FUNCTION,
39
+ MAX_GAS_AMOUNT,
40
+ getAptosChainId,
41
+ USDC_MAINNET_FA,
42
+ USDC_TESTNET_FA,
43
+ getAptosNetwork,
44
+ getAptosRpcUrl
45
+ };
46
+ //# sourceMappingURL=chunk-FG4ANPDN.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/constants.ts"],"sourcesContent":["import { Network, NetworkToNodeAPI } from \"@aptos-labs/ts-sdk\";\n\n/**\n * CAIP-2 network identifier for Aptos Mainnet\n */\nexport const APTOS_MAINNET_CAIP2 = \"aptos:1\";\n\n/**\n * CAIP-2 network identifier for Aptos Testnet\n */\nexport const APTOS_TESTNET_CAIP2 = \"aptos:2\";\n\n/**\n * Regex pattern for validating Aptos addresses\n * Matches 64 hex characters with 0x prefix\n */\nexport const APTOS_ADDRESS_REGEX = /^0x[a-fA-F0-9]{64}$/;\n\n/**\n * The primary fungible store transfer function\n */\nexport const TRANSFER_FUNCTION = \"0x1::primary_fungible_store::transfer\";\n\n/**\n * Maximum gas amount allowed for sponsored transactions to prevent gas draining attacks.\n * The Aptos SDK defaults to 200000 for simple transactions, so we allow some headroom.\n */\nexport const MAX_GAS_AMOUNT = 500000n;\n\n/**\n * Maps CAIP-2 network identifiers to Aptos chain IDs.\n *\n * @param network - The CAIP-2 network identifier (e.g., \"aptos:1\")\n * @returns The corresponding chain ID\n */\nexport function getAptosChainId(network: string): number {\n switch (network) {\n case APTOS_MAINNET_CAIP2:\n return 1;\n case APTOS_TESTNET_CAIP2:\n return 2;\n default:\n throw new Error(`Unsupported Aptos network: ${network}`);\n }\n}\n\n/**\n * Default USDC fungible asset metadata address on mainnet.\n */\nexport const USDC_MAINNET_FA = \"0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b\";\n\n/**\n * Default USDC fungible asset metadata address on testnet.\n */\nexport const USDC_TESTNET_FA = \"0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832\";\n\n/**\n * Maps CAIP-2 network identifiers to Aptos SDK Network enum.\n *\n * @param network - The CAIP-2 network identifier (e.g., \"aptos:1\")\n * @returns The corresponding Aptos SDK Network enum value\n */\nexport function getAptosNetwork(network: string): Network {\n switch (network) {\n case APTOS_MAINNET_CAIP2:\n return Network.MAINNET;\n case APTOS_TESTNET_CAIP2:\n return Network.TESTNET;\n default:\n throw new Error(`Unsupported Aptos network: ${network}`);\n }\n}\n\n/**\n * Gets the default RPC URL for the given Aptos network.\n *\n * @param network - The Aptos SDK Network enum value\n * @returns The default RPC URL for the network\n */\nexport function getAptosRpcUrl(network: Network): string {\n return NetworkToNodeAPI[network];\n}\n"],"mappings":";AAAA,SAAS,SAAS,wBAAwB;AAKnC,IAAM,sBAAsB;AAK5B,IAAM,sBAAsB;AAM5B,IAAM,sBAAsB;AAK5B,IAAM,oBAAoB;AAM1B,IAAM,iBAAiB;AAQvB,SAAS,gBAAgB,SAAyB;AACvD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,YAAM,IAAI,MAAM,8BAA8B,OAAO,EAAE;AAAA,EAC3D;AACF;AAKO,IAAM,kBAAkB;AAKxB,IAAM,kBAAkB;AAQxB,SAAS,gBAAgB,SAA0B;AACxD,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB;AACE,YAAM,IAAI,MAAM,8BAA8B,OAAO,EAAE;AAAA,EAC3D;AACF;AAQO,SAAS,eAAe,SAA0B;AACvD,SAAO,iBAAiB,OAAO;AACjC;","names":[]}
@@ -0,0 +1,29 @@
1
+ import { SchemeNetworkClient, PaymentRequirements, PaymentPayload } from '@x402/core/types';
2
+ import { a as ClientAptosSigner, C as ClientAptosConfig } from '../../signer-DPT9P1NX.mjs';
3
+ import '@aptos-labs/ts-sdk';
4
+
5
+ /**
6
+ * Aptos client implementation for the Exact payment scheme.
7
+ */
8
+ declare class ExactAptosScheme implements SchemeNetworkClient {
9
+ private readonly signer;
10
+ private readonly config?;
11
+ readonly scheme = "exact";
12
+ /**
13
+ * Creates a new ExactAptosScheme instance.
14
+ *
15
+ * @param signer - The Aptos account for signing transactions
16
+ * @param config - Optional configuration with custom RPC URL
17
+ */
18
+ constructor(signer: ClientAptosSigner, config?: ClientAptosConfig | undefined);
19
+ /**
20
+ * Creates a payment payload for the Exact scheme.
21
+ *
22
+ * @param x402Version - The x402 protocol version
23
+ * @param paymentRequirements - The payment requirements
24
+ * @returns Promise resolving to a payment payload
25
+ */
26
+ createPaymentPayload(x402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "x402Version" | "payload">>;
27
+ }
28
+
29
+ export { ExactAptosScheme };
@@ -0,0 +1,9 @@
1
+ import {
2
+ ExactAptosScheme
3
+ } from "../../chunk-6BMAMLXJ.mjs";
4
+ import "../../chunk-D4UVBSUH.mjs";
5
+ import "../../chunk-FG4ANPDN.mjs";
6
+ export {
7
+ ExactAptosScheme
8
+ };
9
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,52 @@
1
+ import { SchemeNetworkFacilitator, PaymentPayload, PaymentRequirements, VerifyResponse, SettleResponse } from '@x402/core/types';
2
+ import { F as FacilitatorAptosSigner } from '../../signer-DPT9P1NX.mjs';
3
+ import '@aptos-labs/ts-sdk';
4
+
5
+ /**
6
+ * Aptos facilitator implementation for the Exact payment scheme.
7
+ */
8
+ declare class ExactAptosScheme implements SchemeNetworkFacilitator {
9
+ private readonly signer;
10
+ private readonly sponsorTransactions;
11
+ readonly scheme = "exact";
12
+ readonly caipFamily = "aptos:*";
13
+ /**
14
+ * Creates a new ExactAptosFacilitator instance.
15
+ *
16
+ * @param signer - The Aptos facilitator signer for transaction submission
17
+ * @param sponsorTransactions - Whether to sponsor transactions (pay gas fees). Defaults to true.
18
+ */
19
+ constructor(signer: FacilitatorAptosSigner, sponsorTransactions?: boolean);
20
+ /**
21
+ * Get mechanism-specific extra data for the supported kinds endpoint.
22
+ *
23
+ * @param _ - The network identifier (unused)
24
+ * @returns Extra data with fee payer address, or undefined if sponsorship is disabled
25
+ */
26
+ getExtra(_: string): Record<string, unknown> | undefined;
27
+ /**
28
+ * Get signer addresses used by this facilitator.
29
+ *
30
+ * @param _ - The network identifier (unused)
31
+ * @returns Array of fee payer addresses
32
+ */
33
+ getSigners(_: string): string[];
34
+ /**
35
+ * Verifies a payment payload.
36
+ *
37
+ * @param payload - The payment payload to verify
38
+ * @param requirements - The payment requirements
39
+ * @returns Promise resolving to verification response
40
+ */
41
+ verify(payload: PaymentPayload, requirements: PaymentRequirements): Promise<VerifyResponse>;
42
+ /**
43
+ * Settles a payment by submitting the transaction.
44
+ *
45
+ * @param payload - The payment payload to settle
46
+ * @param requirements - The payment requirements
47
+ * @returns Promise resolving to settlement response
48
+ */
49
+ settle(payload: PaymentPayload, requirements: PaymentRequirements): Promise<SettleResponse>;
50
+ }
51
+
52
+ export { ExactAptosScheme };
@@ -0,0 +1,294 @@
1
+ import {
2
+ createAptosClient,
3
+ deserializeAptosPayment
4
+ } from "../../chunk-D4UVBSUH.mjs";
5
+ import {
6
+ MAX_GAS_AMOUNT,
7
+ getAptosChainId
8
+ } from "../../chunk-FG4ANPDN.mjs";
9
+
10
+ // src/exact/facilitator/scheme.ts
11
+ import { AccountAddress, Deserializer } from "@aptos-labs/ts-sdk";
12
+ var ExactAptosScheme = class {
13
+ /**
14
+ * Creates a new ExactAptosFacilitator instance.
15
+ *
16
+ * @param signer - The Aptos facilitator signer for transaction submission
17
+ * @param sponsorTransactions - Whether to sponsor transactions (pay gas fees). Defaults to true.
18
+ */
19
+ constructor(signer, sponsorTransactions = true) {
20
+ this.signer = signer;
21
+ this.sponsorTransactions = sponsorTransactions;
22
+ this.scheme = "exact";
23
+ this.caipFamily = "aptos:*";
24
+ }
25
+ /**
26
+ * Get mechanism-specific extra data for the supported kinds endpoint.
27
+ *
28
+ * @param _ - The network identifier (unused)
29
+ * @returns Extra data with fee payer address, or undefined if sponsorship is disabled
30
+ */
31
+ getExtra(_) {
32
+ if (!this.sponsorTransactions) {
33
+ return void 0;
34
+ }
35
+ const addresses = this.signer.getAddresses();
36
+ const randomIndex = Math.floor(Math.random() * addresses.length);
37
+ return { feePayer: addresses[randomIndex] };
38
+ }
39
+ /**
40
+ * Get signer addresses used by this facilitator.
41
+ *
42
+ * @param _ - The network identifier (unused)
43
+ * @returns Array of fee payer addresses
44
+ */
45
+ getSigners(_) {
46
+ return [...this.signer.getAddresses()];
47
+ }
48
+ /**
49
+ * Verifies a payment payload.
50
+ *
51
+ * @param payload - The payment payload to verify
52
+ * @param requirements - The payment requirements
53
+ * @returns Promise resolving to verification response
54
+ */
55
+ async verify(payload, requirements) {
56
+ try {
57
+ const aptosPayload = payload.payload;
58
+ const signerAddresses = this.signer.getAddresses();
59
+ const isSponsored = typeof requirements.extra?.feePayer === "string";
60
+ if (payload.x402Version !== 2) {
61
+ return {
62
+ isValid: false,
63
+ invalidReason: "invalid_exact_aptos_payload_unsupported_version",
64
+ payer: ""
65
+ };
66
+ }
67
+ if (payload.accepted.scheme !== "exact" || requirements.scheme !== "exact") {
68
+ return { isValid: false, invalidReason: "unsupported_scheme", payer: "" };
69
+ }
70
+ if (payload.accepted.network !== requirements.network) {
71
+ return { isValid: false, invalidReason: "network_mismatch", payer: "" };
72
+ }
73
+ if (isSponsored && !signerAddresses.includes(requirements.extra.feePayer)) {
74
+ return { isValid: false, invalidReason: "fee_payer_not_managed_by_facilitator", payer: "" };
75
+ }
76
+ const { transaction, senderAuthenticator, entryFunction } = deserializeAptosPayment(
77
+ aptosPayload.transaction
78
+ );
79
+ const senderAddress = transaction.rawTransaction.sender.toString();
80
+ const expectedChainId = getAptosChainId(requirements.network);
81
+ const txChainId = Number(transaction.rawTransaction.chain_id.chainId);
82
+ if (txChainId !== expectedChainId) {
83
+ return {
84
+ isValid: false,
85
+ invalidReason: `invalid_exact_aptos_payload_chain_id_mismatch: expected ${expectedChainId}, got ${txChainId}`,
86
+ payer: senderAddress
87
+ };
88
+ }
89
+ if (senderAuthenticator.isEd25519()) {
90
+ const pubKey = senderAuthenticator.public_key;
91
+ const derivedAddress = AccountAddress.from(pubKey.authKey().derivedAddress());
92
+ if (!derivedAddress.equals(transaction.rawTransaction.sender)) {
93
+ return {
94
+ isValid: false,
95
+ invalidReason: "invalid_exact_aptos_payload_sender_authenticator_mismatch",
96
+ payer: senderAddress
97
+ };
98
+ }
99
+ }
100
+ if (isSponsored) {
101
+ const maxGasAmount = BigInt(transaction.rawTransaction.max_gas_amount);
102
+ if (maxGasAmount > MAX_GAS_AMOUNT) {
103
+ return {
104
+ isValid: false,
105
+ invalidReason: `invalid_exact_aptos_payload_gas_too_high: ${maxGasAmount} > ${MAX_GAS_AMOUNT}`,
106
+ payer: senderAddress
107
+ };
108
+ }
109
+ }
110
+ if (isSponsored) {
111
+ const expectedFeePayer = AccountAddress.from(requirements.extra.feePayer);
112
+ if (!transaction.feePayerAddress || !expectedFeePayer.equals(transaction.feePayerAddress)) {
113
+ return {
114
+ isValid: false,
115
+ invalidReason: "invalid_exact_aptos_payload_fee_payer_mismatch",
116
+ payer: senderAddress
117
+ };
118
+ }
119
+ }
120
+ if (isSponsored && signerAddresses.includes(senderAddress)) {
121
+ return {
122
+ isValid: false,
123
+ invalidReason: "invalid_exact_aptos_payload_fee_payer_transferring_funds",
124
+ payer: senderAddress
125
+ };
126
+ }
127
+ const EXPIRATION_BUFFER_SECONDS = 5;
128
+ const expirationTimestamp = Number(transaction.rawTransaction.expiration_timestamp_secs);
129
+ if (expirationTimestamp < Math.floor(Date.now() / 1e3) + EXPIRATION_BUFFER_SECONDS) {
130
+ return {
131
+ isValid: false,
132
+ invalidReason: "invalid_exact_aptos_payload_transaction_expired",
133
+ payer: senderAddress
134
+ };
135
+ }
136
+ if (!entryFunction) {
137
+ return {
138
+ isValid: false,
139
+ invalidReason: "invalid_exact_aptos_payload_missing_entry_function",
140
+ payer: senderAddress
141
+ };
142
+ }
143
+ const moduleAddress = entryFunction.module_name.address;
144
+ const moduleName = entryFunction.module_name.name.identifier;
145
+ const functionName = entryFunction.function_name.identifier;
146
+ const isPrimaryFungibleStore = AccountAddress.ONE.equals(moduleAddress) && moduleName === "primary_fungible_store" && functionName === "transfer";
147
+ const isFungibleAsset = AccountAddress.ONE.equals(moduleAddress) && moduleName === "fungible_asset" && functionName === "transfer";
148
+ if (!isPrimaryFungibleStore && !isFungibleAsset) {
149
+ return {
150
+ isValid: false,
151
+ invalidReason: "invalid_exact_aptos_payload_wrong_function",
152
+ payer: senderAddress
153
+ };
154
+ }
155
+ if (entryFunction.type_args.length !== 1) {
156
+ return {
157
+ isValid: false,
158
+ invalidReason: "invalid_exact_aptos_payload_wrong_type_args",
159
+ payer: senderAddress
160
+ };
161
+ }
162
+ const args = entryFunction.args;
163
+ if (args.length !== 3) {
164
+ return {
165
+ isValid: false,
166
+ invalidReason: "invalid_exact_aptos_payload_wrong_args",
167
+ payer: senderAddress
168
+ };
169
+ }
170
+ const [faAddressArg, recipientAddressArg, amountArg] = args;
171
+ const faAddress = AccountAddress.from(faAddressArg.bcsToBytes());
172
+ if (!faAddress.equals(AccountAddress.from(requirements.asset))) {
173
+ return {
174
+ isValid: false,
175
+ invalidReason: "invalid_exact_aptos_payload_asset_mismatch",
176
+ payer: senderAddress
177
+ };
178
+ }
179
+ const amount = new Deserializer(amountArg.bcsToBytes()).deserializeU64().toString(10);
180
+ if (amount !== requirements.amount) {
181
+ return {
182
+ isValid: false,
183
+ invalidReason: "invalid_exact_aptos_payload_amount_mismatch",
184
+ payer: senderAddress
185
+ };
186
+ }
187
+ const recipientAddress = AccountAddress.from(recipientAddressArg.bcsToBytes());
188
+ if (!recipientAddress.equals(AccountAddress.from(requirements.payTo))) {
189
+ return {
190
+ isValid: false,
191
+ invalidReason: "invalid_exact_aptos_payload_recipient_mismatch",
192
+ payer: senderAddress
193
+ };
194
+ }
195
+ const aptos = createAptosClient(requirements.network);
196
+ const balance = await aptos.getCurrentFungibleAssetBalances({
197
+ options: {
198
+ where: {
199
+ owner_address: { _eq: senderAddress },
200
+ asset_type: { _eq: requirements.asset }
201
+ }
202
+ }
203
+ });
204
+ const currentBalance = BigInt(balance[0]?.amount ?? 0);
205
+ if (currentBalance < BigInt(requirements.amount)) {
206
+ return {
207
+ isValid: false,
208
+ invalidReason: "invalid_exact_aptos_payload_insufficient_balance",
209
+ payer: senderAddress
210
+ };
211
+ }
212
+ let publicKey;
213
+ if (senderAuthenticator.isEd25519()) {
214
+ publicKey = senderAuthenticator.public_key;
215
+ } else if (senderAuthenticator.isSingleKey()) {
216
+ publicKey = senderAuthenticator.public_key;
217
+ } else if (senderAuthenticator.isMultiKey()) {
218
+ publicKey = senderAuthenticator.public_keys;
219
+ }
220
+ const simulationResult = (await aptos.transaction.simulate.simple({ signerPublicKey: publicKey, transaction }))[0];
221
+ if (!simulationResult.success) {
222
+ return {
223
+ isValid: false,
224
+ invalidReason: `invalid_exact_aptos_payload_simulation_failed: ${simulationResult.vm_status}`,
225
+ payer: senderAddress
226
+ };
227
+ }
228
+ return { isValid: true, invalidReason: void 0, payer: senderAddress };
229
+ } catch (error) {
230
+ const errorMessage = error instanceof Error ? error.message : String(error);
231
+ return {
232
+ isValid: false,
233
+ invalidReason: `invalid_exact_aptos_payload_verification_error: ${errorMessage}`,
234
+ payer: ""
235
+ };
236
+ }
237
+ }
238
+ /**
239
+ * Settles a payment by submitting the transaction.
240
+ *
241
+ * @param payload - The payment payload to settle
242
+ * @param requirements - The payment requirements
243
+ * @returns Promise resolving to settlement response
244
+ */
245
+ async settle(payload, requirements) {
246
+ const aptosPayload = payload.payload;
247
+ const valid = await this.verify(payload, requirements);
248
+ if (!valid.isValid) {
249
+ return {
250
+ success: false,
251
+ network: payload.accepted.network,
252
+ transaction: "",
253
+ errorReason: valid.invalidReason ?? "verification_failed",
254
+ payer: valid.payer || ""
255
+ };
256
+ }
257
+ try {
258
+ const { transaction, senderAuthenticator } = deserializeAptosPayment(
259
+ aptosPayload.transaction
260
+ );
261
+ const senderAddress = transaction.rawTransaction.sender.toStringLong();
262
+ const isSponsored = typeof requirements.extra?.feePayer === "string";
263
+ const pendingTxn = isSponsored ? await this.signer.signAndSubmitAsFeePayer(
264
+ transaction,
265
+ senderAuthenticator,
266
+ requirements.network
267
+ ) : await this.signer.submitTransaction(
268
+ transaction,
269
+ senderAuthenticator,
270
+ requirements.network
271
+ );
272
+ await this.signer.waitForTransaction(pendingTxn.hash, requirements.network);
273
+ return {
274
+ success: true,
275
+ transaction: pendingTxn.hash,
276
+ network: payload.accepted.network,
277
+ payer: senderAddress
278
+ };
279
+ } catch (error) {
280
+ const errorMessage = error instanceof Error ? error.message : String(error);
281
+ return {
282
+ success: false,
283
+ errorReason: `transaction_failed: ${errorMessage}`,
284
+ transaction: "",
285
+ network: payload.accepted.network,
286
+ payer: valid.payer || ""
287
+ };
288
+ }
289
+ }
290
+ };
291
+ export {
292
+ ExactAptosScheme
293
+ };
294
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/exact/facilitator/scheme.ts"],"sourcesContent":["import { AccountAddress, Deserializer, Ed25519PublicKey, PublicKey } from \"@aptos-labs/ts-sdk\";\nimport type {\n PaymentPayload,\n PaymentRequirements,\n SchemeNetworkFacilitator,\n SettleResponse,\n VerifyResponse,\n} from \"@x402/core/types\";\nimport type { FacilitatorAptosSigner } from \"../../signer\";\nimport type { ExactAptosPayload } from \"../../types\";\nimport { createAptosClient, deserializeAptosPayment } from \"../../utils\";\nimport { getAptosChainId, MAX_GAS_AMOUNT } from \"../../constants\";\n\n/**\n * Aptos facilitator implementation for the Exact payment scheme.\n */\nexport class ExactAptosScheme implements SchemeNetworkFacilitator {\n readonly scheme = \"exact\";\n readonly caipFamily = \"aptos:*\";\n\n /**\n * Creates a new ExactAptosFacilitator instance.\n *\n * @param signer - The Aptos facilitator signer for transaction submission\n * @param sponsorTransactions - Whether to sponsor transactions (pay gas fees). Defaults to true.\n */\n constructor(\n private readonly signer: FacilitatorAptosSigner,\n private readonly sponsorTransactions: boolean = true,\n ) {}\n\n /**\n * Get mechanism-specific extra data for the supported kinds endpoint.\n *\n * @param _ - The network identifier (unused)\n * @returns Extra data with fee payer address, or undefined if sponsorship is disabled\n */\n getExtra(_: string): Record<string, unknown> | undefined {\n if (!this.sponsorTransactions) {\n return undefined;\n }\n const addresses = this.signer.getAddresses();\n const randomIndex = Math.floor(Math.random() * addresses.length);\n return { feePayer: addresses[randomIndex] };\n }\n\n /**\n * Get signer addresses used by this facilitator.\n *\n * @param _ - The network identifier (unused)\n * @returns Array of fee payer addresses\n */\n getSigners(_: string): string[] {\n return [...this.signer.getAddresses()];\n }\n\n /**\n * Verifies a payment payload.\n *\n * @param payload - The payment payload to verify\n * @param requirements - The payment requirements\n * @returns Promise resolving to verification response\n */\n async verify(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<VerifyResponse> {\n try {\n const aptosPayload = payload.payload as ExactAptosPayload;\n const signerAddresses = this.signer.getAddresses();\n const isSponsored = typeof requirements.extra?.feePayer === \"string\";\n\n // Step 2: Verify x402Version is 2\n if (payload.x402Version !== 2) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_unsupported_version\",\n payer: \"\",\n };\n }\n\n // Step 3: Verify the network matches\n if (payload.accepted.scheme !== \"exact\" || requirements.scheme !== \"exact\") {\n return { isValid: false, invalidReason: \"unsupported_scheme\", payer: \"\" };\n }\n\n if (payload.accepted.network !== requirements.network) {\n return { isValid: false, invalidReason: \"network_mismatch\", payer: \"\" };\n }\n\n // If sponsored, verify the fee payer is managed by this facilitator\n if (isSponsored && !signerAddresses.includes(requirements.extra.feePayer as string)) {\n return { isValid: false, invalidReason: \"fee_payer_not_managed_by_facilitator\", payer: \"\" };\n }\n\n // Step 4: Deserialize the BCS-encoded transaction and verify the signature\n const { transaction, senderAuthenticator, entryFunction } = deserializeAptosPayment(\n aptosPayload.transaction,\n );\n const senderAddress = transaction.rawTransaction.sender.toString();\n\n // Verify chain ID matches expected network\n const expectedChainId = getAptosChainId(requirements.network);\n const txChainId = Number(transaction.rawTransaction.chain_id.chainId);\n if (txChainId !== expectedChainId) {\n return {\n isValid: false,\n invalidReason: `invalid_exact_aptos_payload_chain_id_mismatch: expected ${expectedChainId}, got ${txChainId}`,\n payer: senderAddress,\n };\n }\n\n // Verify sender matches authenticator public key (for Ed25519 accounts)\n // Note: SingleKey and MultiKey authenticators are validated during simulation (step 11)\n if (senderAuthenticator.isEd25519()) {\n const pubKey = senderAuthenticator.public_key as Ed25519PublicKey;\n const derivedAddress = AccountAddress.from(pubKey.authKey().derivedAddress());\n if (!derivedAddress.equals(transaction.rawTransaction.sender)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_sender_authenticator_mismatch\",\n payer: senderAddress,\n };\n }\n }\n\n // For sponsored transactions, verify max gas to prevent gas draining\n if (isSponsored) {\n const maxGasAmount = BigInt(transaction.rawTransaction.max_gas_amount);\n if (maxGasAmount > MAX_GAS_AMOUNT) {\n return {\n isValid: false,\n invalidReason: `invalid_exact_aptos_payload_gas_too_high: ${maxGasAmount} > ${MAX_GAS_AMOUNT}`,\n payer: senderAddress,\n };\n }\n }\n\n // For sponsored transactions, verify fee payer address matches\n if (isSponsored) {\n const expectedFeePayer = AccountAddress.from(requirements.extra.feePayer as string);\n if (!transaction.feePayerAddress || !expectedFeePayer.equals(transaction.feePayerAddress)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_fee_payer_mismatch\",\n payer: senderAddress,\n };\n }\n }\n\n // SECURITY (reference implementation): Prevent facilitator from signing away their own tokens\n if (isSponsored && signerAddresses.includes(senderAddress)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_fee_payer_transferring_funds\",\n payer: senderAddress,\n };\n }\n\n // Step 5: Verify the transaction has not expired\n const EXPIRATION_BUFFER_SECONDS = 5;\n const expirationTimestamp = Number(transaction.rawTransaction.expiration_timestamp_secs);\n if (expirationTimestamp < Math.floor(Date.now() / 1000) + EXPIRATION_BUFFER_SECONDS) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_transaction_expired\",\n payer: senderAddress,\n };\n }\n\n // Step 6: Verify the transaction contains a fungible asset transfer operation\n // We accept both primary_fungible_store::transfer and fungible_asset::transfer:\n // - primary_fungible_store::transfer operates on primary stores (the default store for each asset)\n // and automatically creates the recipient's store if it doesn't exist\n // - fungible_asset::transfer is a lower-level function for arbitrary store-to-store transfers\n // and is more gas efficient when stores already exist\n if (!entryFunction) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_missing_entry_function\",\n payer: senderAddress,\n };\n }\n\n const moduleAddress = entryFunction.module_name.address;\n const moduleName = entryFunction.module_name.name.identifier;\n const functionName = entryFunction.function_name.identifier;\n\n const isPrimaryFungibleStore =\n AccountAddress.ONE.equals(moduleAddress) &&\n moduleName === \"primary_fungible_store\" &&\n functionName === \"transfer\";\n\n const isFungibleAsset =\n AccountAddress.ONE.equals(moduleAddress) &&\n moduleName === \"fungible_asset\" &&\n functionName === \"transfer\";\n\n if (!isPrimaryFungibleStore && !isFungibleAsset) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_wrong_function\",\n payer: senderAddress,\n };\n }\n\n if (entryFunction.type_args.length !== 1) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_wrong_type_args\",\n payer: senderAddress,\n };\n }\n\n const args = entryFunction.args;\n if (args.length !== 3) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_wrong_args\",\n payer: senderAddress,\n };\n }\n\n const [faAddressArg, recipientAddressArg, amountArg] = args;\n\n // Step 7: Verify the transfer is for the correct asset\n const faAddress = AccountAddress.from(faAddressArg.bcsToBytes());\n if (!faAddress.equals(AccountAddress.from(requirements.asset))) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_asset_mismatch\",\n payer: senderAddress,\n };\n }\n\n // Step 8: Verify the transfer amount matches\n const amount = new Deserializer(amountArg.bcsToBytes()).deserializeU64().toString(10);\n if (amount !== requirements.amount) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_amount_mismatch\",\n payer: senderAddress,\n };\n }\n\n // Step 9: Verify the transfer recipient matches\n const recipientAddress = AccountAddress.from(recipientAddressArg.bcsToBytes());\n if (!recipientAddress.equals(AccountAddress.from(requirements.payTo))) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_recipient_mismatch\",\n payer: senderAddress,\n };\n }\n\n // Step 10: Verify the sender has sufficient balance\n const aptos = createAptosClient(requirements.network);\n const balance = await aptos.getCurrentFungibleAssetBalances({\n options: {\n where: {\n owner_address: { _eq: senderAddress },\n asset_type: { _eq: requirements.asset },\n },\n },\n });\n const currentBalance = BigInt(balance[0]?.amount ?? 0);\n if (currentBalance < BigInt(requirements.amount)) {\n return {\n isValid: false,\n invalidReason: \"invalid_exact_aptos_payload_insufficient_balance\",\n payer: senderAddress,\n };\n }\n\n // Step 11: Simulate the transaction\n let publicKey: PublicKey | undefined;\n if (senderAuthenticator.isEd25519()) {\n publicKey = senderAuthenticator.public_key;\n } else if (senderAuthenticator.isSingleKey()) {\n publicKey = senderAuthenticator.public_key;\n } else if (senderAuthenticator.isMultiKey()) {\n publicKey = senderAuthenticator.public_keys;\n }\n\n const simulationResult = (\n await aptos.transaction.simulate.simple({ signerPublicKey: publicKey, transaction })\n )[0];\n\n if (!simulationResult.success) {\n return {\n isValid: false,\n invalidReason: `invalid_exact_aptos_payload_simulation_failed: ${simulationResult.vm_status}`,\n payer: senderAddress,\n };\n }\n\n return { isValid: true, invalidReason: undefined, payer: senderAddress };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n isValid: false,\n invalidReason: `invalid_exact_aptos_payload_verification_error: ${errorMessage}`,\n payer: \"\",\n };\n }\n }\n\n /**\n * Settles a payment by submitting the transaction.\n *\n * @param payload - The payment payload to settle\n * @param requirements - The payment requirements\n * @returns Promise resolving to settlement response\n */\n async settle(\n payload: PaymentPayload,\n requirements: PaymentRequirements,\n ): Promise<SettleResponse> {\n const aptosPayload = payload.payload as ExactAptosPayload;\n\n const valid = await this.verify(payload, requirements);\n if (!valid.isValid) {\n return {\n success: false,\n network: payload.accepted.network,\n transaction: \"\",\n errorReason: valid.invalidReason ?? \"verification_failed\",\n payer: valid.payer || \"\",\n };\n }\n\n try {\n const { transaction, senderAuthenticator } = deserializeAptosPayment(\n aptosPayload.transaction,\n );\n const senderAddress = transaction.rawTransaction.sender.toStringLong();\n const isSponsored = typeof requirements.extra?.feePayer === \"string\";\n\n const pendingTxn = isSponsored\n ? await this.signer.signAndSubmitAsFeePayer(\n transaction,\n senderAuthenticator,\n requirements.network,\n )\n : await this.signer.submitTransaction(\n transaction,\n senderAuthenticator,\n requirements.network,\n );\n\n await this.signer.waitForTransaction(pendingTxn.hash, requirements.network);\n\n return {\n success: true,\n transaction: pendingTxn.hash,\n network: payload.accepted.network,\n payer: senderAddress,\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n errorReason: `transaction_failed: ${errorMessage}`,\n transaction: \"\",\n network: payload.accepted.network,\n payer: valid.payer || \"\",\n };\n }\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,67 @@
1
+ import { SchemeNetworkServer, MoneyParser, Price, Network, AssetAmount, PaymentRequirements } from '@x402/core/types';
2
+
3
+ /**
4
+ * Aptos server implementation for the Exact payment scheme.
5
+ */
6
+ declare class ExactAptosScheme implements SchemeNetworkServer {
7
+ readonly scheme = "exact";
8
+ private moneyParsers;
9
+ /**
10
+ * Register a custom money parser in the parser chain.
11
+ *
12
+ * @param parser - Custom function to convert amount to AssetAmount (or null to skip)
13
+ * @returns The service instance for chaining
14
+ */
15
+ registerMoneyParser(parser: MoneyParser): ExactAptosScheme;
16
+ /**
17
+ * Parses a price into an asset amount.
18
+ *
19
+ * @param price - The price to parse
20
+ * @param network - The network to use
21
+ * @returns Promise that resolves to the parsed asset amount
22
+ */
23
+ parsePrice(price: Price, network: Network): Promise<AssetAmount>;
24
+ /**
25
+ * Build payment requirements for this scheme/network combination
26
+ *
27
+ * @param paymentRequirements - The base payment requirements
28
+ * @param supportedKind - The supported kind configuration
29
+ * @param supportedKind.x402Version - The x402 protocol version
30
+ * @param supportedKind.scheme - The payment scheme
31
+ * @param supportedKind.network - The network identifier
32
+ * @param supportedKind.extra - Extra metadata including feePayer address
33
+ * @param extensionKeys - Extension keys supported by the facilitator
34
+ * @returns Enhanced payment requirements with feePayer in extra
35
+ */
36
+ enhancePaymentRequirements(paymentRequirements: PaymentRequirements, supportedKind: {
37
+ x402Version: number;
38
+ scheme: string;
39
+ network: Network;
40
+ extra?: Record<string, unknown>;
41
+ }, extensionKeys: string[]): Promise<PaymentRequirements>;
42
+ /**
43
+ * Parse Money to a decimal number.
44
+ *
45
+ * @param money - The money value to parse
46
+ * @returns Decimal number
47
+ */
48
+ private parseMoneyToDecimal;
49
+ /**
50
+ * Default money conversion to USDC.
51
+ *
52
+ * @param amount - The decimal amount
53
+ * @param network - The network to use
54
+ * @returns The parsed asset amount in USDC
55
+ */
56
+ private defaultMoneyConversion;
57
+ /**
58
+ * Convert a decimal amount string to a token amount string.
59
+ *
60
+ * @param amount - The decimal amount
61
+ * @param decimals - Number of decimals for the token
62
+ * @returns The amount in atomic units as a string
63
+ */
64
+ private convertToTokenAmount;
65
+ }
66
+
67
+ export { ExactAptosScheme };