@aptos-labs/cross-chain-core 4.24.13 → 5.0.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 +11 -0
- package/dist/CrossChainCore.d.ts +3 -3
- package/dist/CrossChainCore.d.ts.map +1 -1
- package/dist/config/mainnet/chains.d.ts +0 -14
- package/dist/config/mainnet/chains.d.ts.map +1 -1
- package/dist/config/mainnet/tokens.d.ts +0 -1
- package/dist/config/mainnet/tokens.d.ts.map +1 -1
- package/dist/config/testnet/chains.d.ts +0 -16
- package/dist/config/testnet/chains.d.ts.map +1 -1
- package/dist/config/testnet/tokens.d.ts +0 -1
- package/dist/config/testnet/tokens.d.ts.map +1 -1
- package/dist/index.js +272 -92
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +263 -73
- package/dist/index.mjs.map +1 -1
- package/dist/providers/wormhole/signers/AptosLocalSigner.d.ts.map +1 -1
- package/dist/providers/wormhole/signers/AptosSigner.d.ts +7 -0
- package/dist/providers/wormhole/signers/AptosSigner.d.ts.map +1 -0
- package/dist/providers/wormhole/signers/Signer.d.ts +7 -2
- package/dist/providers/wormhole/signers/Signer.d.ts.map +1 -1
- package/dist/providers/wormhole/types.d.ts +14 -3
- package/dist/providers/wormhole/types.d.ts.map +1 -1
- package/dist/providers/wormhole/wormhole.d.ts +7 -9
- package/dist/providers/wormhole/wormhole.d.ts.map +1 -1
- package/dist/utils/getUsdcBalance.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.d.ts.map +1 -1
- package/package.json +10 -10
- package/src/CrossChainCore.ts +18 -19
- package/src/config/mainnet/chains.ts +15 -15
- package/src/config/mainnet/tokens.ts +10 -11
- package/src/config/testnet/chains.ts +15 -16
- package/src/config/testnet/tokens.ts +10 -11
- package/src/providers/wormhole/signers/AptosLocalSigner.ts +4 -3
- package/src/providers/wormhole/signers/AptosSigner.ts +139 -0
- package/src/providers/wormhole/signers/Signer.ts +26 -2
- package/src/providers/wormhole/types.ts +16 -3
- package/src/providers/wormhole/wormhole.ts +165 -29
- package/src/utils/getUsdcBalance.ts +9 -11
- package/src/version.ts +1 -1
|
@@ -24,13 +24,15 @@ import { ChainConfig } from "../../config";
|
|
|
24
24
|
import {
|
|
25
25
|
WormholeQuoteRequest,
|
|
26
26
|
WormholeQuoteResponse,
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
WormholeTransferRequest,
|
|
28
|
+
WormholeTransferResponse,
|
|
29
29
|
WormholeRouteResponse,
|
|
30
30
|
WormholeRequest,
|
|
31
31
|
WormholeSubmitTransferRequest,
|
|
32
32
|
WormholeStartTransferResponse,
|
|
33
33
|
WormholeClaimTransferRequest,
|
|
34
|
+
WormholeWithdrawRequest,
|
|
35
|
+
WormholeWithdrawResponse,
|
|
34
36
|
} from "./types";
|
|
35
37
|
import { SolanaDerivedWallet } from "@aptos-labs/derived-wallet-solana";
|
|
36
38
|
import { EIP1193DerivedWallet } from "@aptos-labs/derived-wallet-ethereum";
|
|
@@ -40,8 +42,10 @@ export class WormholeProvider
|
|
|
40
42
|
CrossChainProvider<
|
|
41
43
|
WormholeQuoteRequest,
|
|
42
44
|
WormholeQuoteResponse,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
WormholeTransferRequest,
|
|
46
|
+
WormholeTransferResponse,
|
|
47
|
+
WormholeWithdrawRequest,
|
|
48
|
+
WormholeWithdrawResponse
|
|
45
49
|
>
|
|
46
50
|
{
|
|
47
51
|
private crossChainCore: CrossChainCore;
|
|
@@ -60,7 +64,7 @@ export class WormholeProvider
|
|
|
60
64
|
return this._wormholeContext;
|
|
61
65
|
}
|
|
62
66
|
|
|
63
|
-
async setWormholeContext(sourceChain: Chain) {
|
|
67
|
+
private async setWormholeContext(sourceChain: Chain) {
|
|
64
68
|
const dappNetwork = this.crossChainCore._dappConfig?.aptosNetwork;
|
|
65
69
|
if (dappNetwork === Network.DEVNET) {
|
|
66
70
|
throw new Error("Devnet is not supported on Wormhole");
|
|
@@ -74,7 +78,10 @@ export class WormholeProvider
|
|
|
74
78
|
this._wormholeContext = wh;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
|
-
async getRoute(
|
|
81
|
+
private async getRoute(
|
|
82
|
+
sourceChain: Chain,
|
|
83
|
+
destinationChain: Chain
|
|
84
|
+
): Promise<{
|
|
78
85
|
route: WormholeRouteResponse;
|
|
79
86
|
request: WormholeRequest;
|
|
80
87
|
}> {
|
|
@@ -82,19 +89,23 @@ export class WormholeProvider
|
|
|
82
89
|
throw new Error("Wormhole context not initialized");
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
const { sourceToken, destToken } = this.getTokenInfo(
|
|
92
|
+
const { sourceToken, destToken } = this.getTokenInfo(
|
|
93
|
+
sourceChain,
|
|
94
|
+
destinationChain
|
|
95
|
+
);
|
|
86
96
|
|
|
97
|
+
const destContext = this._wormholeContext
|
|
98
|
+
.getPlatform(chainToPlatform(destinationChain))
|
|
99
|
+
.getChain(destinationChain);
|
|
87
100
|
const sourceContext = this._wormholeContext
|
|
88
101
|
.getPlatform(chainToPlatform(sourceChain))
|
|
89
102
|
.getChain(sourceChain);
|
|
90
103
|
|
|
91
104
|
logger.log("sourceContext", sourceContext);
|
|
92
|
-
|
|
93
|
-
const destContext = this._wormholeContext
|
|
94
|
-
.getPlatform(chainToPlatform("Aptos"))
|
|
95
|
-
.getChain("Aptos");
|
|
105
|
+
logger.log("sourceToken", sourceToken);
|
|
96
106
|
|
|
97
107
|
logger.log("destContext", destContext);
|
|
108
|
+
logger.log("destToken", destToken);
|
|
98
109
|
|
|
99
110
|
const request = await routes.RouteTransferRequest.create(
|
|
100
111
|
this._wormholeContext,
|
|
@@ -103,7 +114,7 @@ export class WormholeProvider
|
|
|
103
114
|
destination: destToken,
|
|
104
115
|
},
|
|
105
116
|
sourceContext,
|
|
106
|
-
destContext
|
|
117
|
+
destContext
|
|
107
118
|
);
|
|
108
119
|
|
|
109
120
|
const resolver = this._wormholeContext.resolver([
|
|
@@ -120,13 +131,22 @@ export class WormholeProvider
|
|
|
120
131
|
}
|
|
121
132
|
|
|
122
133
|
async getQuote(input: WormholeQuoteRequest): Promise<WormholeQuoteResponse> {
|
|
123
|
-
const { amount,
|
|
134
|
+
const { amount, originChain, type } = input;
|
|
124
135
|
|
|
125
136
|
if (!this._wormholeContext) {
|
|
126
|
-
await this.setWormholeContext(
|
|
137
|
+
await this.setWormholeContext(originChain);
|
|
127
138
|
}
|
|
128
139
|
|
|
129
|
-
|
|
140
|
+
logger.log("type", type);
|
|
141
|
+
// If the type of the transaction is "transfer", we want to transfer from a x-chain wallet to the Aptos wallet
|
|
142
|
+
// If the type of the transaction is "withdraw", we want to transfer from the Aptos wallet to a x-chain wallet
|
|
143
|
+
const sourceChain = type === "transfer" ? originChain : "Aptos";
|
|
144
|
+
const destinationChain = type === "transfer" ? "Aptos" : originChain;
|
|
145
|
+
|
|
146
|
+
const { route, request } = await this.getRoute(
|
|
147
|
+
sourceChain,
|
|
148
|
+
destinationChain
|
|
149
|
+
);
|
|
130
150
|
|
|
131
151
|
// TODO what is nativeGas for?
|
|
132
152
|
const transferParams = {
|
|
@@ -150,7 +170,7 @@ export class WormholeProvider
|
|
|
150
170
|
}
|
|
151
171
|
|
|
152
172
|
async submitCCTPTransfer(
|
|
153
|
-
input: WormholeSubmitTransferRequest
|
|
173
|
+
input: WormholeSubmitTransferRequest
|
|
154
174
|
): Promise<WormholeStartTransferResponse> {
|
|
155
175
|
const { sourceChain, wallet, destinationAddress } = input;
|
|
156
176
|
|
|
@@ -184,14 +204,14 @@ export class WormholeProvider
|
|
|
184
204
|
this.getChainConfig(sourceChain),
|
|
185
205
|
signerAddress,
|
|
186
206
|
{},
|
|
187
|
-
wallet
|
|
207
|
+
wallet
|
|
188
208
|
);
|
|
189
209
|
|
|
190
210
|
let receipt = await this.wormholeRoute.initiate(
|
|
191
211
|
this.wormholeRequest,
|
|
192
212
|
signer,
|
|
193
213
|
this.wormholeQuote,
|
|
194
|
-
Wormhole.chainAddress("Aptos", destinationAddress.toString())
|
|
214
|
+
Wormhole.chainAddress("Aptos", destinationAddress.toString())
|
|
195
215
|
);
|
|
196
216
|
|
|
197
217
|
const originChainTxnId =
|
|
@@ -203,7 +223,7 @@ export class WormholeProvider
|
|
|
203
223
|
}
|
|
204
224
|
|
|
205
225
|
async claimCCTPTransfer(
|
|
206
|
-
input: WormholeClaimTransferRequest
|
|
226
|
+
input: WormholeClaimTransferRequest
|
|
207
227
|
): Promise<{ destinationChainTxnId: string }> {
|
|
208
228
|
let { receipt, mainSigner, sponsorAccount } = input;
|
|
209
229
|
if (!this.wormholeRoute) {
|
|
@@ -227,7 +247,7 @@ export class WormholeProvider
|
|
|
227
247
|
"Aptos",
|
|
228
248
|
{},
|
|
229
249
|
mainSigner, // the account that signs the "claim" transaction
|
|
230
|
-
sponsorAccount ? sponsorAccount : undefined
|
|
250
|
+
sponsorAccount ? sponsorAccount : undefined // the fee payer account
|
|
231
251
|
);
|
|
232
252
|
|
|
233
253
|
if (routes.isManual(this.wormholeRoute)) {
|
|
@@ -249,7 +269,7 @@ export class WormholeProvider
|
|
|
249
269
|
} catch (e) {
|
|
250
270
|
console.error(
|
|
251
271
|
`Error tracking transfer (attempt ${retries + 1} / ${maxRetries}):`,
|
|
252
|
-
e
|
|
272
|
+
e
|
|
253
273
|
);
|
|
254
274
|
const delay = baseDelay * Math.pow(2, retries); // Exponential backoff
|
|
255
275
|
await sleep(delay);
|
|
@@ -265,9 +285,9 @@ export class WormholeProvider
|
|
|
265
285
|
* @param args
|
|
266
286
|
* @returns
|
|
267
287
|
*/
|
|
268
|
-
async
|
|
269
|
-
input:
|
|
270
|
-
): Promise<
|
|
288
|
+
async transfer(
|
|
289
|
+
input: WormholeTransferRequest
|
|
290
|
+
): Promise<WormholeTransferResponse> {
|
|
271
291
|
if (this.crossChainCore._dappConfig?.aptosNetwork === Network.DEVNET) {
|
|
272
292
|
throw new Error("Devnet is not supported on Wormhole");
|
|
273
293
|
}
|
|
@@ -276,7 +296,8 @@ export class WormholeProvider
|
|
|
276
296
|
if (input.amount) {
|
|
277
297
|
await this.getQuote({
|
|
278
298
|
amount: input.amount,
|
|
279
|
-
|
|
299
|
+
originChain: input.sourceChain,
|
|
300
|
+
type: "transfer",
|
|
280
301
|
});
|
|
281
302
|
}
|
|
282
303
|
// Submit transfer transaction from origin chain
|
|
@@ -290,6 +311,118 @@ export class WormholeProvider
|
|
|
290
311
|
return { originChainTxnId, destinationChainTxnId };
|
|
291
312
|
}
|
|
292
313
|
|
|
314
|
+
async withdraw(
|
|
315
|
+
input: WormholeWithdrawRequest
|
|
316
|
+
): Promise<WormholeWithdrawResponse> {
|
|
317
|
+
const { sourceChain, wallet, destinationAddress, sponsorAccount } = input;
|
|
318
|
+
logger.log("sourceChain", sourceChain);
|
|
319
|
+
logger.log("wallet", wallet);
|
|
320
|
+
logger.log("destinationAddress", destinationAddress);
|
|
321
|
+
logger.log("sponsorAccount", sponsorAccount);
|
|
322
|
+
|
|
323
|
+
if (!this._wormholeContext) {
|
|
324
|
+
await this.setWormholeContext(sourceChain);
|
|
325
|
+
}
|
|
326
|
+
if (!this._wormholeContext) {
|
|
327
|
+
throw new Error("Wormhole context not initialized");
|
|
328
|
+
}
|
|
329
|
+
if (!this.wormholeRoute || !this.wormholeRequest || !this.wormholeQuote) {
|
|
330
|
+
throw new Error("Wormhole route, request, or quote not initialized");
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const signer = new Signer(
|
|
334
|
+
this.getChainConfig("Aptos"),
|
|
335
|
+
(
|
|
336
|
+
await input.wallet.features["aptos:account"].account()
|
|
337
|
+
).address.toString(),
|
|
338
|
+
{},
|
|
339
|
+
input.wallet,
|
|
340
|
+
undefined,
|
|
341
|
+
sponsorAccount
|
|
342
|
+
);
|
|
343
|
+
|
|
344
|
+
logger.log("signer", signer);
|
|
345
|
+
logger.log("wormholeRequest", this.wormholeRequest);
|
|
346
|
+
logger.log("wormholeQuote", this.wormholeQuote);
|
|
347
|
+
logger.log(
|
|
348
|
+
"Wormhole.chainAddress",
|
|
349
|
+
Wormhole.chainAddress(sourceChain, input.destinationAddress.toString())
|
|
350
|
+
);
|
|
351
|
+
|
|
352
|
+
let receipt = await this.wormholeRoute.initiate(
|
|
353
|
+
this.wormholeRequest,
|
|
354
|
+
signer,
|
|
355
|
+
this.wormholeQuote,
|
|
356
|
+
Wormhole.chainAddress(sourceChain, input.destinationAddress.toString())
|
|
357
|
+
);
|
|
358
|
+
logger.log("receipt", receipt);
|
|
359
|
+
|
|
360
|
+
const originChainTxnId =
|
|
361
|
+
"originTxs" in receipt
|
|
362
|
+
? receipt.originTxs[receipt.originTxs.length - 1].txid
|
|
363
|
+
: undefined;
|
|
364
|
+
|
|
365
|
+
let retries = 0;
|
|
366
|
+
const maxRetries = 5;
|
|
367
|
+
const baseDelay = 1000; // Initial delay of 1 second
|
|
368
|
+
|
|
369
|
+
while (retries < maxRetries) {
|
|
370
|
+
try {
|
|
371
|
+
for await (receipt of this.wormholeRoute.track(receipt, 120 * 1000)) {
|
|
372
|
+
if (receipt.state >= TransferState.SourceInitiated) {
|
|
373
|
+
logger.log("Receipt is on track ", receipt);
|
|
374
|
+
|
|
375
|
+
try {
|
|
376
|
+
const signer = new Signer(
|
|
377
|
+
this.getChainConfig(sourceChain),
|
|
378
|
+
destinationAddress.toString(),
|
|
379
|
+
{},
|
|
380
|
+
wallet
|
|
381
|
+
);
|
|
382
|
+
|
|
383
|
+
if (routes.isManual(this.wormholeRoute)) {
|
|
384
|
+
const circleAttestationReceipt =
|
|
385
|
+
await this.wormholeRoute.complete(signer, receipt);
|
|
386
|
+
logger.log("Claim receipt: ", circleAttestationReceipt);
|
|
387
|
+
|
|
388
|
+
const destinationChainTxnId = signer.claimedTransactionHashes();
|
|
389
|
+
return {
|
|
390
|
+
originChainTxnId: originChainTxnId || "",
|
|
391
|
+
destinationChainTxnId,
|
|
392
|
+
};
|
|
393
|
+
} else {
|
|
394
|
+
// Should be unreachable
|
|
395
|
+
return {
|
|
396
|
+
originChainTxnId: originChainTxnId || "",
|
|
397
|
+
destinationChainTxnId: "",
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
} catch (e) {
|
|
401
|
+
console.error("Failed to claim", e);
|
|
402
|
+
return {
|
|
403
|
+
originChainTxnId: originChainTxnId || "",
|
|
404
|
+
destinationChainTxnId: "",
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
} catch (e) {
|
|
410
|
+
console.error(
|
|
411
|
+
`Error tracking transfer (attempt ${retries + 1} / ${maxRetries}):`,
|
|
412
|
+
e
|
|
413
|
+
);
|
|
414
|
+
const delay = baseDelay * Math.pow(2, retries); // Exponential backoff
|
|
415
|
+
await sleep(delay);
|
|
416
|
+
retries++;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
return {
|
|
421
|
+
originChainTxnId: originChainTxnId || "",
|
|
422
|
+
destinationChainTxnId: "",
|
|
423
|
+
};
|
|
424
|
+
}
|
|
425
|
+
|
|
293
426
|
getChainConfig(chain: Chain): ChainConfig {
|
|
294
427
|
const chainConfig =
|
|
295
428
|
this.crossChainCore.CHAINS[
|
|
@@ -301,18 +434,21 @@ export class WormholeProvider
|
|
|
301
434
|
return chainConfig;
|
|
302
435
|
}
|
|
303
436
|
|
|
304
|
-
getTokenInfo(
|
|
437
|
+
getTokenInfo(
|
|
438
|
+
sourceChain: Chain,
|
|
439
|
+
destinationChain: Chain
|
|
440
|
+
): {
|
|
305
441
|
sourceToken: TokenId;
|
|
306
442
|
destToken: TokenId;
|
|
307
443
|
} {
|
|
308
444
|
const sourceToken: TokenId = Wormhole.tokenId(
|
|
309
445
|
this.crossChainCore.TOKENS[sourceChain].tokenId.chain as Chain,
|
|
310
|
-
this.crossChainCore.TOKENS[sourceChain].tokenId.address
|
|
446
|
+
this.crossChainCore.TOKENS[sourceChain].tokenId.address
|
|
311
447
|
);
|
|
312
448
|
|
|
313
449
|
const destToken: TokenId = Wormhole.tokenId(
|
|
314
|
-
this.crossChainCore.
|
|
315
|
-
this.crossChainCore.
|
|
450
|
+
this.crossChainCore.TOKENS[destinationChain].tokenId.chain as Chain,
|
|
451
|
+
this.crossChainCore.TOKENS[destinationChain].tokenId.address
|
|
316
452
|
);
|
|
317
453
|
|
|
318
454
|
return { sourceToken, destToken };
|
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { Aptos, AptosConfig, Network } from "@aptos-labs/ts-sdk";
|
|
2
2
|
import { Connection, PublicKey } from "@solana/web3.js";
|
|
3
|
-
import {
|
|
4
|
-
AptosMainnetUSDCToken,
|
|
5
|
-
AptosTestnetUSDCToken,
|
|
6
|
-
mainnetTokens,
|
|
7
|
-
testnetTokens,
|
|
8
|
-
} from "../config";
|
|
3
|
+
import { mainnetTokens, testnetTokens } from "../config";
|
|
9
4
|
import { ethers, JsonRpcProvider } from "ethers";
|
|
10
5
|
|
|
11
6
|
export const getSolanaWalletUSDCBalance = async (
|
|
12
7
|
walletAddress: string,
|
|
13
8
|
aptosNetwork: Network,
|
|
14
|
-
rpc: string
|
|
9
|
+
rpc: string
|
|
15
10
|
): Promise<string> => {
|
|
16
11
|
const address = new PublicKey(walletAddress);
|
|
17
12
|
const tokenAddress =
|
|
@@ -40,7 +35,7 @@ export const getSolanaWalletUSDCBalance = async (
|
|
|
40
35
|
export const getEthereumWalletUSDCBalance = async (
|
|
41
36
|
walletAddress: string,
|
|
42
37
|
aptosNetwork: Network,
|
|
43
|
-
rpc: string
|
|
38
|
+
rpc: string
|
|
44
39
|
): Promise<string> => {
|
|
45
40
|
const token =
|
|
46
41
|
aptosNetwork === Network.MAINNET
|
|
@@ -57,12 +52,12 @@ export const getEthereumWalletUSDCBalance = async (
|
|
|
57
52
|
|
|
58
53
|
export const getAptosWalletUSDCBalance = async (
|
|
59
54
|
walletAddress: string,
|
|
60
|
-
aptosNetwork: Network
|
|
55
|
+
aptosNetwork: Network
|
|
61
56
|
): Promise<string> => {
|
|
62
57
|
const token =
|
|
63
58
|
aptosNetwork === Network.MAINNET
|
|
64
|
-
?
|
|
65
|
-
:
|
|
59
|
+
? mainnetTokens["Aptos"]
|
|
60
|
+
: testnetTokens["Aptos"];
|
|
66
61
|
const tokenAddress = token.tokenId.address;
|
|
67
62
|
const aptosConfig = new AptosConfig({ network: aptosNetwork });
|
|
68
63
|
const connection = new Aptos(aptosConfig);
|
|
@@ -74,6 +69,9 @@ export const getAptosWalletUSDCBalance = async (
|
|
|
74
69
|
},
|
|
75
70
|
},
|
|
76
71
|
});
|
|
72
|
+
if (response.length === 0) {
|
|
73
|
+
return "0";
|
|
74
|
+
}
|
|
77
75
|
const balance = (
|
|
78
76
|
Number(response[0].amount) /
|
|
79
77
|
10 ** token.decimals
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const CROSS_CHAIN_CORE_VERSION = "
|
|
1
|
+
export const CROSS_CHAIN_CORE_VERSION = "5.0.0";
|