@aptos-labs/cross-chain-core 4.23.1
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/LICENSE +201 -0
- package/dist/CrossChainCore.d.ts +36 -0
- package/dist/CrossChainCore.d.ts.map +1 -0
- package/dist/config/index.d.ts +4 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/mainnet/chains.d.ts +17 -0
- package/dist/config/mainnet/chains.d.ts.map +1 -0
- package/dist/config/mainnet/index.d.ts +3 -0
- package/dist/config/mainnet/index.d.ts.map +1 -0
- package/dist/config/mainnet/tokens.d.ts +4 -0
- package/dist/config/mainnet/tokens.d.ts.map +1 -0
- package/dist/config/testnet/chains.d.ts +19 -0
- package/dist/config/testnet/chains.d.ts.map +1 -0
- package/dist/config/testnet/index.d.ts +3 -0
- package/dist/config/testnet/index.d.ts.map +1 -0
- package/dist/config/testnet/tokens.d.ts +4 -0
- package/dist/config/testnet/tokens.d.ts.map +1 -0
- package/dist/config/types.d.ts +41 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +989 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +957 -0
- package/dist/index.mjs.map +1 -0
- package/dist/providers/wormhole/index.d.ts +5 -0
- package/dist/providers/wormhole/index.d.ts.map +1 -0
- package/dist/providers/wormhole/signers/AptosLocalSigner.d.ts +18 -0
- package/dist/providers/wormhole/signers/AptosLocalSigner.d.ts.map +1 -0
- package/dist/providers/wormhole/signers/EthereumSigner.d.ts +5 -0
- package/dist/providers/wormhole/signers/EthereumSigner.d.ts.map +1 -0
- package/dist/providers/wormhole/signers/Signer.d.ts +17 -0
- package/dist/providers/wormhole/signers/Signer.d.ts.map +1 -0
- package/dist/providers/wormhole/signers/SolanaSigner.d.ts +28 -0
- package/dist/providers/wormhole/signers/SolanaSigner.d.ts.map +1 -0
- package/dist/providers/wormhole/types.d.ts +39 -0
- package/dist/providers/wormhole/types.d.ts.map +1 -0
- package/dist/providers/wormhole/wormhole.d.ts +35 -0
- package/dist/providers/wormhole/wormhole.d.ts.map +1 -0
- package/dist/utils/getUsdcBalance.d.ts +5 -0
- package/dist/utils/getUsdcBalance.d.ts.map +1 -0
- package/dist/utils/logger.d.ts +6 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/package.json +83 -0
- package/src/CrossChainCore.ts +130 -0
- package/src/config/index.ts +3 -0
- package/src/config/mainnet/chains.ts +64 -0
- package/src/config/mainnet/index.ts +2 -0
- package/src/config/mainnet/tokens.ts +43 -0
- package/src/config/testnet/chains.ts +69 -0
- package/src/config/testnet/index.ts +2 -0
- package/src/config/testnet/tokens.ts +43 -0
- package/src/config/types.ts +45 -0
- package/src/index.ts +5 -0
- package/src/providers/wormhole/index.ts +4 -0
- package/src/providers/wormhole/signers/AptosLocalSigner.ts +136 -0
- package/src/providers/wormhole/signers/EthereumSigner.ts +49 -0
- package/src/providers/wormhole/signers/Signer.ts +102 -0
- package/src/providers/wormhole/signers/SolanaSigner.ts +418 -0
- package/src/providers/wormhole/types.ts +59 -0
- package/src/providers/wormhole/wormhole.ts +320 -0
- package/src/utils/getUsdcBalance.ts +82 -0
- package/src/utils/logger.ts +17 -0
- package/src/version.ts +1 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,957 @@
|
|
|
1
|
+
// src/CrossChainCore.ts
|
|
2
|
+
import { Network as Network3 } from "@aptos-labs/ts-sdk";
|
|
3
|
+
|
|
4
|
+
// src/providers/wormhole/wormhole.ts
|
|
5
|
+
import {
|
|
6
|
+
chainToPlatform,
|
|
7
|
+
routes,
|
|
8
|
+
Wormhole,
|
|
9
|
+
wormhole,
|
|
10
|
+
TransferState
|
|
11
|
+
} from "@wormhole-foundation/sdk";
|
|
12
|
+
import { Network, sleep as sleep2 } from "@aptos-labs/ts-sdk";
|
|
13
|
+
import aptos from "@wormhole-foundation/sdk/aptos";
|
|
14
|
+
import solana from "@wormhole-foundation/sdk/solana";
|
|
15
|
+
import evm from "@wormhole-foundation/sdk/evm";
|
|
16
|
+
|
|
17
|
+
// src/utils/logger.ts
|
|
18
|
+
var logger = {
|
|
19
|
+
log: (...args) => {
|
|
20
|
+
if (process.env.NODE_ENV === "development") {
|
|
21
|
+
console.log(...args);
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
warn: (...args) => {
|
|
25
|
+
if (process.env.NODE_ENV === "development") {
|
|
26
|
+
console.warn(...args);
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
error: (...args) => {
|
|
30
|
+
if (process.env.NODE_ENV === "development") {
|
|
31
|
+
console.error(...args);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// src/providers/wormhole/signers/AptosLocalSigner.ts
|
|
37
|
+
import {
|
|
38
|
+
Aptos,
|
|
39
|
+
AptosConfig,
|
|
40
|
+
Network as AptosNetwork
|
|
41
|
+
} from "@aptos-labs/ts-sdk";
|
|
42
|
+
var AptosLocalSigner = class {
|
|
43
|
+
constructor(chain, options, wallet, feePayerAccount) {
|
|
44
|
+
this._chain = chain;
|
|
45
|
+
this._options = options;
|
|
46
|
+
this._wallet = wallet;
|
|
47
|
+
this._sponsorAccount = feePayerAccount;
|
|
48
|
+
this._claimedTransactionHashes = "";
|
|
49
|
+
}
|
|
50
|
+
chain() {
|
|
51
|
+
return this._chain;
|
|
52
|
+
}
|
|
53
|
+
address() {
|
|
54
|
+
return this._wallet.accountAddress.toString();
|
|
55
|
+
}
|
|
56
|
+
claimedTransactionHashes() {
|
|
57
|
+
return this._claimedTransactionHashes;
|
|
58
|
+
}
|
|
59
|
+
async signAndSend(txs) {
|
|
60
|
+
const txHashes = [];
|
|
61
|
+
for (const tx of txs) {
|
|
62
|
+
const txId = await signAndSendTransaction(
|
|
63
|
+
tx,
|
|
64
|
+
this._wallet,
|
|
65
|
+
this._sponsorAccount
|
|
66
|
+
);
|
|
67
|
+
txHashes.push(txId);
|
|
68
|
+
this._claimedTransactionHashes = txId;
|
|
69
|
+
}
|
|
70
|
+
return txHashes;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
async function signAndSendTransaction(request, wallet, sponsorAccount) {
|
|
74
|
+
if (!wallet) {
|
|
75
|
+
throw new Error("Wallet is undefined");
|
|
76
|
+
}
|
|
77
|
+
const payload = request.transaction;
|
|
78
|
+
payload.functionArguments = payload.functionArguments.map((a) => {
|
|
79
|
+
if (a instanceof Uint8Array) {
|
|
80
|
+
return Array.from(a);
|
|
81
|
+
} else if (typeof a === "bigint") {
|
|
82
|
+
return a.toString();
|
|
83
|
+
} else {
|
|
84
|
+
return a;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
const aptosConfig = new AptosConfig({
|
|
88
|
+
network: AptosNetwork.TESTNET
|
|
89
|
+
});
|
|
90
|
+
const aptos2 = new Aptos(aptosConfig);
|
|
91
|
+
const txnToSign = await aptos2.transaction.build.simple({
|
|
92
|
+
data: payload,
|
|
93
|
+
sender: wallet.accountAddress.toString(),
|
|
94
|
+
withFeePayer: sponsorAccount ? true : false
|
|
95
|
+
});
|
|
96
|
+
const senderAuthenticator = await aptos2.transaction.sign({
|
|
97
|
+
signer: wallet,
|
|
98
|
+
transaction: txnToSign
|
|
99
|
+
});
|
|
100
|
+
const txnToSubmit = {
|
|
101
|
+
transaction: txnToSign,
|
|
102
|
+
senderAuthenticator
|
|
103
|
+
};
|
|
104
|
+
if (sponsorAccount) {
|
|
105
|
+
if (typeof sponsorAccount === "string") {
|
|
106
|
+
} else {
|
|
107
|
+
const feePayerSignerAuthenticator = aptos2.transaction.signAsFeePayer({
|
|
108
|
+
signer: sponsorAccount,
|
|
109
|
+
transaction: txnToSign
|
|
110
|
+
});
|
|
111
|
+
txnToSubmit.feePayerAuthenticator = feePayerSignerAuthenticator;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
const response = await aptos2.transaction.submit.simple(txnToSubmit);
|
|
115
|
+
const tx = await aptos2.waitForTransaction({
|
|
116
|
+
transactionHash: response.hash
|
|
117
|
+
});
|
|
118
|
+
return tx.hash;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/providers/wormhole/signers/SolanaSigner.ts
|
|
122
|
+
import {
|
|
123
|
+
ComputeBudgetProgram,
|
|
124
|
+
LAMPORTS_PER_SOL
|
|
125
|
+
} from "@solana/web3.js";
|
|
126
|
+
import {
|
|
127
|
+
determinePriorityFee,
|
|
128
|
+
determinePriorityFeeTritonOne
|
|
129
|
+
} from "@wormhole-foundation/sdk-solana";
|
|
130
|
+
import { Connection } from "@solana/web3.js";
|
|
131
|
+
import { SolanaDerivedWallet } from "@aptos-labs/derived-wallet-solana";
|
|
132
|
+
async function signAndSendTransaction2(request, wallet, options, crossChainCore) {
|
|
133
|
+
var _a, _b, _c, _d;
|
|
134
|
+
if (!wallet || !(wallet instanceof SolanaDerivedWallet)) {
|
|
135
|
+
throw new Error("Invalid wallet type or missing Solana wallet").message;
|
|
136
|
+
}
|
|
137
|
+
const commitment = (_a = options == null ? void 0 : options.commitment) != null ? _a : "finalized";
|
|
138
|
+
const connection = new Connection(
|
|
139
|
+
(_d = (_c = (_b = crossChainCore == null ? void 0 : crossChainCore._dappConfig) == null ? void 0 : _b.solanaConfig) == null ? void 0 : _c.rpc) != null ? _d : "https://api.devnet.solana.com"
|
|
140
|
+
);
|
|
141
|
+
const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash(commitment);
|
|
142
|
+
const transaction = request.transaction.transaction;
|
|
143
|
+
const unsignedTx = await setPriorityFeeInstructions(
|
|
144
|
+
connection,
|
|
145
|
+
blockhash,
|
|
146
|
+
lastValidBlockHeight,
|
|
147
|
+
request,
|
|
148
|
+
crossChainCore
|
|
149
|
+
);
|
|
150
|
+
let confirmTransactionPromise = null;
|
|
151
|
+
let confirmedTx = null;
|
|
152
|
+
let txSendAttempts = 1;
|
|
153
|
+
let signature = "";
|
|
154
|
+
if (!wallet.solanaWallet.signTransaction) {
|
|
155
|
+
throw new Error("Wallet does not support signing transactions").message;
|
|
156
|
+
}
|
|
157
|
+
const tx = await wallet.solanaWallet.signTransaction(unsignedTx);
|
|
158
|
+
if (!tx)
|
|
159
|
+
throw new Error("Failed to sign transaction").message;
|
|
160
|
+
const serializedTx = tx.serialize();
|
|
161
|
+
const sendOptions = {
|
|
162
|
+
skipPreflight: true,
|
|
163
|
+
maxRetries: 0,
|
|
164
|
+
preFlightCommitment: commitment
|
|
165
|
+
};
|
|
166
|
+
signature = await connection.sendRawTransaction(serializedTx, sendOptions);
|
|
167
|
+
confirmTransactionPromise = connection.confirmTransaction(
|
|
168
|
+
{
|
|
169
|
+
signature,
|
|
170
|
+
blockhash,
|
|
171
|
+
lastValidBlockHeight
|
|
172
|
+
},
|
|
173
|
+
commitment
|
|
174
|
+
);
|
|
175
|
+
const txRetryInterval = 5e3;
|
|
176
|
+
while (!confirmedTx) {
|
|
177
|
+
confirmedTx = await Promise.race([
|
|
178
|
+
confirmTransactionPromise,
|
|
179
|
+
new Promise(
|
|
180
|
+
(resolve) => setTimeout(() => {
|
|
181
|
+
resolve(null);
|
|
182
|
+
}, txRetryInterval)
|
|
183
|
+
)
|
|
184
|
+
]);
|
|
185
|
+
if (confirmedTx) {
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
console.log(
|
|
189
|
+
`Tx not confirmed after ${txRetryInterval * txSendAttempts++}ms, resending`
|
|
190
|
+
);
|
|
191
|
+
try {
|
|
192
|
+
await connection.sendRawTransaction(serializedTx, sendOptions);
|
|
193
|
+
} catch (e) {
|
|
194
|
+
console.error("Failed to resend transaction:", e);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
if (confirmedTx.value.err) {
|
|
198
|
+
let errorMessage = `Transaction failed: ${confirmedTx.value.err}`;
|
|
199
|
+
if (typeof confirmedTx.value.err === "object") {
|
|
200
|
+
try {
|
|
201
|
+
errorMessage = `Transaction failed: ${JSON.stringify(
|
|
202
|
+
confirmedTx.value.err,
|
|
203
|
+
(_key, value) => typeof value === "bigint" ? value.toString() : value
|
|
204
|
+
)}`;
|
|
205
|
+
} catch (e) {
|
|
206
|
+
errorMessage = `Transaction failed: Unknown error`;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
throw new Error(`Transaction failed: ${errorMessage}`).message;
|
|
210
|
+
}
|
|
211
|
+
return signature;
|
|
212
|
+
}
|
|
213
|
+
async function setPriorityFeeInstructions(connection, blockhash, lastValidBlockHeight, request, crossChainCore) {
|
|
214
|
+
const unsignedTx = request.transaction.transaction;
|
|
215
|
+
const computeBudgetIxFilter = (ix) => ix.programId.toString() !== "ComputeBudget111111111111111111111111111111";
|
|
216
|
+
unsignedTx.recentBlockhash = blockhash;
|
|
217
|
+
unsignedTx.lastValidBlockHeight = lastValidBlockHeight;
|
|
218
|
+
unsignedTx.instructions = unsignedTx.instructions.filter(
|
|
219
|
+
computeBudgetIxFilter
|
|
220
|
+
);
|
|
221
|
+
unsignedTx.add(
|
|
222
|
+
...await createPriorityFeeInstructions(
|
|
223
|
+
connection,
|
|
224
|
+
unsignedTx,
|
|
225
|
+
crossChainCore
|
|
226
|
+
)
|
|
227
|
+
);
|
|
228
|
+
if (request.transaction.signers) {
|
|
229
|
+
unsignedTx.partialSign(...request.transaction.signers);
|
|
230
|
+
}
|
|
231
|
+
return unsignedTx;
|
|
232
|
+
}
|
|
233
|
+
async function createPriorityFeeInstructions(connection, transaction, crossChainCore) {
|
|
234
|
+
var _a, _b, _c;
|
|
235
|
+
let unitsUsed = 2e5;
|
|
236
|
+
let simulationAttempts = 0;
|
|
237
|
+
simulationLoop:
|
|
238
|
+
while (true) {
|
|
239
|
+
const response = await connection.simulateTransaction(
|
|
240
|
+
transaction
|
|
241
|
+
);
|
|
242
|
+
if (response.value.err) {
|
|
243
|
+
if (checkKnownSimulationError(response.value)) {
|
|
244
|
+
if (simulationAttempts < 5) {
|
|
245
|
+
simulationAttempts++;
|
|
246
|
+
await sleep(1e3);
|
|
247
|
+
continue simulationLoop;
|
|
248
|
+
}
|
|
249
|
+
} else if (simulationAttempts < 3) {
|
|
250
|
+
simulationAttempts++;
|
|
251
|
+
await sleep(1e3);
|
|
252
|
+
continue simulationLoop;
|
|
253
|
+
}
|
|
254
|
+
throw new Error(
|
|
255
|
+
`Simulation failed: ${JSON.stringify(response.value.err)}
|
|
256
|
+
Logs:
|
|
257
|
+
${(response.value.logs || []).join("\n ")}`
|
|
258
|
+
).message;
|
|
259
|
+
} else {
|
|
260
|
+
if (response.value.unitsConsumed) {
|
|
261
|
+
unitsUsed = response.value.unitsConsumed;
|
|
262
|
+
}
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
const unitBudget = Math.floor(unitsUsed * 1.2);
|
|
267
|
+
const instructions = [];
|
|
268
|
+
instructions.push(
|
|
269
|
+
ComputeBudgetProgram.setComputeUnitLimit({
|
|
270
|
+
units: unitBudget
|
|
271
|
+
})
|
|
272
|
+
);
|
|
273
|
+
const {
|
|
274
|
+
percentile = 0.9,
|
|
275
|
+
percentileMultiple = 1,
|
|
276
|
+
min = 1e5,
|
|
277
|
+
max = 1e8
|
|
278
|
+
} = (_c = (_b = (_a = crossChainCore == null ? void 0 : crossChainCore._dappConfig) == null ? void 0 : _a.solanaConfig) == null ? void 0 : _b.priorityFeeConfig) != null ? _c : {};
|
|
279
|
+
const calculateFee = async (rpcProvider2) => {
|
|
280
|
+
if (rpcProvider2 === "triton") {
|
|
281
|
+
try {
|
|
282
|
+
const fee2 = await determinePriorityFeeTritonOne(
|
|
283
|
+
connection,
|
|
284
|
+
transaction,
|
|
285
|
+
percentile,
|
|
286
|
+
percentileMultiple,
|
|
287
|
+
min,
|
|
288
|
+
max
|
|
289
|
+
);
|
|
290
|
+
return {
|
|
291
|
+
fee: fee2,
|
|
292
|
+
methodUsed: "triton"
|
|
293
|
+
};
|
|
294
|
+
} catch (e) {
|
|
295
|
+
console.warn(`Failed to determine priority fee using Triton RPC:`, e);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
try {
|
|
299
|
+
const fee2 = await determinePriorityFee(
|
|
300
|
+
connection,
|
|
301
|
+
transaction,
|
|
302
|
+
percentile,
|
|
303
|
+
percentileMultiple,
|
|
304
|
+
min,
|
|
305
|
+
max
|
|
306
|
+
);
|
|
307
|
+
return {
|
|
308
|
+
fee: fee2,
|
|
309
|
+
methodUsed: "default"
|
|
310
|
+
};
|
|
311
|
+
} catch (e) {
|
|
312
|
+
console.warn(`Failed to determine priority fee using Triton RPC:`, e);
|
|
313
|
+
return {
|
|
314
|
+
fee: min,
|
|
315
|
+
methodUsed: "minimum"
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
};
|
|
319
|
+
const rpcProvider = determineRpcProvider(connection.rpcEndpoint);
|
|
320
|
+
const { fee, methodUsed } = await calculateFee(rpcProvider);
|
|
321
|
+
const maxFeeInSol = fee / 1e6 / LAMPORTS_PER_SOL * unitBudget;
|
|
322
|
+
console.table({
|
|
323
|
+
"RPC Provider": rpcProvider,
|
|
324
|
+
"Method used": methodUsed,
|
|
325
|
+
"Percentile used": percentile,
|
|
326
|
+
"Multiple used": percentileMultiple,
|
|
327
|
+
"Compute budget": unitBudget,
|
|
328
|
+
"Priority fee": fee,
|
|
329
|
+
"Max fee in SOL": maxFeeInSol
|
|
330
|
+
});
|
|
331
|
+
instructions.push(
|
|
332
|
+
ComputeBudgetProgram.setComputeUnitPrice({ microLamports: fee })
|
|
333
|
+
);
|
|
334
|
+
return instructions;
|
|
335
|
+
}
|
|
336
|
+
function checkKnownSimulationError(response) {
|
|
337
|
+
const errors = {};
|
|
338
|
+
if (response.err === "BlockhashNotFound") {
|
|
339
|
+
errors["BlockhashNotFound"] = "Blockhash not found during simulation. Trying again.";
|
|
340
|
+
}
|
|
341
|
+
if (response.logs) {
|
|
342
|
+
for (const line of response.logs) {
|
|
343
|
+
if (line.includes("SlippageToleranceExceeded")) {
|
|
344
|
+
errors["SlippageToleranceExceeded"] = "Slippage failure during simulation. Trying again.";
|
|
345
|
+
}
|
|
346
|
+
if (line.includes("RequireGteViolated")) {
|
|
347
|
+
errors["RequireGteViolated"] = "Swap instruction failure during simulation. Trying again.";
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
if (isEmptyObject(errors)) {
|
|
352
|
+
return false;
|
|
353
|
+
}
|
|
354
|
+
console.table(errors);
|
|
355
|
+
return true;
|
|
356
|
+
}
|
|
357
|
+
async function sleep(timeout) {
|
|
358
|
+
return new Promise((resolve) => setTimeout(resolve, timeout));
|
|
359
|
+
}
|
|
360
|
+
var isEmptyObject = (value) => {
|
|
361
|
+
if (value === null || value === void 0) {
|
|
362
|
+
return true;
|
|
363
|
+
}
|
|
364
|
+
for (const key in value) {
|
|
365
|
+
if (value.hasOwnProperty.call(value, key)) {
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return true;
|
|
370
|
+
};
|
|
371
|
+
function determineRpcProvider(endpoint) {
|
|
372
|
+
try {
|
|
373
|
+
const url = new URL(endpoint);
|
|
374
|
+
const hostname = url.hostname;
|
|
375
|
+
if (hostname === "rpcpool.com") {
|
|
376
|
+
return "triton";
|
|
377
|
+
} else if (hostname === "helius-rpc.com") {
|
|
378
|
+
return "helius";
|
|
379
|
+
} else if (hostname === "rpc.ankr.com") {
|
|
380
|
+
return "ankr";
|
|
381
|
+
} else {
|
|
382
|
+
return "unknown";
|
|
383
|
+
}
|
|
384
|
+
} catch (e) {
|
|
385
|
+
return "unknown";
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
// src/providers/wormhole/signers/EthereumSigner.ts
|
|
390
|
+
import { ethers, getBigInt } from "ethers";
|
|
391
|
+
async function signAndSendTransaction3(request, wallet, chainName, options) {
|
|
392
|
+
if (!wallet) {
|
|
393
|
+
throw new Error("wallet.sendTransaction is undefined").message;
|
|
394
|
+
}
|
|
395
|
+
const chainId = await wallet.eip1193Provider.request({
|
|
396
|
+
method: "eth_chainId"
|
|
397
|
+
});
|
|
398
|
+
const actualChainId = parseInt(chainId, 16);
|
|
399
|
+
if (!actualChainId)
|
|
400
|
+
throw new Error("No signer found for chain" + chainName).message;
|
|
401
|
+
const expectedChainId = request.transaction.chainId ? getBigInt(request.transaction.chainId) : void 0;
|
|
402
|
+
if (!actualChainId || !expectedChainId || BigInt(actualChainId) !== expectedChainId) {
|
|
403
|
+
throw new Error(
|
|
404
|
+
`Signer is not connected to the right chain. Expected ${expectedChainId}, got ${actualChainId}`
|
|
405
|
+
).message;
|
|
406
|
+
}
|
|
407
|
+
const provider = new ethers.BrowserProvider(
|
|
408
|
+
wallet.eip1193Provider
|
|
409
|
+
);
|
|
410
|
+
const signer = await provider.getSigner();
|
|
411
|
+
const response = await signer.sendTransaction(request.transaction);
|
|
412
|
+
const receipt = await response.wait();
|
|
413
|
+
return (receipt == null ? void 0 : receipt.hash) || "";
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// src/providers/wormhole/signers/Signer.ts
|
|
417
|
+
var Signer = class {
|
|
418
|
+
constructor(chain, address, options, wallet, crossChainCore) {
|
|
419
|
+
this._chain = chain;
|
|
420
|
+
this._address = address;
|
|
421
|
+
this._options = options;
|
|
422
|
+
this._wallet = wallet;
|
|
423
|
+
this._crossChainCore = crossChainCore;
|
|
424
|
+
}
|
|
425
|
+
chain() {
|
|
426
|
+
return this._chain.displayName;
|
|
427
|
+
}
|
|
428
|
+
address() {
|
|
429
|
+
return this._address;
|
|
430
|
+
}
|
|
431
|
+
async signAndSend(txs) {
|
|
432
|
+
const txHashes = [];
|
|
433
|
+
for (const tx of txs) {
|
|
434
|
+
const txId = await signAndSendTransaction4(
|
|
435
|
+
this._chain,
|
|
436
|
+
tx,
|
|
437
|
+
this._wallet,
|
|
438
|
+
this._options,
|
|
439
|
+
this._crossChainCore
|
|
440
|
+
);
|
|
441
|
+
txHashes.push(txId);
|
|
442
|
+
}
|
|
443
|
+
return txHashes;
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
var signAndSendTransaction4 = async (chain, request, wallet, options = {}, crossChainCore) => {
|
|
447
|
+
if (!wallet) {
|
|
448
|
+
throw new Error("wallet is undefined");
|
|
449
|
+
}
|
|
450
|
+
if (chain.context === "Solana") {
|
|
451
|
+
const signature = await signAndSendTransaction2(
|
|
452
|
+
request,
|
|
453
|
+
wallet,
|
|
454
|
+
options,
|
|
455
|
+
crossChainCore
|
|
456
|
+
);
|
|
457
|
+
return signature;
|
|
458
|
+
} else if (chain.context === "Ethereum") {
|
|
459
|
+
const tx = await signAndSendTransaction3(
|
|
460
|
+
request,
|
|
461
|
+
wallet,
|
|
462
|
+
chain.displayName,
|
|
463
|
+
options
|
|
464
|
+
);
|
|
465
|
+
return tx;
|
|
466
|
+
} else {
|
|
467
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
// src/providers/wormhole/wormhole.ts
|
|
472
|
+
var WormholeProvider = class {
|
|
473
|
+
constructor(core) {
|
|
474
|
+
this.crossChainCore = core;
|
|
475
|
+
}
|
|
476
|
+
get wormholeContext() {
|
|
477
|
+
return this._wormholeContext;
|
|
478
|
+
}
|
|
479
|
+
async setWormholeContext(sourceChain) {
|
|
480
|
+
var _a;
|
|
481
|
+
const dappNetwork = (_a = this.crossChainCore._dappConfig) == null ? void 0 : _a.aptosNetwork;
|
|
482
|
+
if (dappNetwork === Network.DEVNET) {
|
|
483
|
+
throw new Error("Devnet is not supported on Wormhole");
|
|
484
|
+
}
|
|
485
|
+
if (!sourceChain) {
|
|
486
|
+
throw new Error("Origin chain not selected");
|
|
487
|
+
}
|
|
488
|
+
const isMainnet = dappNetwork === Network.MAINNET;
|
|
489
|
+
const platforms = [aptos, solana, evm];
|
|
490
|
+
const wh = await wormhole(isMainnet ? "Mainnet" : "Testnet", platforms);
|
|
491
|
+
this._wormholeContext = wh;
|
|
492
|
+
}
|
|
493
|
+
async getRoute(sourceChain) {
|
|
494
|
+
if (!this._wormholeContext) {
|
|
495
|
+
throw new Error("Wormhole context not initialized");
|
|
496
|
+
}
|
|
497
|
+
const { sourceToken, destToken } = this.getTokenInfo(sourceChain);
|
|
498
|
+
const sourceContext = this._wormholeContext.getPlatform(chainToPlatform(sourceChain)).getChain(sourceChain);
|
|
499
|
+
logger.log("sourceContext", sourceContext);
|
|
500
|
+
const destContext = this._wormholeContext.getPlatform(chainToPlatform("Aptos")).getChain("Aptos");
|
|
501
|
+
logger.log("destContext", destContext);
|
|
502
|
+
const request = await routes.RouteTransferRequest.create(
|
|
503
|
+
this._wormholeContext,
|
|
504
|
+
{
|
|
505
|
+
source: sourceToken,
|
|
506
|
+
destination: destToken
|
|
507
|
+
},
|
|
508
|
+
sourceContext,
|
|
509
|
+
destContext
|
|
510
|
+
);
|
|
511
|
+
const resolver = this._wormholeContext.resolver([
|
|
512
|
+
routes.CCTPRoute
|
|
513
|
+
]);
|
|
514
|
+
const route = await resolver.findRoutes(request);
|
|
515
|
+
const cctpRoute = route[0];
|
|
516
|
+
this.wormholeRoute = cctpRoute;
|
|
517
|
+
this.wormholeRequest = request;
|
|
518
|
+
return { route: cctpRoute, request };
|
|
519
|
+
}
|
|
520
|
+
async getQuote(input) {
|
|
521
|
+
const { amount, sourceChain } = input;
|
|
522
|
+
if (!this._wormholeContext) {
|
|
523
|
+
await this.setWormholeContext(sourceChain);
|
|
524
|
+
}
|
|
525
|
+
const { route, request } = await this.getRoute(sourceChain);
|
|
526
|
+
const transferParams = {
|
|
527
|
+
amount,
|
|
528
|
+
options: { nativeGas: 0 }
|
|
529
|
+
};
|
|
530
|
+
const validated = await route.validate(request, transferParams);
|
|
531
|
+
if (!validated.valid) {
|
|
532
|
+
logger.log("invalid", validated.valid);
|
|
533
|
+
throw new Error(`Invalid quote: ${validated.error}`).message;
|
|
534
|
+
}
|
|
535
|
+
const quote = await route.quote(request, validated.params);
|
|
536
|
+
if (!quote.success) {
|
|
537
|
+
logger.log("quote failed", quote.success);
|
|
538
|
+
throw new Error(`Invalid quote: ${quote.error}`).message;
|
|
539
|
+
}
|
|
540
|
+
this.wormholeQuote = quote;
|
|
541
|
+
logger.log("quote", quote);
|
|
542
|
+
return quote;
|
|
543
|
+
}
|
|
544
|
+
async submitCCTPTransfer(input) {
|
|
545
|
+
var _a;
|
|
546
|
+
const { sourceChain, wallet, destinationAddress } = input;
|
|
547
|
+
if (!this._wormholeContext) {
|
|
548
|
+
await this.setWormholeContext(sourceChain);
|
|
549
|
+
}
|
|
550
|
+
if (!this.wormholeRoute || !this.wormholeRequest || !this.wormholeQuote) {
|
|
551
|
+
throw new Error("Wormhole route, request, or quote not initialized");
|
|
552
|
+
}
|
|
553
|
+
let signerAddress;
|
|
554
|
+
const chainContext = this.getChainConfig(sourceChain).context;
|
|
555
|
+
if (chainContext === "Solana") {
|
|
556
|
+
signerAddress = ((_a = wallet.solanaWallet.publicKey) == null ? void 0 : _a.toBase58()) || "";
|
|
557
|
+
} else {
|
|
558
|
+
[signerAddress] = await wallet.eip1193Provider.request({
|
|
559
|
+
method: "eth_requestAccounts"
|
|
560
|
+
});
|
|
561
|
+
}
|
|
562
|
+
logger.log("signerAddress", signerAddress);
|
|
563
|
+
const signer = new Signer(
|
|
564
|
+
this.getChainConfig(sourceChain),
|
|
565
|
+
signerAddress,
|
|
566
|
+
{},
|
|
567
|
+
wallet
|
|
568
|
+
);
|
|
569
|
+
let receipt = await this.wormholeRoute.initiate(
|
|
570
|
+
this.wormholeRequest,
|
|
571
|
+
signer,
|
|
572
|
+
this.wormholeQuote,
|
|
573
|
+
Wormhole.chainAddress("Aptos", destinationAddress.toString())
|
|
574
|
+
);
|
|
575
|
+
const originChainTxnId = "originTxs" in receipt ? receipt.originTxs[receipt.originTxs.length - 1].txid : void 0;
|
|
576
|
+
return { originChainTxnId: originChainTxnId || "", receipt };
|
|
577
|
+
}
|
|
578
|
+
async claimCCTPTransfer(input) {
|
|
579
|
+
let { receipt, mainSigner, sponsorAccount } = input;
|
|
580
|
+
if (!this.wormholeRoute) {
|
|
581
|
+
throw new Error("Wormhole route not initialized");
|
|
582
|
+
}
|
|
583
|
+
logger.log("mainSigner", mainSigner.accountAddress.toString());
|
|
584
|
+
let retries = 0;
|
|
585
|
+
const maxRetries = 5;
|
|
586
|
+
const baseDelay = 1e3;
|
|
587
|
+
while (retries < maxRetries) {
|
|
588
|
+
try {
|
|
589
|
+
for await (receipt of this.wormholeRoute.track(receipt, 120 * 1e3)) {
|
|
590
|
+
if (receipt.state >= TransferState.SourceInitiated) {
|
|
591
|
+
logger.log("Receipt is on track ", receipt);
|
|
592
|
+
try {
|
|
593
|
+
const signer = new AptosLocalSigner(
|
|
594
|
+
"Aptos",
|
|
595
|
+
{},
|
|
596
|
+
mainSigner,
|
|
597
|
+
sponsorAccount ? sponsorAccount : void 0
|
|
598
|
+
);
|
|
599
|
+
if (routes.isManual(this.wormholeRoute)) {
|
|
600
|
+
const circleAttestationReceipt = await this.wormholeRoute.complete(signer, receipt);
|
|
601
|
+
logger.log("Claim receipt: ", circleAttestationReceipt);
|
|
602
|
+
const destinationChainTxnId = signer.claimedTransactionHashes();
|
|
603
|
+
return { destinationChainTxnId };
|
|
604
|
+
} else {
|
|
605
|
+
return { destinationChainTxnId: "" };
|
|
606
|
+
}
|
|
607
|
+
} catch (e) {
|
|
608
|
+
console.error("Failed to claim", e);
|
|
609
|
+
return { destinationChainTxnId: "" };
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
} catch (e) {
|
|
614
|
+
console.error(
|
|
615
|
+
`Error tracking transfer (attempt ${retries + 1} / ${maxRetries}):`,
|
|
616
|
+
e
|
|
617
|
+
);
|
|
618
|
+
const delay = baseDelay * Math.pow(2, retries);
|
|
619
|
+
await sleep2(delay);
|
|
620
|
+
retries++;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return { destinationChainTxnId: "" };
|
|
624
|
+
}
|
|
625
|
+
async initiateCCTPTransfer(input) {
|
|
626
|
+
var _a;
|
|
627
|
+
if (((_a = this.crossChainCore._dappConfig) == null ? void 0 : _a.aptosNetwork) === Network.DEVNET) {
|
|
628
|
+
throw new Error("Devnet is not supported on Wormhole");
|
|
629
|
+
}
|
|
630
|
+
if (input.amount) {
|
|
631
|
+
await this.getQuote({
|
|
632
|
+
amount: input.amount,
|
|
633
|
+
sourceChain: input.sourceChain
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
let { originChainTxnId, receipt } = await this.submitCCTPTransfer(input);
|
|
637
|
+
const { destinationChainTxnId } = await this.claimCCTPTransfer({
|
|
638
|
+
receipt,
|
|
639
|
+
mainSigner: input.mainSigner,
|
|
640
|
+
sponsorAccount: input.sponsorAccount
|
|
641
|
+
});
|
|
642
|
+
return { originChainTxnId, destinationChainTxnId };
|
|
643
|
+
}
|
|
644
|
+
getChainConfig(chain) {
|
|
645
|
+
const chainConfig = this.crossChainCore.CHAINS[chain];
|
|
646
|
+
if (!chainConfig) {
|
|
647
|
+
throw new Error(`Chain config not found for chain: ${chain}`);
|
|
648
|
+
}
|
|
649
|
+
return chainConfig;
|
|
650
|
+
}
|
|
651
|
+
getTokenInfo(sourceChain) {
|
|
652
|
+
const sourceToken = Wormhole.tokenId(
|
|
653
|
+
this.crossChainCore.TOKENS[sourceChain].tokenId.chain,
|
|
654
|
+
this.crossChainCore.TOKENS[sourceChain].tokenId.address
|
|
655
|
+
);
|
|
656
|
+
const destToken = Wormhole.tokenId(
|
|
657
|
+
this.crossChainCore.APTOS_TOKEN.tokenId.chain,
|
|
658
|
+
this.crossChainCore.APTOS_TOKEN.tokenId.address
|
|
659
|
+
);
|
|
660
|
+
return { sourceToken, destToken };
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
|
|
664
|
+
// src/config/types.ts
|
|
665
|
+
var Context = /* @__PURE__ */ ((Context2) => {
|
|
666
|
+
Context2["ETH"] = "Ethereum";
|
|
667
|
+
Context2["SOLANA"] = "Solana";
|
|
668
|
+
Context2["APTOS"] = "Aptos";
|
|
669
|
+
return Context2;
|
|
670
|
+
})(Context || {});
|
|
671
|
+
|
|
672
|
+
// src/config/testnet/chains.ts
|
|
673
|
+
var testnetChains = {
|
|
674
|
+
Sepolia: {
|
|
675
|
+
key: "Sepolia",
|
|
676
|
+
id: 10002,
|
|
677
|
+
context: "Ethereum" /* ETH */,
|
|
678
|
+
finalityThreshold: 0,
|
|
679
|
+
displayName: "Sepolia",
|
|
680
|
+
explorerUrl: "https://sepolia.etherscan.io/",
|
|
681
|
+
explorerName: "Etherscan",
|
|
682
|
+
gasToken: "ETHsepolia",
|
|
683
|
+
chainId: 11155111,
|
|
684
|
+
icon: "Ethereum",
|
|
685
|
+
maxBlockSearch: 2e3,
|
|
686
|
+
symbol: "ETH",
|
|
687
|
+
defaultRpc: "https://eth-sepolia.public.blastapi.io",
|
|
688
|
+
wrappedGasToken: "0xeef12A83EE5b7161D3873317c8E0E7B76e0B5D9c"
|
|
689
|
+
},
|
|
690
|
+
Solana: {
|
|
691
|
+
key: "Solana",
|
|
692
|
+
id: 1,
|
|
693
|
+
context: "Solana" /* SOLANA */,
|
|
694
|
+
finalityThreshold: 32,
|
|
695
|
+
displayName: "Solana",
|
|
696
|
+
explorerUrl: "https://explorer.solana.com/",
|
|
697
|
+
explorerName: "Solana Explorer",
|
|
698
|
+
gasToken: "SOL",
|
|
699
|
+
chainId: 0,
|
|
700
|
+
icon: "Solana",
|
|
701
|
+
maxBlockSearch: 2e3,
|
|
702
|
+
symbol: "SOL",
|
|
703
|
+
defaultRpc: "https://api.devnet.solana.com",
|
|
704
|
+
wrappedGasToken: "So11111111111111111111111111111111111111112"
|
|
705
|
+
}
|
|
706
|
+
};
|
|
707
|
+
var AptosTestnetChain = {
|
|
708
|
+
key: "Aptos",
|
|
709
|
+
id: 22,
|
|
710
|
+
context: "Aptos" /* APTOS */,
|
|
711
|
+
finalityThreshold: 0,
|
|
712
|
+
displayName: "Aptos",
|
|
713
|
+
explorerUrl: "https://explorer.aptoslabs.com?network=testnet",
|
|
714
|
+
explorerName: "Aptos Explorer",
|
|
715
|
+
gasToken: "APT",
|
|
716
|
+
chainId: 0,
|
|
717
|
+
icon: "Aptos",
|
|
718
|
+
maxBlockSearch: 0,
|
|
719
|
+
symbol: "APT",
|
|
720
|
+
sdkName: "Aptos"
|
|
721
|
+
};
|
|
722
|
+
|
|
723
|
+
// src/config/testnet/tokens.ts
|
|
724
|
+
var testnetTokens = {
|
|
725
|
+
Sepolia: {
|
|
726
|
+
symbol: "USDC",
|
|
727
|
+
icon: "USDC",
|
|
728
|
+
decimals: 6,
|
|
729
|
+
tokenId: {
|
|
730
|
+
chain: "Sepolia",
|
|
731
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"
|
|
732
|
+
}
|
|
733
|
+
},
|
|
734
|
+
Solana: {
|
|
735
|
+
symbol: "USDC",
|
|
736
|
+
tokenId: {
|
|
737
|
+
chain: "Solana",
|
|
738
|
+
address: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU"
|
|
739
|
+
},
|
|
740
|
+
icon: "USDC",
|
|
741
|
+
decimals: 6
|
|
742
|
+
}
|
|
743
|
+
};
|
|
744
|
+
var AptosTestnetUSDCToken = {
|
|
745
|
+
symbol: "USDC",
|
|
746
|
+
decimals: 6,
|
|
747
|
+
tokenId: {
|
|
748
|
+
chain: "Aptos",
|
|
749
|
+
address: "0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832"
|
|
750
|
+
},
|
|
751
|
+
icon: "USDC"
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
// src/config/mainnet/chains.ts
|
|
755
|
+
var mainnetChains = {
|
|
756
|
+
Ethereum: {
|
|
757
|
+
key: "Ethereum",
|
|
758
|
+
id: 2,
|
|
759
|
+
context: "Ethereum" /* ETH */,
|
|
760
|
+
finalityThreshold: 64,
|
|
761
|
+
displayName: "Ethereum",
|
|
762
|
+
explorerUrl: "https://etherscan.io/",
|
|
763
|
+
explorerName: "Etherscan",
|
|
764
|
+
gasToken: "ETH",
|
|
765
|
+
chainId: 1,
|
|
766
|
+
icon: "Ethereum",
|
|
767
|
+
maxBlockSearch: 2e3,
|
|
768
|
+
symbol: "ETH",
|
|
769
|
+
defaultRpc: "https://rpc.ankr.com/eth"
|
|
770
|
+
},
|
|
771
|
+
Solana: {
|
|
772
|
+
key: "Solana",
|
|
773
|
+
id: 1,
|
|
774
|
+
context: "Solana" /* SOLANA */,
|
|
775
|
+
finalityThreshold: 32,
|
|
776
|
+
displayName: "Solana",
|
|
777
|
+
explorerUrl: "https://explorer.solana.com/",
|
|
778
|
+
explorerName: "Solana Explorer",
|
|
779
|
+
gasToken: "SOL",
|
|
780
|
+
chainId: 0,
|
|
781
|
+
icon: "Solana",
|
|
782
|
+
maxBlockSearch: 2e3,
|
|
783
|
+
symbol: "SOL",
|
|
784
|
+
defaultRpc: "https://solana-mainnet.rpc.extrnode.com"
|
|
785
|
+
}
|
|
786
|
+
};
|
|
787
|
+
var AptosMainnetChain = {
|
|
788
|
+
key: "Aptos",
|
|
789
|
+
id: 22,
|
|
790
|
+
context: "Aptos",
|
|
791
|
+
finalityThreshold: 0,
|
|
792
|
+
displayName: "Aptos",
|
|
793
|
+
explorerUrl: "https://explorer.aptoslabs.com/",
|
|
794
|
+
explorerName: "Aptos Explorer",
|
|
795
|
+
gasToken: "APT",
|
|
796
|
+
chainId: 0,
|
|
797
|
+
icon: "Aptos",
|
|
798
|
+
maxBlockSearch: 0,
|
|
799
|
+
symbol: "APT"
|
|
800
|
+
};
|
|
801
|
+
|
|
802
|
+
// src/config/mainnet/tokens.ts
|
|
803
|
+
var mainnetTokens = {
|
|
804
|
+
Ethereum: {
|
|
805
|
+
symbol: "USDC",
|
|
806
|
+
tokenId: {
|
|
807
|
+
chain: "Ethereum",
|
|
808
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
809
|
+
},
|
|
810
|
+
icon: "USDC",
|
|
811
|
+
decimals: 6
|
|
812
|
+
},
|
|
813
|
+
Solana: {
|
|
814
|
+
symbol: "USDC",
|
|
815
|
+
tokenId: {
|
|
816
|
+
chain: "Solana",
|
|
817
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
818
|
+
},
|
|
819
|
+
icon: "USDC",
|
|
820
|
+
decimals: 6
|
|
821
|
+
}
|
|
822
|
+
};
|
|
823
|
+
var AptosMainnetUSDCToken = {
|
|
824
|
+
symbol: "USDC",
|
|
825
|
+
tokenId: {
|
|
826
|
+
chain: "Aptos",
|
|
827
|
+
address: "0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b"
|
|
828
|
+
},
|
|
829
|
+
icon: "USDC",
|
|
830
|
+
decimals: 6
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
// src/utils/getUsdcBalance.ts
|
|
834
|
+
import { Aptos as Aptos2, AptosConfig as AptosConfig2, Network as Network2 } from "@aptos-labs/ts-sdk";
|
|
835
|
+
import { Connection as Connection2, PublicKey } from "@solana/web3.js";
|
|
836
|
+
import { ethers as ethers2, JsonRpcProvider } from "ethers";
|
|
837
|
+
var getSolanaWalletUSDCBalance = async (walletAddress, aptosNetwork, rpc) => {
|
|
838
|
+
var _a;
|
|
839
|
+
const address = new PublicKey(walletAddress);
|
|
840
|
+
const tokenAddress = aptosNetwork === Network2.MAINNET ? mainnetTokens["Solana"].tokenId.address : testnetTokens["Solana"].tokenId.address;
|
|
841
|
+
const connection = new Connection2(rpc);
|
|
842
|
+
const splToken = await connection.getTokenAccountsByOwner(address, {
|
|
843
|
+
mint: new PublicKey(tokenAddress)
|
|
844
|
+
});
|
|
845
|
+
const checkAddress = splToken.value.length > 0 ? splToken.value[0].pubkey : address;
|
|
846
|
+
const balance = await connection.getTokenAccountBalance(checkAddress);
|
|
847
|
+
console.log("balance", balance);
|
|
848
|
+
return (_a = balance.value.uiAmountString) != null ? _a : (Number(balance.value.amount) / 10 ** balance.value.decimals).toString();
|
|
849
|
+
};
|
|
850
|
+
var getEthereumWalletUSDCBalance = async (walletAddress, aptosNetwork, rpc) => {
|
|
851
|
+
const token = aptosNetwork === Network2.MAINNET ? mainnetTokens["Ethereum"] : testnetTokens["Sepolia"];
|
|
852
|
+
const tokenAddress = token.tokenId.address;
|
|
853
|
+
const connection = new JsonRpcProvider(rpc);
|
|
854
|
+
const abi = ["function balanceOf(address owner) view returns (uint256)"];
|
|
855
|
+
const contract = new ethers2.Contract(tokenAddress, abi, connection);
|
|
856
|
+
const balance = await contract.balanceOf(walletAddress);
|
|
857
|
+
return ethers2.formatUnits(balance, token.decimals).toString();
|
|
858
|
+
};
|
|
859
|
+
var getAptosWalletUSDCBalance = async (walletAddress, aptosNetwork) => {
|
|
860
|
+
const token = aptosNetwork === Network2.MAINNET ? AptosMainnetUSDCToken : AptosTestnetUSDCToken;
|
|
861
|
+
const tokenAddress = token.tokenId.address;
|
|
862
|
+
const aptosConfig = new AptosConfig2({ network: aptosNetwork });
|
|
863
|
+
const connection = new Aptos2(aptosConfig);
|
|
864
|
+
const response = await connection.getCurrentFungibleAssetBalances({
|
|
865
|
+
options: {
|
|
866
|
+
where: {
|
|
867
|
+
owner_address: { _eq: walletAddress },
|
|
868
|
+
asset_type: { _eq: tokenAddress }
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
});
|
|
872
|
+
const balance = (Number(response[0].amount) / 10 ** token.decimals).toString();
|
|
873
|
+
return balance;
|
|
874
|
+
};
|
|
875
|
+
|
|
876
|
+
// src/CrossChainCore.ts
|
|
877
|
+
import { NetworkToChainId, NetworkToNodeAPI } from "@aptos-labs/ts-sdk";
|
|
878
|
+
var CrossChainCore = class {
|
|
879
|
+
constructor(args) {
|
|
880
|
+
this._dappConfig = {
|
|
881
|
+
aptosNetwork: Network3.TESTNET
|
|
882
|
+
};
|
|
883
|
+
this.CHAINS = testnetChains;
|
|
884
|
+
this.TOKENS = testnetTokens;
|
|
885
|
+
this.APTOS_TOKEN = AptosTestnetUSDCToken;
|
|
886
|
+
var _a;
|
|
887
|
+
this._dappConfig = args.dappConfig;
|
|
888
|
+
if (((_a = args.dappConfig) == null ? void 0 : _a.aptosNetwork) === Network3.MAINNET) {
|
|
889
|
+
this.CHAINS = mainnetChains;
|
|
890
|
+
this.TOKENS = mainnetTokens;
|
|
891
|
+
this.APTOS_TOKEN = AptosMainnetUSDCToken;
|
|
892
|
+
} else {
|
|
893
|
+
this.CHAINS = testnetChains;
|
|
894
|
+
this.TOKENS = testnetTokens;
|
|
895
|
+
this.APTOS_TOKEN = AptosTestnetUSDCToken;
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
getProvider(providerType) {
|
|
899
|
+
switch (providerType) {
|
|
900
|
+
case "Wormhole":
|
|
901
|
+
return new WormholeProvider(this);
|
|
902
|
+
default:
|
|
903
|
+
throw new Error(`Unknown provider: ${providerType}`);
|
|
904
|
+
}
|
|
905
|
+
}
|
|
906
|
+
async getWalletUSDCBalance(walletAddress, sourceChain) {
|
|
907
|
+
var _a, _b, _c;
|
|
908
|
+
if (sourceChain === "Aptos") {
|
|
909
|
+
return await getAptosWalletUSDCBalance(
|
|
910
|
+
walletAddress,
|
|
911
|
+
this._dappConfig.aptosNetwork
|
|
912
|
+
);
|
|
913
|
+
}
|
|
914
|
+
if (!this.CHAINS[sourceChain]) {
|
|
915
|
+
throw new Error(`Unsupported chain: ${sourceChain}`);
|
|
916
|
+
}
|
|
917
|
+
switch (sourceChain) {
|
|
918
|
+
case "Solana":
|
|
919
|
+
return await getSolanaWalletUSDCBalance(
|
|
920
|
+
walletAddress,
|
|
921
|
+
this._dappConfig.aptosNetwork,
|
|
922
|
+
(_c = (_b = (_a = this._dappConfig) == null ? void 0 : _a.solanaConfig) == null ? void 0 : _b.rpc) != null ? _c : this.CHAINS[sourceChain].defaultRpc
|
|
923
|
+
);
|
|
924
|
+
case "Ethereum":
|
|
925
|
+
case "Sepolia":
|
|
926
|
+
return await getEthereumWalletUSDCBalance(
|
|
927
|
+
walletAddress,
|
|
928
|
+
this._dappConfig.aptosNetwork,
|
|
929
|
+
this.CHAINS[sourceChain].defaultRpc
|
|
930
|
+
);
|
|
931
|
+
default:
|
|
932
|
+
throw new Error(`Unsupported chain: ${sourceChain}`);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
|
|
937
|
+
// src/index.ts
|
|
938
|
+
import { Network as Network4 } from "@aptos-labs/ts-sdk";
|
|
939
|
+
export {
|
|
940
|
+
AptosLocalSigner,
|
|
941
|
+
AptosMainnetChain,
|
|
942
|
+
AptosMainnetUSDCToken,
|
|
943
|
+
AptosTestnetChain,
|
|
944
|
+
AptosTestnetUSDCToken,
|
|
945
|
+
Context,
|
|
946
|
+
CrossChainCore,
|
|
947
|
+
Network4 as Network,
|
|
948
|
+
NetworkToChainId,
|
|
949
|
+
NetworkToNodeAPI,
|
|
950
|
+
WormholeProvider,
|
|
951
|
+
mainnetChains,
|
|
952
|
+
mainnetTokens,
|
|
953
|
+
signAndSendTransaction,
|
|
954
|
+
testnetChains,
|
|
955
|
+
testnetTokens
|
|
956
|
+
};
|
|
957
|
+
//# sourceMappingURL=index.mjs.map
|