@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
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Context, ChainsConfig } from "../types";
|
|
2
|
+
|
|
3
|
+
export const mainnetChains: ChainsConfig = {
|
|
4
|
+
Ethereum: {
|
|
5
|
+
key: "Ethereum",
|
|
6
|
+
id: 2,
|
|
7
|
+
context: Context.ETH,
|
|
8
|
+
finalityThreshold: 64,
|
|
9
|
+
displayName: "Ethereum",
|
|
10
|
+
explorerUrl: "https://etherscan.io/",
|
|
11
|
+
explorerName: "Etherscan",
|
|
12
|
+
gasToken: "ETH",
|
|
13
|
+
chainId: 1,
|
|
14
|
+
icon: "Ethereum",
|
|
15
|
+
maxBlockSearch: 2000,
|
|
16
|
+
symbol: "ETH",
|
|
17
|
+
defaultRpc: "https://rpc.ankr.com/eth",
|
|
18
|
+
},
|
|
19
|
+
Solana: {
|
|
20
|
+
key: "Solana",
|
|
21
|
+
id: 1,
|
|
22
|
+
context: Context.SOLANA,
|
|
23
|
+
finalityThreshold: 32,
|
|
24
|
+
displayName: "Solana",
|
|
25
|
+
explorerUrl: "https://explorer.solana.com/",
|
|
26
|
+
explorerName: "Solana Explorer",
|
|
27
|
+
gasToken: "SOL",
|
|
28
|
+
chainId: 0,
|
|
29
|
+
icon: "Solana",
|
|
30
|
+
maxBlockSearch: 2000,
|
|
31
|
+
symbol: "SOL",
|
|
32
|
+
defaultRpc: "https://solana-mainnet.rpc.extrnode.com",
|
|
33
|
+
},
|
|
34
|
+
// Sui: {
|
|
35
|
+
// key: "Sui",
|
|
36
|
+
// id: 21,
|
|
37
|
+
// context: Context.SUI,
|
|
38
|
+
// finalityThreshold: 0,
|
|
39
|
+
// displayName: "Sui",
|
|
40
|
+
// sdkName: "Sui",
|
|
41
|
+
// explorerUrl: "https://suiscan.xyz/",
|
|
42
|
+
// explorerName: "Suiscan",
|
|
43
|
+
// gasToken: "SUI",
|
|
44
|
+
// chainId: 0,
|
|
45
|
+
// icon: "Sui",
|
|
46
|
+
// maxBlockSearch: 0,
|
|
47
|
+
// symbol: "SUI",
|
|
48
|
+
// },
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
export const AptosMainnetChain = {
|
|
52
|
+
key: "Aptos",
|
|
53
|
+
id: 22,
|
|
54
|
+
context: "Aptos",
|
|
55
|
+
finalityThreshold: 0,
|
|
56
|
+
displayName: "Aptos",
|
|
57
|
+
explorerUrl: "https://explorer.aptoslabs.com/",
|
|
58
|
+
explorerName: "Aptos Explorer",
|
|
59
|
+
gasToken: "APT",
|
|
60
|
+
chainId: 0,
|
|
61
|
+
icon: "Aptos",
|
|
62
|
+
maxBlockSearch: 0,
|
|
63
|
+
symbol: "APT",
|
|
64
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TokenConfig } from "../types";
|
|
2
|
+
|
|
3
|
+
export const mainnetTokens: Record<string, TokenConfig> = {
|
|
4
|
+
Ethereum: {
|
|
5
|
+
symbol: "USDC",
|
|
6
|
+
tokenId: {
|
|
7
|
+
chain: "Ethereum",
|
|
8
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
|
|
9
|
+
},
|
|
10
|
+
icon: "USDC",
|
|
11
|
+
decimals: 6,
|
|
12
|
+
},
|
|
13
|
+
Solana: {
|
|
14
|
+
symbol: "USDC",
|
|
15
|
+
tokenId: {
|
|
16
|
+
chain: "Solana",
|
|
17
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
|
|
18
|
+
},
|
|
19
|
+
icon: "USDC",
|
|
20
|
+
decimals: 6,
|
|
21
|
+
},
|
|
22
|
+
// Sui: {
|
|
23
|
+
// symbol: "USDC",
|
|
24
|
+
// decimals: 6,
|
|
25
|
+
// tokenId: {
|
|
26
|
+
// chain: "Sui",
|
|
27
|
+
// address:
|
|
28
|
+
// "0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC",
|
|
29
|
+
// },
|
|
30
|
+
// icon: "USDC",
|
|
31
|
+
// },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const AptosMainnetUSDCToken: TokenConfig = {
|
|
35
|
+
symbol: "USDC",
|
|
36
|
+
tokenId: {
|
|
37
|
+
chain: "Aptos",
|
|
38
|
+
address:
|
|
39
|
+
"0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b",
|
|
40
|
+
},
|
|
41
|
+
icon: "USDC",
|
|
42
|
+
decimals: 6,
|
|
43
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { Context } from "../types";
|
|
2
|
+
|
|
3
|
+
import { ChainsConfig } from "../types";
|
|
4
|
+
|
|
5
|
+
export const testnetChains: ChainsConfig = {
|
|
6
|
+
Sepolia: {
|
|
7
|
+
key: "Sepolia",
|
|
8
|
+
id: 10002,
|
|
9
|
+
context: Context.ETH,
|
|
10
|
+
finalityThreshold: 0,
|
|
11
|
+
displayName: "Sepolia",
|
|
12
|
+
explorerUrl: "https://sepolia.etherscan.io/",
|
|
13
|
+
explorerName: "Etherscan",
|
|
14
|
+
gasToken: "ETHsepolia",
|
|
15
|
+
chainId: 11155111,
|
|
16
|
+
icon: "Ethereum",
|
|
17
|
+
maxBlockSearch: 2000,
|
|
18
|
+
symbol: "ETH",
|
|
19
|
+
defaultRpc: "https://eth-sepolia.public.blastapi.io",
|
|
20
|
+
wrappedGasToken: "0xeef12A83EE5b7161D3873317c8E0E7B76e0B5D9c",
|
|
21
|
+
},
|
|
22
|
+
Solana: {
|
|
23
|
+
key: "Solana",
|
|
24
|
+
id: 1,
|
|
25
|
+
context: Context.SOLANA,
|
|
26
|
+
finalityThreshold: 32,
|
|
27
|
+
displayName: "Solana",
|
|
28
|
+
explorerUrl: "https://explorer.solana.com/",
|
|
29
|
+
explorerName: "Solana Explorer",
|
|
30
|
+
gasToken: "SOL",
|
|
31
|
+
chainId: 0,
|
|
32
|
+
icon: "Solana",
|
|
33
|
+
maxBlockSearch: 2000,
|
|
34
|
+
symbol: "SOL",
|
|
35
|
+
defaultRpc: "https://api.devnet.solana.com",
|
|
36
|
+
wrappedGasToken: "So11111111111111111111111111111111111111112",
|
|
37
|
+
},
|
|
38
|
+
// Sui: {
|
|
39
|
+
// key: "Sui",
|
|
40
|
+
// id: 21,
|
|
41
|
+
// context: Context.SUI,
|
|
42
|
+
// finalityThreshold: 0,
|
|
43
|
+
// displayName: "Sui",
|
|
44
|
+
// explorerUrl: "https://suiscan.xyz/testnet/",
|
|
45
|
+
// explorerName: "Suiscan",
|
|
46
|
+
// gasToken: "SUI",
|
|
47
|
+
// chainId: 0,
|
|
48
|
+
// icon: "Sui",
|
|
49
|
+
// maxBlockSearch: 0,
|
|
50
|
+
// symbol: "SUI",
|
|
51
|
+
// sdkName: "Sui",
|
|
52
|
+
// },
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export const AptosTestnetChain = {
|
|
56
|
+
key: "Aptos",
|
|
57
|
+
id: 22,
|
|
58
|
+
context: Context.APTOS,
|
|
59
|
+
finalityThreshold: 0,
|
|
60
|
+
displayName: "Aptos",
|
|
61
|
+
explorerUrl: "https://explorer.aptoslabs.com?network=testnet",
|
|
62
|
+
explorerName: "Aptos Explorer",
|
|
63
|
+
gasToken: "APT",
|
|
64
|
+
chainId: 0,
|
|
65
|
+
icon: "Aptos",
|
|
66
|
+
maxBlockSearch: 0,
|
|
67
|
+
symbol: "APT",
|
|
68
|
+
sdkName: "Aptos",
|
|
69
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { TokenConfig } from "../types";
|
|
2
|
+
|
|
3
|
+
export const testnetTokens: Record<string, TokenConfig> = {
|
|
4
|
+
Sepolia: {
|
|
5
|
+
symbol: "USDC",
|
|
6
|
+
icon: "USDC",
|
|
7
|
+
decimals: 6,
|
|
8
|
+
tokenId: {
|
|
9
|
+
chain: "Sepolia",
|
|
10
|
+
address: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
Solana: {
|
|
14
|
+
symbol: "USDC",
|
|
15
|
+
tokenId: {
|
|
16
|
+
chain: "Solana",
|
|
17
|
+
address: "4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU",
|
|
18
|
+
},
|
|
19
|
+
icon: "USDC",
|
|
20
|
+
decimals: 6,
|
|
21
|
+
},
|
|
22
|
+
// Sui: {
|
|
23
|
+
// symbol: "USDC",
|
|
24
|
+
// tokenId: {
|
|
25
|
+
// chain: "Sui",
|
|
26
|
+
// address:
|
|
27
|
+
// "0xa1ec7fc00a6f40db9693ad1415d0c193ad3906494428cf252621037bd7117e29::usdc::USDC",
|
|
28
|
+
// },
|
|
29
|
+
// icon: "USDC",
|
|
30
|
+
// decimals: 6,
|
|
31
|
+
// },
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const AptosTestnetUSDCToken: TokenConfig = {
|
|
35
|
+
symbol: "USDC",
|
|
36
|
+
decimals: 6,
|
|
37
|
+
tokenId: {
|
|
38
|
+
chain: "Aptos",
|
|
39
|
+
address:
|
|
40
|
+
"0x69091fbab5f7d635ee7ac5098cf0c1efbe31d68fec0f2cd565e8d168daf52832",
|
|
41
|
+
},
|
|
42
|
+
icon: "USDC",
|
|
43
|
+
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { ChainId } from "@wormhole-foundation/sdk";
|
|
2
|
+
import { Chain } from "../CrossChainCore";
|
|
3
|
+
|
|
4
|
+
export enum Context {
|
|
5
|
+
ETH = "Ethereum",
|
|
6
|
+
SOLANA = "Solana",
|
|
7
|
+
APTOS = "Aptos",
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export type BaseChainConfig = {
|
|
11
|
+
key: Chain;
|
|
12
|
+
id: ChainId;
|
|
13
|
+
context: Context;
|
|
14
|
+
finalityThreshold: number;
|
|
15
|
+
disabledAsSource?: boolean;
|
|
16
|
+
disabledAsDestination?: boolean;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export interface ChainConfig extends BaseChainConfig {
|
|
20
|
+
defaultRpc: string;
|
|
21
|
+
displayName: string;
|
|
22
|
+
explorerUrl: string;
|
|
23
|
+
explorerName: string;
|
|
24
|
+
gasToken: string;
|
|
25
|
+
wrappedGasToken?: string;
|
|
26
|
+
chainId: number | string;
|
|
27
|
+
icon: Chain;
|
|
28
|
+
maxBlockSearch: number;
|
|
29
|
+
symbol?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export type ChainsConfig = {
|
|
33
|
+
[chain in Chain]?: ChainConfig;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type TokenConfig = {
|
|
37
|
+
symbol: string;
|
|
38
|
+
name?: string;
|
|
39
|
+
decimals: number;
|
|
40
|
+
icon: string;
|
|
41
|
+
tokenId: {
|
|
42
|
+
chain: Chain;
|
|
43
|
+
address: string;
|
|
44
|
+
};
|
|
45
|
+
};
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccountAuthenticator,
|
|
3
|
+
AnyRawTransaction,
|
|
4
|
+
Aptos,
|
|
5
|
+
AptosConfig,
|
|
6
|
+
Network as AptosNetwork,
|
|
7
|
+
Account,
|
|
8
|
+
} from "@aptos-labs/ts-sdk";
|
|
9
|
+
|
|
10
|
+
import {
|
|
11
|
+
Chain,
|
|
12
|
+
Network,
|
|
13
|
+
SignAndSendSigner,
|
|
14
|
+
TxHash,
|
|
15
|
+
UnsignedTransaction,
|
|
16
|
+
} from "@wormhole-foundation/sdk";
|
|
17
|
+
import {
|
|
18
|
+
AptosUnsignedTransaction,
|
|
19
|
+
AptosChains,
|
|
20
|
+
} from "@wormhole-foundation/sdk-aptos";
|
|
21
|
+
import { GasStationApiKey } from "../types";
|
|
22
|
+
|
|
23
|
+
export class AptosLocalSigner<N extends Network, C extends Chain>
|
|
24
|
+
implements SignAndSendSigner<N, C>
|
|
25
|
+
{
|
|
26
|
+
_chain: C;
|
|
27
|
+
_options: any;
|
|
28
|
+
_wallet: Account;
|
|
29
|
+
_sponsorAccount: Account | GasStationApiKey | undefined;
|
|
30
|
+
_claimedTransactionHashes: string;
|
|
31
|
+
|
|
32
|
+
constructor(
|
|
33
|
+
chain: C,
|
|
34
|
+
options: any,
|
|
35
|
+
wallet: Account,
|
|
36
|
+
feePayerAccount: Account | GasStationApiKey | undefined
|
|
37
|
+
) {
|
|
38
|
+
this._chain = chain;
|
|
39
|
+
this._options = options;
|
|
40
|
+
this._wallet = wallet;
|
|
41
|
+
this._sponsorAccount = feePayerAccount;
|
|
42
|
+
this._claimedTransactionHashes = "";
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
chain(): C {
|
|
46
|
+
return this._chain;
|
|
47
|
+
}
|
|
48
|
+
address(): string {
|
|
49
|
+
return this._wallet.accountAddress.toString();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
claimedTransactionHashes(): string {
|
|
53
|
+
return this._claimedTransactionHashes;
|
|
54
|
+
}
|
|
55
|
+
/* other methods... */
|
|
56
|
+
|
|
57
|
+
async signAndSend(txs: UnsignedTransaction<N, C>[]): Promise<TxHash[]> {
|
|
58
|
+
const txHashes: TxHash[] = [];
|
|
59
|
+
|
|
60
|
+
for (const tx of txs) {
|
|
61
|
+
const txId = await signAndSendTransaction(
|
|
62
|
+
tx as AptosUnsignedTransaction<Network, AptosChains>,
|
|
63
|
+
this._wallet,
|
|
64
|
+
this._sponsorAccount
|
|
65
|
+
);
|
|
66
|
+
txHashes.push(txId);
|
|
67
|
+
this._claimedTransactionHashes = txId;
|
|
68
|
+
}
|
|
69
|
+
return txHashes;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export async function signAndSendTransaction(
|
|
74
|
+
request: UnsignedTransaction<Network, AptosChains>,
|
|
75
|
+
wallet: Account,
|
|
76
|
+
sponsorAccount: Account | GasStationApiKey | undefined
|
|
77
|
+
) {
|
|
78
|
+
if (!wallet) {
|
|
79
|
+
throw new Error("Wallet is undefined");
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const payload = request.transaction;
|
|
83
|
+
// The wallets do not handle Uint8Array serialization
|
|
84
|
+
payload.functionArguments = payload.functionArguments.map((a: any) => {
|
|
85
|
+
if (a instanceof Uint8Array) {
|
|
86
|
+
return Array.from(a);
|
|
87
|
+
} else if (typeof a === "bigint") {
|
|
88
|
+
return a.toString();
|
|
89
|
+
} else {
|
|
90
|
+
return a;
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const aptosConfig = new AptosConfig({
|
|
95
|
+
network: AptosNetwork.TESTNET,
|
|
96
|
+
});
|
|
97
|
+
const aptos = new Aptos(aptosConfig);
|
|
98
|
+
|
|
99
|
+
const txnToSign = await aptos.transaction.build.simple({
|
|
100
|
+
data: payload,
|
|
101
|
+
sender: wallet.accountAddress.toString(),
|
|
102
|
+
withFeePayer: sponsorAccount ? true : false,
|
|
103
|
+
});
|
|
104
|
+
const senderAuthenticator = await aptos.transaction.sign({
|
|
105
|
+
signer: wallet,
|
|
106
|
+
transaction: txnToSign,
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
const txnToSubmit: {
|
|
110
|
+
transaction: AnyRawTransaction;
|
|
111
|
+
senderAuthenticator: AccountAuthenticator;
|
|
112
|
+
feePayerAuthenticator?: AccountAuthenticator;
|
|
113
|
+
} = {
|
|
114
|
+
transaction: txnToSign,
|
|
115
|
+
senderAuthenticator,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
if (sponsorAccount) {
|
|
119
|
+
if (typeof sponsorAccount === "string") {
|
|
120
|
+
// TODO: handle gas station integration here
|
|
121
|
+
} else {
|
|
122
|
+
const feePayerSignerAuthenticator = aptos.transaction.signAsFeePayer({
|
|
123
|
+
signer: sponsorAccount as Account,
|
|
124
|
+
transaction: txnToSign,
|
|
125
|
+
});
|
|
126
|
+
txnToSubmit.feePayerAuthenticator = feePayerSignerAuthenticator;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
const response = await aptos.transaction.submit.simple(txnToSubmit);
|
|
130
|
+
|
|
131
|
+
const tx = await aptos.waitForTransaction({
|
|
132
|
+
transactionHash: response.hash,
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return tx.hash;
|
|
136
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
EvmUnsignedTransaction,
|
|
3
|
+
EvmChains,
|
|
4
|
+
} from "@wormhole-foundation/sdk-evm";
|
|
5
|
+
import { Network } from "@wormhole-foundation/sdk";
|
|
6
|
+
import { ethers, getBigInt } from "ethers";
|
|
7
|
+
import { AdapterWallet } from "@aptos-labs/wallet-adapter-core";
|
|
8
|
+
import { EIP1193DerivedWallet } from "@aptos-labs/derived-wallet-ethereum";
|
|
9
|
+
export async function signAndSendTransaction(
|
|
10
|
+
request: EvmUnsignedTransaction<Network, EvmChains>,
|
|
11
|
+
wallet: AdapterWallet,
|
|
12
|
+
chainName: string,
|
|
13
|
+
options: any
|
|
14
|
+
): Promise<string> {
|
|
15
|
+
if (!wallet) {
|
|
16
|
+
throw new Error("wallet.sendTransaction is undefined").message;
|
|
17
|
+
}
|
|
18
|
+
// Ensure the signer is connected to the correct chain
|
|
19
|
+
const chainId = await (
|
|
20
|
+
wallet as EIP1193DerivedWallet
|
|
21
|
+
).eip1193Provider.request({
|
|
22
|
+
method: "eth_chainId",
|
|
23
|
+
});
|
|
24
|
+
const actualChainId = parseInt(chainId, 16);
|
|
25
|
+
|
|
26
|
+
if (!actualChainId)
|
|
27
|
+
throw new Error("No signer found for chain" + chainName).message;
|
|
28
|
+
const expectedChainId = request.transaction.chainId
|
|
29
|
+
? getBigInt(request.transaction.chainId)
|
|
30
|
+
: undefined;
|
|
31
|
+
if (
|
|
32
|
+
!actualChainId ||
|
|
33
|
+
!expectedChainId ||
|
|
34
|
+
BigInt(actualChainId) !== expectedChainId
|
|
35
|
+
) {
|
|
36
|
+
throw new Error(
|
|
37
|
+
`Signer is not connected to the right chain. Expected ${expectedChainId}, got ${actualChainId}`
|
|
38
|
+
).message;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const provider = new ethers.BrowserProvider(
|
|
42
|
+
(wallet as EIP1193DerivedWallet).eip1193Provider
|
|
43
|
+
);
|
|
44
|
+
const signer = await provider.getSigner();
|
|
45
|
+
const response = await signer.sendTransaction(request.transaction);
|
|
46
|
+
const receipt = await response.wait();
|
|
47
|
+
|
|
48
|
+
return receipt?.hash || "";
|
|
49
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import {
|
|
2
|
+
UnsignedTransaction,
|
|
3
|
+
Network,
|
|
4
|
+
Chain,
|
|
5
|
+
TxHash,
|
|
6
|
+
SignAndSendSigner,
|
|
7
|
+
} from "@wormhole-foundation/sdk";
|
|
8
|
+
import { SolanaUnsignedTransaction } from "@wormhole-foundation/sdk-solana";
|
|
9
|
+
import { AdapterWallet } from "@aptos-labs/wallet-adapter-core";
|
|
10
|
+
import {
|
|
11
|
+
EvmUnsignedTransaction,
|
|
12
|
+
EvmChains,
|
|
13
|
+
} from "@wormhole-foundation/sdk-evm";
|
|
14
|
+
|
|
15
|
+
import * as solanaSigner from "./SolanaSigner";
|
|
16
|
+
import * as ethereumSigner from "./EthereumSigner";
|
|
17
|
+
// import {
|
|
18
|
+
// SuiChains,
|
|
19
|
+
// SuiUnsignedTransaction,
|
|
20
|
+
// } from "@wormhole-foundation/sdk-sui";
|
|
21
|
+
// import * as suiSigner from "./SuiSigner";
|
|
22
|
+
|
|
23
|
+
import { ChainConfig } from "../../../config";
|
|
24
|
+
import { CrossChainCore } from "../../../CrossChainCore";
|
|
25
|
+
export class Signer<N extends Network, C extends Chain>
|
|
26
|
+
implements SignAndSendSigner<N, C>
|
|
27
|
+
{
|
|
28
|
+
_chain: ChainConfig;
|
|
29
|
+
_address: string;
|
|
30
|
+
_options: any;
|
|
31
|
+
_wallet: AdapterWallet;
|
|
32
|
+
_crossChainCore?: CrossChainCore;
|
|
33
|
+
|
|
34
|
+
constructor(
|
|
35
|
+
chain: ChainConfig,
|
|
36
|
+
address: string,
|
|
37
|
+
options: any,
|
|
38
|
+
wallet: AdapterWallet,
|
|
39
|
+
crossChainCore?: CrossChainCore
|
|
40
|
+
) {
|
|
41
|
+
this._chain = chain;
|
|
42
|
+
this._address = address;
|
|
43
|
+
this._options = options;
|
|
44
|
+
this._wallet = wallet;
|
|
45
|
+
this._crossChainCore = crossChainCore;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
chain(): C {
|
|
49
|
+
return this._chain.displayName as C;
|
|
50
|
+
}
|
|
51
|
+
address(): string {
|
|
52
|
+
return this._address;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async signAndSend(txs: UnsignedTransaction<N, C>[]): Promise<TxHash[]> {
|
|
56
|
+
const txHashes: TxHash[] = [];
|
|
57
|
+
|
|
58
|
+
for (const tx of txs) {
|
|
59
|
+
const txId = await signAndSendTransaction(
|
|
60
|
+
this._chain,
|
|
61
|
+
tx,
|
|
62
|
+
this._wallet,
|
|
63
|
+
this._options,
|
|
64
|
+
this._crossChainCore
|
|
65
|
+
);
|
|
66
|
+
txHashes.push(txId);
|
|
67
|
+
}
|
|
68
|
+
return txHashes;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const signAndSendTransaction = async (
|
|
73
|
+
chain: ChainConfig,
|
|
74
|
+
request: UnsignedTransaction<Network, Chain>,
|
|
75
|
+
wallet: AdapterWallet,
|
|
76
|
+
options: any = {},
|
|
77
|
+
crossChainCore?: CrossChainCore
|
|
78
|
+
): Promise<string> => {
|
|
79
|
+
if (!wallet) {
|
|
80
|
+
throw new Error("wallet is undefined");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (chain.context === "Solana") {
|
|
84
|
+
const signature = await solanaSigner.signAndSendTransaction(
|
|
85
|
+
request as SolanaUnsignedTransaction<Network>,
|
|
86
|
+
wallet,
|
|
87
|
+
options,
|
|
88
|
+
crossChainCore
|
|
89
|
+
);
|
|
90
|
+
return signature;
|
|
91
|
+
} else if (chain.context === "Ethereum") {
|
|
92
|
+
const tx = await ethereumSigner.signAndSendTransaction(
|
|
93
|
+
request as EvmUnsignedTransaction<Network, EvmChains>,
|
|
94
|
+
wallet,
|
|
95
|
+
chain.displayName,
|
|
96
|
+
options
|
|
97
|
+
);
|
|
98
|
+
return tx;
|
|
99
|
+
} else {
|
|
100
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
101
|
+
}
|
|
102
|
+
};
|