@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/src/utils.ts
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Aptos Utility Functions
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { Network } from "@t402/core/types";
|
|
6
|
+
import {
|
|
7
|
+
APTOS_CAIP2_NAMESPACE,
|
|
8
|
+
APTOS_MAINNET_CAIP2,
|
|
9
|
+
APTOS_TESTNET_CAIP2,
|
|
10
|
+
APTOS_DEVNET_CAIP2,
|
|
11
|
+
DEFAULT_MAINNET_RPC,
|
|
12
|
+
DEFAULT_TESTNET_RPC,
|
|
13
|
+
DEFAULT_DEVNET_RPC,
|
|
14
|
+
FA_TRANSFER_FUNCTION,
|
|
15
|
+
} from "./constants.js";
|
|
16
|
+
import type {
|
|
17
|
+
AptosTransactionResult,
|
|
18
|
+
AptosTransactionEvent,
|
|
19
|
+
ParsedFATransfer,
|
|
20
|
+
} from "./types.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Validate Aptos address format
|
|
24
|
+
* Aptos addresses are 64 hex characters (32 bytes) with 0x prefix
|
|
25
|
+
*/
|
|
26
|
+
export function isValidAptosAddress(address: string): boolean {
|
|
27
|
+
if (!address) return false;
|
|
28
|
+
// Must start with 0x
|
|
29
|
+
if (!address.startsWith("0x")) return false;
|
|
30
|
+
// Remove 0x prefix and check hex
|
|
31
|
+
const hex = address.slice(2);
|
|
32
|
+
// Aptos addresses can be 1-64 hex chars (leading zeros may be omitted)
|
|
33
|
+
if (hex.length === 0 || hex.length > 64) return false;
|
|
34
|
+
return /^[0-9a-fA-F]+$/.test(hex);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Normalize Aptos address to full 64-character format
|
|
39
|
+
*/
|
|
40
|
+
export function normalizeAptosAddress(address: string): string {
|
|
41
|
+
if (!address.startsWith("0x")) {
|
|
42
|
+
throw new Error("Aptos address must start with 0x");
|
|
43
|
+
}
|
|
44
|
+
const hex = address.slice(2).toLowerCase();
|
|
45
|
+
// Pad to 64 characters
|
|
46
|
+
return "0x" + hex.padStart(64, "0");
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Compare two Aptos addresses (case-insensitive, handles short addresses)
|
|
51
|
+
*/
|
|
52
|
+
export function compareAddresses(addr1: string, addr2: string): boolean {
|
|
53
|
+
try {
|
|
54
|
+
return normalizeAptosAddress(addr1) === normalizeAptosAddress(addr2);
|
|
55
|
+
} catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Validate transaction hash format
|
|
62
|
+
*/
|
|
63
|
+
export function isValidTxHash(txHash: string): boolean {
|
|
64
|
+
if (!txHash) return false;
|
|
65
|
+
if (!txHash.startsWith("0x")) return false;
|
|
66
|
+
const hex = txHash.slice(2);
|
|
67
|
+
// Transaction hash is 64 hex characters (32 bytes)
|
|
68
|
+
if (hex.length !== 64) return false;
|
|
69
|
+
return /^[0-9a-fA-F]+$/.test(hex);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Get default RPC URL for a network
|
|
74
|
+
*/
|
|
75
|
+
export function getDefaultRpcUrl(network: Network): string {
|
|
76
|
+
switch (network) {
|
|
77
|
+
case APTOS_MAINNET_CAIP2:
|
|
78
|
+
return DEFAULT_MAINNET_RPC;
|
|
79
|
+
case APTOS_TESTNET_CAIP2:
|
|
80
|
+
return DEFAULT_TESTNET_RPC;
|
|
81
|
+
case APTOS_DEVNET_CAIP2:
|
|
82
|
+
return DEFAULT_DEVNET_RPC;
|
|
83
|
+
default:
|
|
84
|
+
throw new Error(`Unknown Aptos network: ${network}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Check if a network identifier is for Aptos
|
|
90
|
+
*/
|
|
91
|
+
export function isAptosNetwork(network: Network): boolean {
|
|
92
|
+
return network.startsWith(`${APTOS_CAIP2_NAMESPACE}:`);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Parse CAIP-19 asset identifier for Aptos
|
|
97
|
+
* Format: aptos:1/fa:0x...
|
|
98
|
+
*/
|
|
99
|
+
export function parseAssetIdentifier(asset: string): {
|
|
100
|
+
network: Network;
|
|
101
|
+
metadataAddress: string;
|
|
102
|
+
} | null {
|
|
103
|
+
const parts = asset.split("/");
|
|
104
|
+
if (parts.length !== 2) return null;
|
|
105
|
+
|
|
106
|
+
const network = parts[0] as Network;
|
|
107
|
+
if (!isAptosNetwork(network)) return null;
|
|
108
|
+
|
|
109
|
+
const [assetType, address] = parts[1].split(":");
|
|
110
|
+
if (assetType !== "fa" || !address) return null;
|
|
111
|
+
|
|
112
|
+
if (!isValidAptosAddress(address)) return null;
|
|
113
|
+
|
|
114
|
+
return { network, metadataAddress: address };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Create CAIP-19 asset identifier for Aptos FA
|
|
119
|
+
*/
|
|
120
|
+
export function createAssetIdentifier(
|
|
121
|
+
network: Network,
|
|
122
|
+
metadataAddress: string,
|
|
123
|
+
): string {
|
|
124
|
+
return `${network}/fa:${metadataAddress}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Parse fungible asset transfer from transaction events
|
|
129
|
+
*/
|
|
130
|
+
export function parseFATransferFromEvents(
|
|
131
|
+
events: AptosTransactionEvent[],
|
|
132
|
+
): ParsedFATransfer | null {
|
|
133
|
+
// Look for Withdraw and Deposit events
|
|
134
|
+
const withdrawEvent = events.find(
|
|
135
|
+
(e) =>
|
|
136
|
+
e.type === "0x1::fungible_asset::Withdraw" ||
|
|
137
|
+
e.type.includes("::fungible_asset::Withdraw"),
|
|
138
|
+
);
|
|
139
|
+
const depositEvent = events.find(
|
|
140
|
+
(e) =>
|
|
141
|
+
e.type === "0x1::fungible_asset::Deposit" ||
|
|
142
|
+
e.type.includes("::fungible_asset::Deposit"),
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
if (!withdrawEvent || !depositEvent) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Extract data from events
|
|
150
|
+
const withdrawData = withdrawEvent.data as {
|
|
151
|
+
store?: string;
|
|
152
|
+
amount?: string;
|
|
153
|
+
};
|
|
154
|
+
const depositData = depositEvent.data as {
|
|
155
|
+
store?: string;
|
|
156
|
+
amount?: string;
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
if (!withdrawData.amount || !depositData.store) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// The from address is the account that owns the withdraw store
|
|
164
|
+
// The to address is the account that owns the deposit store
|
|
165
|
+
// For simplicity, we'll extract from the event guid
|
|
166
|
+
const from = withdrawEvent.guid.accountAddress;
|
|
167
|
+
const to = depositEvent.guid.accountAddress;
|
|
168
|
+
const amount = BigInt(withdrawData.amount);
|
|
169
|
+
|
|
170
|
+
// Metadata address would need to be extracted from state changes
|
|
171
|
+
// For now, return with empty metadata (to be filled by caller)
|
|
172
|
+
return {
|
|
173
|
+
from,
|
|
174
|
+
to,
|
|
175
|
+
amount,
|
|
176
|
+
metadataAddress: "", // Will be filled from transaction details
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if transaction is a FA transfer
|
|
182
|
+
*/
|
|
183
|
+
export function isFATransferTransaction(tx: AptosTransactionResult): boolean {
|
|
184
|
+
if (!tx.payload) return false;
|
|
185
|
+
if (tx.payload.type !== "entry_function_payload") return false;
|
|
186
|
+
return (
|
|
187
|
+
tx.payload.function === FA_TRANSFER_FUNCTION ||
|
|
188
|
+
tx.payload.function?.includes("primary_fungible_store::transfer") ||
|
|
189
|
+
false
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Extract transfer details from transaction
|
|
195
|
+
*/
|
|
196
|
+
export function extractTransferDetails(
|
|
197
|
+
tx: AptosTransactionResult,
|
|
198
|
+
): ParsedFATransfer | null {
|
|
199
|
+
if (!tx.success) return null;
|
|
200
|
+
if (!tx.payload || tx.payload.type !== "entry_function_payload") return null;
|
|
201
|
+
|
|
202
|
+
const args = tx.payload.arguments;
|
|
203
|
+
if (!args || args.length < 3) return null;
|
|
204
|
+
|
|
205
|
+
// Arguments for primary_fungible_store::transfer:
|
|
206
|
+
// [0] - metadata object address
|
|
207
|
+
// [1] - recipient address
|
|
208
|
+
// [2] - amount
|
|
209
|
+
|
|
210
|
+
const metadataAddress = args[0] as string;
|
|
211
|
+
const to = args[1] as string;
|
|
212
|
+
const amount = BigInt(args[2] as string);
|
|
213
|
+
|
|
214
|
+
return {
|
|
215
|
+
from: tx.sender,
|
|
216
|
+
to,
|
|
217
|
+
amount,
|
|
218
|
+
metadataAddress,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Format amount with decimals for display
|
|
224
|
+
*/
|
|
225
|
+
export function formatAmount(amount: bigint, decimals: number): string {
|
|
226
|
+
const divisor = BigInt(10 ** decimals);
|
|
227
|
+
const wholePart = amount / divisor;
|
|
228
|
+
const fractionalPart = amount % divisor;
|
|
229
|
+
const paddedFractional = fractionalPart.toString().padStart(decimals, "0");
|
|
230
|
+
return `${wholePart}.${paddedFractional}`;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Parse amount string to bigint
|
|
235
|
+
*/
|
|
236
|
+
export function parseAmount(amount: string, decimals: number): bigint {
|
|
237
|
+
const [whole, fractional = ""] = amount.split(".");
|
|
238
|
+
const paddedFractional = fractional.padEnd(decimals, "0").slice(0, decimals);
|
|
239
|
+
return BigInt(whole + paddedFractional);
|
|
240
|
+
}
|