@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.
- package/README.md +171 -0
- package/dist/exact-direct/client/index.d.cts +91 -0
- package/dist/exact-direct/client/index.d.ts +91 -0
- package/dist/exact-direct/client/index.js +203 -0
- package/dist/exact-direct/client/index.js.map +1 -0
- package/dist/exact-direct/client/index.mjs +175 -0
- package/dist/exact-direct/client/index.mjs.map +1 -0
- package/dist/exact-direct/facilitator/index.d.cts +110 -0
- package/dist/exact-direct/facilitator/index.d.ts +110 -0
- package/dist/exact-direct/facilitator/index.js +352 -0
- package/dist/exact-direct/facilitator/index.js.map +1 -0
- package/dist/exact-direct/facilitator/index.mjs +324 -0
- package/dist/exact-direct/facilitator/index.mjs.map +1 -0
- package/dist/exact-direct/server/index.d.cts +106 -0
- package/dist/exact-direct/server/index.d.ts +106 -0
- package/dist/exact-direct/server/index.js +220 -0
- package/dist/exact-direct/server/index.js.map +1 -0
- package/dist/exact-direct/server/index.mjs +192 -0
- package/dist/exact-direct/server/index.mjs.map +1 -0
- package/dist/index.d.cts +145 -0
- package/dist/index.d.ts +145 -0
- package/dist/index.js +759 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +687 -0
- package/dist/index.mjs.map +1 -0
- package/dist/types-kOweBf4U.d.cts +149 -0
- package/dist/types-kOweBf4U.d.ts +149 -0
- package/package.json +100 -0
- package/src/constants.ts +48 -0
- package/src/exact-direct/client/index.ts +12 -0
- package/src/exact-direct/client/register.ts +83 -0
- package/src/exact-direct/client/scheme.ts +148 -0
- package/src/exact-direct/facilitator/index.ts +12 -0
- package/src/exact-direct/facilitator/register.ts +74 -0
- package/src/exact-direct/facilitator/scheme.ts +300 -0
- package/src/exact-direct/server/index.ts +12 -0
- package/src/exact-direct/server/register.ts +65 -0
- package/src/exact-direct/server/scheme.ts +196 -0
- package/src/index.ts +58 -0
- package/src/tokens.ts +114 -0
- package/src/types.ts +174 -0
- package/src/utils.ts +240 -0
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# @t402/aptos
|
|
2
|
+
|
|
3
|
+
Aptos implementation of the t402 payment protocol using the **exact-direct** payment scheme with Fungible Asset (FA) transfers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @t402/aptos
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @t402/aptos
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Overview
|
|
14
|
+
|
|
15
|
+
This package provides support for USDT/USDC payments on Aptos using the exact-direct scheme with the Fungible Asset standard. The client executes a `primary_fungible_store::transfer` call directly on-chain, then provides the transaction hash as proof of payment.
|
|
16
|
+
|
|
17
|
+
Three main components:
|
|
18
|
+
|
|
19
|
+
- **Client** - For applications that make payments (have Aptos wallets)
|
|
20
|
+
- **Facilitator** - For payment processors that verify transactions via Aptos REST API
|
|
21
|
+
- **Server** - For resource servers that accept payments and build payment requirements
|
|
22
|
+
|
|
23
|
+
## Supported Networks
|
|
24
|
+
|
|
25
|
+
| Network | CAIP-2 Identifier | Chain ID | USDT Metadata | Status |
|
|
26
|
+
|---------|-------------------|----------|---------------|--------|
|
|
27
|
+
| Aptos Mainnet | `aptos:1` | 1 | `0xf73e887a...` | Production |
|
|
28
|
+
| Aptos Testnet | `aptos:2` | 2 | `0xf73e887a...` | Testnet |
|
|
29
|
+
| Aptos Devnet | `aptos:149` | 149 | - | Development |
|
|
30
|
+
|
|
31
|
+
## Package Exports
|
|
32
|
+
|
|
33
|
+
### Main Package (`@t402/aptos`)
|
|
34
|
+
|
|
35
|
+
**Constants:**
|
|
36
|
+
- `APTOS_MAINNET_CAIP2` - CAIP-2 identifier for mainnet (`aptos:1`)
|
|
37
|
+
- `APTOS_TESTNET_CAIP2` - CAIP-2 identifier for testnet (`aptos:2`)
|
|
38
|
+
- `APTOS_DEVNET_CAIP2` - CAIP-2 identifier for devnet (`aptos:149`)
|
|
39
|
+
- `APTOS_NETWORKS` - Array of supported networks
|
|
40
|
+
- `FA_TRANSFER_FUNCTION` - Transfer function identifier
|
|
41
|
+
- `DEFAULT_MAINNET_RPC` - Default Aptos Labs RPC endpoint
|
|
42
|
+
|
|
43
|
+
**Tokens:**
|
|
44
|
+
- `TOKEN_REGISTRY` - Token configurations by network
|
|
45
|
+
- `getTokenConfig(network, symbol)` - Get token by symbol
|
|
46
|
+
- `getTokenByAddress(network, metadataAddress)` - Get token by metadata address
|
|
47
|
+
- `getSupportedTokens(network)` - Get all tokens for network
|
|
48
|
+
- `getDefaultToken(network)` - Get default token (USDT)
|
|
49
|
+
- `isTokenSupported(network, symbol)` - Check token support
|
|
50
|
+
|
|
51
|
+
**Utilities:**
|
|
52
|
+
- `isValidAptosAddress(address)` - Validate hex address format
|
|
53
|
+
- `normalizeAptosAddress(address)` - Normalize to 64-char format
|
|
54
|
+
- `compareAddresses(addr1, addr2)` - Compare addresses (case-insensitive)
|
|
55
|
+
- `isValidTxHash(txHash)` - Validate transaction hash
|
|
56
|
+
- `isAptosNetwork(network)` - Check if network is Aptos
|
|
57
|
+
- `formatAmount(amount, decimals)` - Format for display
|
|
58
|
+
- `parseAmount(amount, decimals)` - Parse to smallest units
|
|
59
|
+
- `extractTransferDetails(tx)` - Extract transfer from transaction
|
|
60
|
+
- `isFATransferTransaction(tx)` - Check if tx is FA transfer
|
|
61
|
+
|
|
62
|
+
### Client (`@t402/aptos/exact-direct/client`)
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
import { createExactDirectAptosClient } from '@t402/aptos/exact-direct/client';
|
|
66
|
+
|
|
67
|
+
const client = createExactDirectAptosClient({
|
|
68
|
+
signer: myAptosSigner,
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Server (`@t402/aptos/exact-direct/server`)
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { registerExactDirectAptosServer } from '@t402/aptos/exact-direct/server';
|
|
76
|
+
|
|
77
|
+
registerExactDirectAptosServer(server);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Facilitator (`@t402/aptos/exact-direct/facilitator`)
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createExactDirectAptosFacilitator } from '@t402/aptos/exact-direct/facilitator';
|
|
84
|
+
|
|
85
|
+
const facilitator = createExactDirectAptosFacilitator(signer);
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Payment Flow
|
|
89
|
+
|
|
90
|
+
1. **Client** requests protected resource
|
|
91
|
+
2. **Server** responds with 402 + payment requirements (network, amount, payTo)
|
|
92
|
+
3. **Client** calls `0x1::primary_fungible_store::transfer` with FA metadata
|
|
93
|
+
4. **Client** submits transaction hash as payment proof
|
|
94
|
+
5. **Facilitator** queries Aptos REST API to verify the transaction
|
|
95
|
+
6. **Facilitator** confirms payment matches requirements
|
|
96
|
+
|
|
97
|
+
## Payload Structure
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
interface ExactDirectAptosPayload {
|
|
101
|
+
txHash: string; // 0x-prefixed transaction hash
|
|
102
|
+
from: string; // Sender address (0x...)
|
|
103
|
+
to: string; // Recipient address
|
|
104
|
+
amount: string; // Amount in smallest units
|
|
105
|
+
metadataAddress: string; // FA metadata object address
|
|
106
|
+
version?: string; // Transaction version (optional)
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Address Format
|
|
111
|
+
|
|
112
|
+
Aptos uses hex addresses:
|
|
113
|
+
- Prefixed with `0x`
|
|
114
|
+
- 1-64 hex characters (leading zeros can be omitted)
|
|
115
|
+
- Full format: 64 hex characters
|
|
116
|
+
|
|
117
|
+
Examples:
|
|
118
|
+
```
|
|
119
|
+
0x1 (short form)
|
|
120
|
+
0x0000000000000000000000000000000000000000000000000000000000000001 (full form)
|
|
121
|
+
0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb (USDT metadata)
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Fungible Asset Standard
|
|
125
|
+
|
|
126
|
+
This package uses Aptos Fungible Asset (FA) standard:
|
|
127
|
+
- Modern replacement for legacy Coin module
|
|
128
|
+
- Metadata object identifies the asset
|
|
129
|
+
- `primary_fungible_store::transfer` for transfers
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// Transfer function call
|
|
133
|
+
{
|
|
134
|
+
function: "0x1::primary_fungible_store::transfer",
|
|
135
|
+
arguments: [
|
|
136
|
+
metadataAddress, // FA metadata object
|
|
137
|
+
recipientAddress, // Recipient
|
|
138
|
+
amount // Amount in smallest units
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Token Metadata Addresses
|
|
144
|
+
|
|
145
|
+
| Token | Mainnet Metadata Address |
|
|
146
|
+
|-------|-------------------------|
|
|
147
|
+
| USDT | `0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb` |
|
|
148
|
+
| USDC | `0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b` |
|
|
149
|
+
|
|
150
|
+
## Development
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Build
|
|
154
|
+
pnpm build
|
|
155
|
+
|
|
156
|
+
# Test
|
|
157
|
+
pnpm test
|
|
158
|
+
|
|
159
|
+
# Test with coverage
|
|
160
|
+
pnpm test:coverage
|
|
161
|
+
|
|
162
|
+
# Lint
|
|
163
|
+
pnpm lint
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Related Packages
|
|
167
|
+
|
|
168
|
+
- `@t402/core` - Core protocol types and client
|
|
169
|
+
- `@t402/fetch` - HTTP wrapper with automatic payment handling
|
|
170
|
+
- `@t402/evm` - EVM chains implementation
|
|
171
|
+
- `@t402/near` - NEAR Protocol implementation
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@t402/core/types';
|
|
2
|
+
import { C as ClientAptosSigner } from '../../types-kOweBf4U.cjs';
|
|
3
|
+
import { t402Client, PaymentPolicy } from '@t402/core/client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Aptos Exact-Direct Client Scheme
|
|
7
|
+
*
|
|
8
|
+
* The client executes the FA transfer directly and provides
|
|
9
|
+
* the transaction hash as proof of payment.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for ExactDirectAptosClient
|
|
14
|
+
*/
|
|
15
|
+
interface ExactDirectAptosClientConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Whether to verify the transfer was successful before returning
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
verifyTransfer?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Aptos Exact-Direct Client
|
|
24
|
+
*
|
|
25
|
+
* Implements the client-side payment flow where the client:
|
|
26
|
+
* 1. Receives payment requirements
|
|
27
|
+
* 2. Executes the FA transfer transaction
|
|
28
|
+
* 3. Returns transaction hash as proof
|
|
29
|
+
*/
|
|
30
|
+
declare class ExactDirectAptosClient implements SchemeNetworkClient {
|
|
31
|
+
private readonly signer;
|
|
32
|
+
readonly scheme = "exact-direct";
|
|
33
|
+
constructor(signer: ClientAptosSigner, config?: ExactDirectAptosClientConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Create a payment payload by executing the transfer
|
|
36
|
+
*/
|
|
37
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "t402Version" | "payload">>;
|
|
38
|
+
/**
|
|
39
|
+
* Validate payment requirements
|
|
40
|
+
*/
|
|
41
|
+
private validateRequirements;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Registration function for Aptos Exact-Direct client
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Configuration options for registering Aptos schemes to a t402Client
|
|
50
|
+
*/
|
|
51
|
+
interface AptosClientConfig {
|
|
52
|
+
/**
|
|
53
|
+
* The Aptos signer for client operations
|
|
54
|
+
*/
|
|
55
|
+
signer: ClientAptosSigner;
|
|
56
|
+
/**
|
|
57
|
+
* Optional policies to apply to the client
|
|
58
|
+
*/
|
|
59
|
+
policies?: PaymentPolicy[];
|
|
60
|
+
/**
|
|
61
|
+
* Optional specific networks to register
|
|
62
|
+
* If not provided, registers wildcard support (aptos:*)
|
|
63
|
+
*/
|
|
64
|
+
networks?: Network[];
|
|
65
|
+
/**
|
|
66
|
+
* Optional scheme configuration
|
|
67
|
+
*/
|
|
68
|
+
schemeConfig?: ExactDirectAptosClientConfig;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Registers Aptos exact-direct payment schemes to a t402Client instance.
|
|
72
|
+
*
|
|
73
|
+
* @param client - The t402Client instance to register schemes to
|
|
74
|
+
* @param config - Configuration for Aptos client registration
|
|
75
|
+
* @returns The client instance for chaining
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { registerExactDirectAptosClient } from "@t402/aptos/exact-direct/client";
|
|
80
|
+
* import { t402Client } from "@t402/core/client";
|
|
81
|
+
*
|
|
82
|
+
* const client = new t402Client();
|
|
83
|
+
* registerExactDirectAptosClient(client, {
|
|
84
|
+
* signer: myAptosSigner,
|
|
85
|
+
* networks: ["aptos:1"]
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function registerExactDirectAptosClient(client: t402Client, config: AptosClientConfig): t402Client;
|
|
90
|
+
|
|
91
|
+
export { type AptosClientConfig, ExactDirectAptosClient, type ExactDirectAptosClientConfig, registerExactDirectAptosClient };
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { SchemeNetworkClient, PaymentRequirements, PaymentPayload, Network } from '@t402/core/types';
|
|
2
|
+
import { C as ClientAptosSigner } from '../../types-kOweBf4U.js';
|
|
3
|
+
import { t402Client, PaymentPolicy } from '@t402/core/client';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Aptos Exact-Direct Client Scheme
|
|
7
|
+
*
|
|
8
|
+
* The client executes the FA transfer directly and provides
|
|
9
|
+
* the transaction hash as proof of payment.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Configuration for ExactDirectAptosClient
|
|
14
|
+
*/
|
|
15
|
+
interface ExactDirectAptosClientConfig {
|
|
16
|
+
/**
|
|
17
|
+
* Whether to verify the transfer was successful before returning
|
|
18
|
+
* @default true
|
|
19
|
+
*/
|
|
20
|
+
verifyTransfer?: boolean;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Aptos Exact-Direct Client
|
|
24
|
+
*
|
|
25
|
+
* Implements the client-side payment flow where the client:
|
|
26
|
+
* 1. Receives payment requirements
|
|
27
|
+
* 2. Executes the FA transfer transaction
|
|
28
|
+
* 3. Returns transaction hash as proof
|
|
29
|
+
*/
|
|
30
|
+
declare class ExactDirectAptosClient implements SchemeNetworkClient {
|
|
31
|
+
private readonly signer;
|
|
32
|
+
readonly scheme = "exact-direct";
|
|
33
|
+
constructor(signer: ClientAptosSigner, config?: ExactDirectAptosClientConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Create a payment payload by executing the transfer
|
|
36
|
+
*/
|
|
37
|
+
createPaymentPayload(t402Version: number, paymentRequirements: PaymentRequirements): Promise<Pick<PaymentPayload, "t402Version" | "payload">>;
|
|
38
|
+
/**
|
|
39
|
+
* Validate payment requirements
|
|
40
|
+
*/
|
|
41
|
+
private validateRequirements;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Registration function for Aptos Exact-Direct client
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Configuration options for registering Aptos schemes to a t402Client
|
|
50
|
+
*/
|
|
51
|
+
interface AptosClientConfig {
|
|
52
|
+
/**
|
|
53
|
+
* The Aptos signer for client operations
|
|
54
|
+
*/
|
|
55
|
+
signer: ClientAptosSigner;
|
|
56
|
+
/**
|
|
57
|
+
* Optional policies to apply to the client
|
|
58
|
+
*/
|
|
59
|
+
policies?: PaymentPolicy[];
|
|
60
|
+
/**
|
|
61
|
+
* Optional specific networks to register
|
|
62
|
+
* If not provided, registers wildcard support (aptos:*)
|
|
63
|
+
*/
|
|
64
|
+
networks?: Network[];
|
|
65
|
+
/**
|
|
66
|
+
* Optional scheme configuration
|
|
67
|
+
*/
|
|
68
|
+
schemeConfig?: ExactDirectAptosClientConfig;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Registers Aptos exact-direct payment schemes to a t402Client instance.
|
|
72
|
+
*
|
|
73
|
+
* @param client - The t402Client instance to register schemes to
|
|
74
|
+
* @param config - Configuration for Aptos client registration
|
|
75
|
+
* @returns The client instance for chaining
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* ```typescript
|
|
79
|
+
* import { registerExactDirectAptosClient } from "@t402/aptos/exact-direct/client";
|
|
80
|
+
* import { t402Client } from "@t402/core/client";
|
|
81
|
+
*
|
|
82
|
+
* const client = new t402Client();
|
|
83
|
+
* registerExactDirectAptosClient(client, {
|
|
84
|
+
* signer: myAptosSigner,
|
|
85
|
+
* networks: ["aptos:1"]
|
|
86
|
+
* });
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function registerExactDirectAptosClient(client: t402Client, config: AptosClientConfig): t402Client;
|
|
90
|
+
|
|
91
|
+
export { type AptosClientConfig, ExactDirectAptosClient, type ExactDirectAptosClientConfig, registerExactDirectAptosClient };
|
|
@@ -0,0 +1,203 @@
|
|
|
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/client/index.ts
|
|
21
|
+
var client_exports = {};
|
|
22
|
+
__export(client_exports, {
|
|
23
|
+
ExactDirectAptosClient: () => ExactDirectAptosClient,
|
|
24
|
+
registerExactDirectAptosClient: () => registerExactDirectAptosClient
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(client_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/tokens.ts
|
|
38
|
+
var TOKEN_REGISTRY = {
|
|
39
|
+
[APTOS_MAINNET_CAIP2]: [
|
|
40
|
+
{
|
|
41
|
+
metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
|
|
42
|
+
symbol: "USDT",
|
|
43
|
+
name: "Tether USD",
|
|
44
|
+
decimals: 6
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
metadataAddress: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
|
|
48
|
+
symbol: "USDC",
|
|
49
|
+
name: "USD Coin",
|
|
50
|
+
decimals: 6
|
|
51
|
+
}
|
|
52
|
+
],
|
|
53
|
+
[APTOS_TESTNET_CAIP2]: [
|
|
54
|
+
{
|
|
55
|
+
// Testnet USDT (may differ from mainnet)
|
|
56
|
+
metadataAddress: "0xf73e887a8754f540ee6e1a93bdc6dde2af69fc7ca5de32013e89dd44244473cb",
|
|
57
|
+
symbol: "USDT",
|
|
58
|
+
name: "Tether USD",
|
|
59
|
+
decimals: 6
|
|
60
|
+
}
|
|
61
|
+
],
|
|
62
|
+
[APTOS_DEVNET_CAIP2]: []
|
|
63
|
+
};
|
|
64
|
+
function getTokenConfig(network, symbol) {
|
|
65
|
+
const tokens = TOKEN_REGISTRY[network];
|
|
66
|
+
if (!tokens) return void 0;
|
|
67
|
+
return tokens.find(
|
|
68
|
+
(t) => t.symbol.toUpperCase() === symbol.toUpperCase()
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/utils.ts
|
|
73
|
+
function isValidAptosAddress(address) {
|
|
74
|
+
if (!address) return false;
|
|
75
|
+
if (!address.startsWith("0x")) return false;
|
|
76
|
+
const hex = address.slice(2);
|
|
77
|
+
if (hex.length === 0 || hex.length > 64) return false;
|
|
78
|
+
return /^[0-9a-fA-F]+$/.test(hex);
|
|
79
|
+
}
|
|
80
|
+
function normalizeAptosAddress(address) {
|
|
81
|
+
if (!address.startsWith("0x")) {
|
|
82
|
+
throw new Error("Aptos address must start with 0x");
|
|
83
|
+
}
|
|
84
|
+
const hex = address.slice(2).toLowerCase();
|
|
85
|
+
return "0x" + hex.padStart(64, "0");
|
|
86
|
+
}
|
|
87
|
+
function compareAddresses(addr1, addr2) {
|
|
88
|
+
try {
|
|
89
|
+
return normalizeAptosAddress(addr1) === normalizeAptosAddress(addr2);
|
|
90
|
+
} catch {
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function isAptosNetwork(network) {
|
|
95
|
+
return network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`);
|
|
96
|
+
}
|
|
97
|
+
function parseAssetIdentifier(asset) {
|
|
98
|
+
const parts = asset.split("/");
|
|
99
|
+
if (parts.length !== 2) return null;
|
|
100
|
+
const network = parts[0];
|
|
101
|
+
if (!isAptosNetwork(network)) return null;
|
|
102
|
+
const [assetType, address] = parts[1].split(":");
|
|
103
|
+
if (assetType !== "fa" || !address) return null;
|
|
104
|
+
if (!isValidAptosAddress(address)) return null;
|
|
105
|
+
return { network, metadataAddress: address };
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// src/exact-direct/client/scheme.ts
|
|
109
|
+
var ExactDirectAptosClient = class {
|
|
110
|
+
constructor(signer, config = {}) {
|
|
111
|
+
this.signer = signer;
|
|
112
|
+
void config;
|
|
113
|
+
}
|
|
114
|
+
scheme = SCHEME_EXACT_DIRECT;
|
|
115
|
+
/**
|
|
116
|
+
* Create a payment payload by executing the transfer
|
|
117
|
+
*/
|
|
118
|
+
async createPaymentPayload(t402Version, paymentRequirements) {
|
|
119
|
+
this.validateRequirements(paymentRequirements);
|
|
120
|
+
const from = await this.signer.getAddress();
|
|
121
|
+
const assetInfo = parseAssetIdentifier(paymentRequirements.asset);
|
|
122
|
+
if (!assetInfo) {
|
|
123
|
+
throw new Error(`Invalid asset identifier: ${paymentRequirements.asset}`);
|
|
124
|
+
}
|
|
125
|
+
const amount = BigInt(paymentRequirements.amount);
|
|
126
|
+
const balance = await this.signer.getBalance(assetInfo.metadataAddress);
|
|
127
|
+
if (balance < amount) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
`Insufficient balance: have ${balance}, need ${amount}`
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
const txHash = await this.signer.transfer(
|
|
133
|
+
paymentRequirements.payTo,
|
|
134
|
+
assetInfo.metadataAddress,
|
|
135
|
+
amount
|
|
136
|
+
);
|
|
137
|
+
const payload = {
|
|
138
|
+
txHash,
|
|
139
|
+
from,
|
|
140
|
+
to: paymentRequirements.payTo,
|
|
141
|
+
amount: paymentRequirements.amount,
|
|
142
|
+
metadataAddress: assetInfo.metadataAddress
|
|
143
|
+
};
|
|
144
|
+
return {
|
|
145
|
+
t402Version,
|
|
146
|
+
payload
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Validate payment requirements
|
|
151
|
+
*/
|
|
152
|
+
validateRequirements(requirements) {
|
|
153
|
+
if (requirements.scheme !== SCHEME_EXACT_DIRECT) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Invalid scheme: expected ${SCHEME_EXACT_DIRECT}, got ${requirements.scheme}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if (!requirements.network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`)) {
|
|
159
|
+
throw new Error(`Invalid network: ${requirements.network}`);
|
|
160
|
+
}
|
|
161
|
+
if (!isValidAptosAddress(requirements.payTo)) {
|
|
162
|
+
throw new Error(`Invalid payTo address: ${requirements.payTo}`);
|
|
163
|
+
}
|
|
164
|
+
const amount = BigInt(requirements.amount);
|
|
165
|
+
if (amount <= 0n) {
|
|
166
|
+
throw new Error(`Invalid amount: ${requirements.amount}`);
|
|
167
|
+
}
|
|
168
|
+
const assetInfo = parseAssetIdentifier(requirements.asset);
|
|
169
|
+
if (!assetInfo) {
|
|
170
|
+
throw new Error(`Invalid asset: ${requirements.asset}`);
|
|
171
|
+
}
|
|
172
|
+
const tokenConfig = getTokenConfig(requirements.network, "USDT");
|
|
173
|
+
if (tokenConfig && !compareAddresses(tokenConfig.metadataAddress, assetInfo.metadataAddress)) {
|
|
174
|
+
console.warn(
|
|
175
|
+
`Using non-standard token: ${assetInfo.metadataAddress}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
// src/exact-direct/client/register.ts
|
|
182
|
+
function registerExactDirectAptosClient(client, config) {
|
|
183
|
+
const scheme = new ExactDirectAptosClient(config.signer, config.schemeConfig);
|
|
184
|
+
if (config.networks && config.networks.length > 0) {
|
|
185
|
+
config.networks.forEach((network) => {
|
|
186
|
+
client.register(network, scheme);
|
|
187
|
+
});
|
|
188
|
+
} else {
|
|
189
|
+
client.register("aptos:*", scheme);
|
|
190
|
+
}
|
|
191
|
+
if (config.policies) {
|
|
192
|
+
config.policies.forEach((policy) => {
|
|
193
|
+
client.registerPolicy(policy);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return client;
|
|
197
|
+
}
|
|
198
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
199
|
+
0 && (module.exports = {
|
|
200
|
+
ExactDirectAptosClient,
|
|
201
|
+
registerExactDirectAptosClient
|
|
202
|
+
});
|
|
203
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/exact-direct/client/index.ts","../../../src/constants.ts","../../../src/tokens.ts","../../../src/utils.ts","../../../src/exact-direct/client/scheme.ts","../../../src/exact-direct/client/register.ts"],"sourcesContent":["/**\n * Aptos Exact-Direct Client Exports\n */\n\nexport {\n ExactDirectAptosClient,\n type ExactDirectAptosClientConfig,\n} from \"./scheme.js\";\nexport {\n registerExactDirectAptosClient,\n type AptosClientConfig,\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 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 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 Exact-Direct Client Scheme\n *\n * The client executes the FA transfer directly and provides\n * the transaction hash as proof of payment.\n */\n\nimport type {\n SchemeNetworkClient,\n PaymentPayload,\n PaymentRequirements,\n} from \"@t402/core/types\";\nimport { SCHEME_EXACT_DIRECT, APTOS_CAIP2_NAMESPACE } from \"../../constants.js\";\nimport type { ClientAptosSigner, ExactDirectAptosPayload } from \"../../types.js\";\nimport { getTokenConfig } from \"../../tokens.js\";\nimport {\n isValidAptosAddress,\n parseAssetIdentifier,\n compareAddresses,\n} from \"../../utils.js\";\n\n/**\n * Configuration for ExactDirectAptosClient\n */\nexport interface ExactDirectAptosClientConfig {\n /**\n * Whether to verify the transfer was successful before returning\n * @default true\n */\n verifyTransfer?: boolean;\n}\n\n/**\n * Aptos Exact-Direct Client\n *\n * Implements the client-side payment flow where the client:\n * 1. Receives payment requirements\n * 2. Executes the FA transfer transaction\n * 3. Returns transaction hash as proof\n */\nexport class ExactDirectAptosClient implements SchemeNetworkClient {\n readonly scheme = SCHEME_EXACT_DIRECT;\n\n constructor(\n private readonly signer: ClientAptosSigner,\n config: ExactDirectAptosClientConfig = {},\n ) {\n // Config reserved for future use (e.g., verifyTransfer option)\n void config;\n }\n\n /**\n * Create a payment payload by executing the transfer\n */\n async createPaymentPayload(\n t402Version: number,\n paymentRequirements: PaymentRequirements,\n ): Promise<Pick<PaymentPayload, \"t402Version\" | \"payload\">> {\n // Validate requirements\n this.validateRequirements(paymentRequirements);\n\n // Get sender address\n const from = await this.signer.getAddress();\n\n // Parse asset to get metadata address\n const assetInfo = parseAssetIdentifier(paymentRequirements.asset);\n if (!assetInfo) {\n throw new Error(`Invalid asset identifier: ${paymentRequirements.asset}`);\n }\n\n // Get amount\n const amount = BigInt(paymentRequirements.amount);\n\n // Check balance\n const balance = await this.signer.getBalance(assetInfo.metadataAddress);\n if (balance < amount) {\n throw new Error(\n `Insufficient balance: have ${balance}, need ${amount}`,\n );\n }\n\n // Execute transfer\n const txHash = await this.signer.transfer(\n paymentRequirements.payTo,\n assetInfo.metadataAddress,\n amount,\n );\n\n // Create payload\n const payload: ExactDirectAptosPayload = {\n txHash,\n from,\n to: paymentRequirements.payTo,\n amount: paymentRequirements.amount,\n metadataAddress: assetInfo.metadataAddress,\n };\n\n return {\n t402Version,\n payload,\n };\n }\n\n /**\n * Validate payment requirements\n */\n private validateRequirements(requirements: PaymentRequirements): void {\n // Check scheme\n if (requirements.scheme !== SCHEME_EXACT_DIRECT) {\n throw new Error(\n `Invalid scheme: expected ${SCHEME_EXACT_DIRECT}, got ${requirements.scheme}`,\n );\n }\n\n // Check network\n if (!requirements.network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`)) {\n throw new Error(`Invalid network: ${requirements.network}`);\n }\n\n // Check payTo address\n if (!isValidAptosAddress(requirements.payTo)) {\n throw new Error(`Invalid payTo address: ${requirements.payTo}`);\n }\n\n // Check amount\n const amount = BigInt(requirements.amount);\n if (amount <= 0n) {\n throw new Error(`Invalid amount: ${requirements.amount}`);\n }\n\n // Check asset\n const assetInfo = parseAssetIdentifier(requirements.asset);\n if (!assetInfo) {\n throw new Error(`Invalid asset: ${requirements.asset}`);\n }\n\n // Verify token is supported\n const tokenConfig = getTokenConfig(requirements.network, \"USDT\");\n if (tokenConfig && !compareAddresses(tokenConfig.metadataAddress, assetInfo.metadataAddress)) {\n // Allow any valid FA, but log warning for unknown tokens\n console.warn(\n `Using non-standard token: ${assetInfo.metadataAddress}`,\n );\n }\n }\n}\n\nexport default ExactDirectAptosClient;\n","/**\n * Registration function for Aptos Exact-Direct client\n */\n\nimport { t402Client, PaymentPolicy } from \"@t402/core/client\";\nimport type { Network } from \"@t402/core/types\";\nimport type { ClientAptosSigner } from \"../../types.js\";\nimport {\n ExactDirectAptosClient,\n type ExactDirectAptosClientConfig,\n} from \"./scheme.js\";\n\n/**\n * Configuration options for registering Aptos schemes to a t402Client\n */\nexport interface AptosClientConfig {\n /**\n * The Aptos signer for client operations\n */\n signer: ClientAptosSigner;\n\n /**\n * Optional policies to apply to the client\n */\n policies?: PaymentPolicy[];\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?: ExactDirectAptosClientConfig;\n}\n\n/**\n * Registers Aptos exact-direct payment schemes to a t402Client instance.\n *\n * @param client - The t402Client instance to register schemes to\n * @param config - Configuration for Aptos client registration\n * @returns The client instance for chaining\n *\n * @example\n * ```typescript\n * import { registerExactDirectAptosClient } from \"@t402/aptos/exact-direct/client\";\n * import { t402Client } from \"@t402/core/client\";\n *\n * const client = new t402Client();\n * registerExactDirectAptosClient(client, {\n * signer: myAptosSigner,\n * networks: [\"aptos:1\"]\n * });\n * ```\n */\nexport function registerExactDirectAptosClient(\n client: t402Client,\n config: AptosClientConfig,\n): t402Client {\n const scheme = new ExactDirectAptosClient(config.signer, config.schemeConfig);\n\n // Register scheme\n if (config.networks && config.networks.length > 0) {\n // Register specific networks\n config.networks.forEach((network) => {\n client.register(network, scheme);\n });\n } else {\n // Register wildcard for all Aptos networks\n client.register(\"aptos:*\", scheme);\n }\n\n // Apply policies if provided\n if (config.policies) {\n config.policies.forEach((policy) => {\n client.registerPolicy(policy);\n });\n }\n\n return client;\n}\n"],"mappings":"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","names":[]}
|