@deserialize/multi-vm-wallet 1.5.35 → 1.6.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/dist/constant.js +54 -4
- package/dist/evm/evm.js +1 -1
- package/dist/savings/evm-savings.js +6 -4
- package/dist/savings/multi-chain-savings.js +2 -1
- package/dist/savings/saving-manager.d.ts +1 -1
- package/dist/savings/saving-manager.js +13 -14
- package/dist/savings/savings-operations.js +4 -2
- package/dist/savings/svm-savings.d.ts +1 -0
- package/dist/savings/svm-savings.js +16 -8
- package/dist/test.js +2 -0
- package/dist/types.d.ts +2 -1
- package/dist/utils.d.ts +30 -1
- package/dist/utils.js +199 -1
- package/dist/walletBip32.js +1 -1
- package/package.json +1 -1
- package/utils/constant.ts +58 -4
- package/utils/evm/evm.ts +1 -1
- package/utils/savings/evm-savings.ts +6 -4
- package/utils/savings/multi-chain-savings.ts +2 -2
- package/utils/savings/saving-manager.ts +20 -20
- package/utils/savings/savings-operations.ts +11 -9
- package/utils/savings/svm-savings.ts +17 -8
- package/utils/test.ts +1 -1
- package/utils/types.ts +2 -1
- package/utils/utils.ts +250 -4
- package/utils/walletBip32.ts +5 -2
package/dist/constant.js
CHANGED
|
@@ -16,7 +16,21 @@ exports.DefaultChains = [{
|
|
|
16
16
|
logoUrl: "https://solana.com/src/img/branding/solanaLogoMark.svg",
|
|
17
17
|
vmType: "SVM",
|
|
18
18
|
savings: {
|
|
19
|
-
|
|
19
|
+
supported: true,
|
|
20
|
+
tokens: [
|
|
21
|
+
{
|
|
22
|
+
name: "USDC",
|
|
23
|
+
symbol: "USDC",
|
|
24
|
+
decimals: 6,
|
|
25
|
+
address: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: "USDT",
|
|
29
|
+
symbol: "USDT",
|
|
30
|
+
decimals: 6,
|
|
31
|
+
address: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB"
|
|
32
|
+
}
|
|
33
|
+
]
|
|
20
34
|
}
|
|
21
35
|
},
|
|
22
36
|
{
|
|
@@ -33,6 +47,7 @@ exports.DefaultChains = [{
|
|
|
33
47
|
logoUrl: "https://push.org/assets/website/favicons/favicon.svg",
|
|
34
48
|
vmType: "EVM",
|
|
35
49
|
savings: {
|
|
50
|
+
supported: false,
|
|
36
51
|
tokens: []
|
|
37
52
|
}
|
|
38
53
|
},
|
|
@@ -48,7 +63,23 @@ exports.DefaultChains = [{
|
|
|
48
63
|
},
|
|
49
64
|
testnet: false,
|
|
50
65
|
logoUrl: "https://etherscan.io/images/svg/brands/ethereum-original-light.svg",
|
|
51
|
-
vmType: "EVM"
|
|
66
|
+
vmType: "EVM",
|
|
67
|
+
savings: {
|
|
68
|
+
supported: true,
|
|
69
|
+
tokens: [{
|
|
70
|
+
name: "USDC",
|
|
71
|
+
symbol: "USDC",
|
|
72
|
+
decimals: 6,
|
|
73
|
+
address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: "USDT",
|
|
77
|
+
symbol: "USDT",
|
|
78
|
+
decimals: 6,
|
|
79
|
+
address: "0xdac17f958d2ee523a2206206994597c13d831ec7"
|
|
80
|
+
}
|
|
81
|
+
]
|
|
82
|
+
}
|
|
52
83
|
}, {
|
|
53
84
|
chainId: 56,
|
|
54
85
|
name: "BSC",
|
|
@@ -63,7 +94,15 @@ exports.DefaultChains = [{
|
|
|
63
94
|
logoUrl: "https://bscscan.com/assets/bsc/images/svg/logos/token-light.svg?v=25.10.5.0",
|
|
64
95
|
vmType: "EVM",
|
|
65
96
|
savings: {
|
|
66
|
-
|
|
97
|
+
supported: true,
|
|
98
|
+
tokens: [
|
|
99
|
+
{
|
|
100
|
+
name: "BUSD",
|
|
101
|
+
symbol: "BUSD",
|
|
102
|
+
decimals: 6,
|
|
103
|
+
address: "0x55d398326f99059fF775485246999027B3197955"
|
|
104
|
+
}
|
|
105
|
+
]
|
|
67
106
|
}
|
|
68
107
|
},
|
|
69
108
|
{
|
|
@@ -80,7 +119,15 @@ exports.DefaultChains = [{
|
|
|
80
119
|
logoUrl: "https://avatars.githubusercontent.com/u/108554348?s=200&v=4",
|
|
81
120
|
vmType: "EVM",
|
|
82
121
|
savings: {
|
|
83
|
-
|
|
122
|
+
supported: true,
|
|
123
|
+
tokens: [
|
|
124
|
+
{
|
|
125
|
+
name: "USDC",
|
|
126
|
+
symbol: "USDC",
|
|
127
|
+
decimals: 6,
|
|
128
|
+
address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
129
|
+
}
|
|
130
|
+
]
|
|
84
131
|
}
|
|
85
132
|
},
|
|
86
133
|
{
|
|
@@ -97,6 +144,7 @@ exports.DefaultChains = [{
|
|
|
97
144
|
logoUrl: "https://avatars.githubusercontent.com/u/119917794?s=280&v=4",
|
|
98
145
|
vmType: "EVM",
|
|
99
146
|
savings: {
|
|
147
|
+
supported: false,
|
|
100
148
|
tokens: []
|
|
101
149
|
}
|
|
102
150
|
},
|
|
@@ -114,6 +162,7 @@ exports.DefaultChains = [{
|
|
|
114
162
|
logoUrl: "https://avatars.githubusercontent.com/u/58791460?s=280&v=4",
|
|
115
163
|
vmType: "EVM",
|
|
116
164
|
savings: {
|
|
165
|
+
supported: false,
|
|
117
166
|
tokens: []
|
|
118
167
|
}
|
|
119
168
|
},
|
|
@@ -131,6 +180,7 @@ exports.DefaultChains = [{
|
|
|
131
180
|
logoUrl: "https://polygonscan.com/images/svg/brands/polygon-light.svg?v=0.0.36",
|
|
132
181
|
vmType: "EVM",
|
|
133
182
|
savings: {
|
|
183
|
+
supported: false,
|
|
134
184
|
tokens: []
|
|
135
185
|
}
|
|
136
186
|
}
|
package/dist/evm/evm.js
CHANGED
|
@@ -397,7 +397,7 @@ class EVMVM extends vm_1.VM {
|
|
|
397
397
|
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
398
398
|
try {
|
|
399
399
|
const pocketIndex = accountIndex + 1;
|
|
400
|
-
const derivationPath = `m/44'/60'/${pocketIndex}'/0/${walletIndex}
|
|
400
|
+
const derivationPath = `m/44'/60'/${pocketIndex}'/0/${walletIndex}`;
|
|
401
401
|
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(this.seed, walletIndex, `m/44'/60'/${pocketIndex}'/0/`);
|
|
402
402
|
const wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
403
403
|
const address = wallet.address;
|
|
@@ -42,9 +42,10 @@ class EVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
42
42
|
this.checkNotDisposed();
|
|
43
43
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
44
44
|
const pocketIndex = accountIndex + 1;
|
|
45
|
-
const
|
|
45
|
+
const derivationPathBase = `${this.derivationPathBase}${pocketIndex}'/0/`;
|
|
46
|
+
const derivationPath = `${derivationPathBase}${this.walletIndex}'`;
|
|
46
47
|
const seed = (0, walletBip32_1.mnemonicToSeed)(this.mnemonic);
|
|
47
|
-
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, this.walletIndex,
|
|
48
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, this.walletIndex, derivationPathBase);
|
|
48
49
|
const wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
49
50
|
const pocket = {
|
|
50
51
|
privateKey,
|
|
@@ -57,9 +58,10 @@ class EVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
57
58
|
}
|
|
58
59
|
getMainWallet() {
|
|
59
60
|
this.checkNotDisposed();
|
|
60
|
-
const
|
|
61
|
+
const derivationPathBase = `${this.derivationPathBase}0'/0/`;
|
|
62
|
+
const derivationPath = `${derivationPathBase}${this.walletIndex}'`;
|
|
61
63
|
const seed = (0, walletBip32_1.mnemonicToSeed)(this.mnemonic);
|
|
62
|
-
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, this.walletIndex,
|
|
64
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, this.walletIndex, derivationPathBase);
|
|
63
65
|
const wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
64
66
|
return {
|
|
65
67
|
privateKey,
|
|
@@ -29,9 +29,9 @@ class MultiChainSavingsManager {
|
|
|
29
29
|
if (this.chainConfigs.has(chain.id)) {
|
|
30
30
|
throw new Error(`Chain with id '${chain.id}' already exists`);
|
|
31
31
|
}
|
|
32
|
-
this.chainConfigs.set(chain.id, chain);
|
|
33
32
|
if (chain.type === 'EVM') {
|
|
34
33
|
const manager = new evm_savings_1.EVMSavingsManager(this.mnemonic, chain.config, this.walletIndex);
|
|
34
|
+
this.chainConfigs.set(chain.id, chain);
|
|
35
35
|
this.evmManagers.set(chain.id, manager);
|
|
36
36
|
}
|
|
37
37
|
else if (chain.type === 'SVM') {
|
|
@@ -40,6 +40,7 @@ class MultiChainSavingsManager {
|
|
|
40
40
|
throw new Error(`SVM chain '${chain.id}' must have rpcUrl in config`);
|
|
41
41
|
}
|
|
42
42
|
const manager = new svm_savings_1.SVMSavingsManager(this.mnemonic, config.rpcUrl, this.walletIndex);
|
|
43
|
+
this.chainConfigs.set(chain.id, chain);
|
|
43
44
|
this.svmManagers.set(chain.id, manager);
|
|
44
45
|
}
|
|
45
46
|
else {
|
|
@@ -42,5 +42,5 @@ export declare class SavingsManager extends BaseSavingsManager {
|
|
|
42
42
|
address: Hex | 'native';
|
|
43
43
|
balance: Balance;
|
|
44
44
|
}[]>;
|
|
45
|
-
sendToMainWallet(pocketIndex: number,
|
|
45
|
+
sendToMainWallet(pocketIndex: number, amount: bigint, token: Hex | "native"): Promise<TransactionResult>;
|
|
46
46
|
}
|
|
@@ -43,24 +43,25 @@ class BaseSavingsManager {
|
|
|
43
43
|
derivePocket(accountIndex) {
|
|
44
44
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
45
45
|
const pocketIndex = accountIndex + 1;
|
|
46
|
-
const
|
|
47
|
-
const
|
|
46
|
+
const derivationPathBase = `m/44'/60'/${pocketIndex}'/0/`;
|
|
47
|
+
const derivationPath = `${derivationPathBase}${this.walletIndex}'`;
|
|
48
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)((0, walletBip32_1.mnemonicToSeed)(this.mnemonic), this.walletIndex, derivationPathBase);
|
|
48
49
|
const wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
49
50
|
const pocket = { privateKey, address: wallet.address, derivationPath, index: pocketIndex };
|
|
50
|
-
this.pockets.set(
|
|
51
|
+
this.pockets.set(accountIndex, pocket);
|
|
51
52
|
return pocket;
|
|
52
53
|
}
|
|
53
54
|
getMainWallet() {
|
|
54
|
-
const
|
|
55
|
-
const
|
|
55
|
+
const mainWalletDerivationPathBase = `m/44'/60'/0'/0/`;
|
|
56
|
+
const mainWalletDerivationPath = `${mainWalletDerivationPathBase}${this.walletIndex}'`;
|
|
57
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)((0, walletBip32_1.mnemonicToSeed)(this.mnemonic), this.walletIndex, mainWalletDerivationPathBase);
|
|
56
58
|
const wallet = new ethers_1.ethers.Wallet(privateKey);
|
|
57
59
|
return { privateKey, address: wallet.address, derivationPath: mainWalletDerivationPath };
|
|
58
60
|
}
|
|
59
61
|
getMainWalletAddress() {
|
|
60
62
|
if (this.masterAddress)
|
|
61
63
|
return this.masterAddress;
|
|
62
|
-
|
|
63
|
-
return new ethers_1.ethers.Wallet(privateKey).address;
|
|
64
|
+
return this.getMainWallet().address;
|
|
64
65
|
}
|
|
65
66
|
getPocket(accountIndex) {
|
|
66
67
|
if (!this.pockets.has(accountIndex)) {
|
|
@@ -88,7 +89,7 @@ class BaseSavingsManager {
|
|
|
88
89
|
return pocket.address.toLowerCase() === storedAddress.toLowerCase();
|
|
89
90
|
}
|
|
90
91
|
accountFromPocketId(p) {
|
|
91
|
-
return (0, accounts_1.privateKeyToAccount)(`0x${this.
|
|
92
|
+
return (0, accounts_1.privateKeyToAccount)(`0x${this.getPocket(p).privateKey}`);
|
|
92
93
|
}
|
|
93
94
|
clearPocket(accountIndex) {
|
|
94
95
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
@@ -151,11 +152,9 @@ class SavingsManager extends BaseSavingsManager {
|
|
|
151
152
|
}));
|
|
152
153
|
return balancesList;
|
|
153
154
|
}
|
|
154
|
-
async sendToMainWallet(pocketIndex,
|
|
155
|
+
async sendToMainWallet(pocketIndex, amount, token) {
|
|
155
156
|
validation_1.SavingsValidation.validateAccountIndex(pocketIndex);
|
|
156
|
-
|
|
157
|
-
throw new Error(`Amount must be a positive number, got: ${amountInEther}`);
|
|
158
|
-
}
|
|
157
|
+
validation_1.SavingsValidation.validateAmount(amount, 'Transfer amount');
|
|
159
158
|
if (token !== 'native') {
|
|
160
159
|
validation_1.SavingsValidation.validateAddress(token, 'Token address');
|
|
161
160
|
}
|
|
@@ -167,9 +166,9 @@ class SavingsManager extends BaseSavingsManager {
|
|
|
167
166
|
chain: this.client.chain
|
|
168
167
|
});
|
|
169
168
|
if (token === "native") {
|
|
170
|
-
return await (0, evm_1.sendNativeToken)(walletClient, this.client, mainWalletAddress,
|
|
169
|
+
return await (0, evm_1.sendNativeToken)(walletClient, this.client, mainWalletAddress, amount);
|
|
171
170
|
}
|
|
172
|
-
const res = await (0, evm_1.sendERC20Token)(walletClient, this.client, token, mainWalletAddress,
|
|
171
|
+
const res = await (0, evm_1.sendERC20Token)(walletClient, this.client, token, mainWalletAddress, amount);
|
|
173
172
|
return res;
|
|
174
173
|
}
|
|
175
174
|
}
|
|
@@ -9,8 +9,9 @@ class SavingsOperations {
|
|
|
9
9
|
validation_1.SavingsValidation.validateMnemonic(mnemonic);
|
|
10
10
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
11
11
|
validation_1.SavingsValidation.validateWalletIndex(walletIndex);
|
|
12
|
+
const pocketIndex = accountIndex + 1;
|
|
12
13
|
const seed = (0, walletBip32_1.mnemonicToSeed)(mnemonic);
|
|
13
|
-
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, walletIndex, `m/44'/60'/${
|
|
14
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, walletIndex, `m/44'/60'/${pocketIndex}'/0/`);
|
|
14
15
|
const wallet = new ethers_1.Wallet(privateKey, provider);
|
|
15
16
|
const address = wallet.address;
|
|
16
17
|
const cleanup = () => {
|
|
@@ -131,8 +132,9 @@ class SavingsOperations {
|
|
|
131
132
|
validation_1.SavingsValidation.validateMnemonic(mnemonic);
|
|
132
133
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
133
134
|
validation_1.SavingsValidation.validateWalletIndex(walletIndex);
|
|
135
|
+
const pocketIndex = accountIndex + 1;
|
|
134
136
|
const seed = (0, walletBip32_1.mnemonicToSeed)(mnemonic);
|
|
135
|
-
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, walletIndex, `m/44'/60'/${
|
|
137
|
+
const { privateKey } = (0, walletBip32_1.EVMDeriveChildPrivateKey)(seed, walletIndex, `m/44'/60'/${pocketIndex}'/0/`);
|
|
136
138
|
const wallet = new ethers_1.Wallet(privateKey);
|
|
137
139
|
const address = wallet.address;
|
|
138
140
|
return address;
|
|
@@ -10,6 +10,7 @@ export declare class SVMSavingsManager extends SavingsManager<PublicKey, Connect
|
|
|
10
10
|
get client(): Connection;
|
|
11
11
|
createClient(rpcUrl: string): Connection;
|
|
12
12
|
clearClient(): void;
|
|
13
|
+
private toSafeNumberAmount;
|
|
13
14
|
derivePocket(accountIndex: number): Pocket<PublicKey>;
|
|
14
15
|
getMainWallet(): {
|
|
15
16
|
privateKey: Keypair;
|
|
@@ -34,13 +34,20 @@ class SVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
34
34
|
clearClient() {
|
|
35
35
|
this._client = undefined;
|
|
36
36
|
}
|
|
37
|
+
toSafeNumberAmount(amount, label) {
|
|
38
|
+
if (amount > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
39
|
+
throw new Error(`${label} exceeds Number.MAX_SAFE_INTEGER and cannot be represented safely: ${amount}`);
|
|
40
|
+
}
|
|
41
|
+
return Number(amount);
|
|
42
|
+
}
|
|
37
43
|
derivePocket(accountIndex) {
|
|
38
44
|
this.checkNotDisposed();
|
|
39
45
|
validation_1.SavingsValidation.validateAccountIndex(accountIndex);
|
|
40
46
|
const pocketIndex = accountIndex + 1;
|
|
41
|
-
const
|
|
47
|
+
const derivationPathBase = `${this.derivationPathBase}${pocketIndex}'/0/`;
|
|
48
|
+
const derivationPath = `${derivationPathBase}${this.walletIndex}'`;
|
|
42
49
|
const seed = (0, walletBip32_1.mnemonicToSeed)(this.mnemonic);
|
|
43
|
-
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(seed, this.walletIndex,
|
|
50
|
+
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(seed, this.walletIndex, derivationPathBase);
|
|
44
51
|
const pocket = {
|
|
45
52
|
privateKey: keypair,
|
|
46
53
|
address: keypair.publicKey,
|
|
@@ -52,9 +59,10 @@ class SVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
52
59
|
}
|
|
53
60
|
getMainWallet() {
|
|
54
61
|
this.checkNotDisposed();
|
|
55
|
-
const
|
|
62
|
+
const derivationPathBase = `${this.derivationPathBase}0'/0/`;
|
|
63
|
+
const derivationPath = `${derivationPathBase}${this.walletIndex}'`;
|
|
56
64
|
const seed = (0, walletBip32_1.mnemonicToSeed)(this.mnemonic);
|
|
57
|
-
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(seed, this.walletIndex,
|
|
65
|
+
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(seed, this.walletIndex, derivationPathBase);
|
|
58
66
|
return {
|
|
59
67
|
privateKey: keypair,
|
|
60
68
|
address: keypair.publicKey,
|
|
@@ -120,7 +128,7 @@ class SVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
120
128
|
throw new Error(`Amount must be a positive bigint, got: ${amount}`);
|
|
121
129
|
}
|
|
122
130
|
const pocket = this.getPocket(pocketIndex);
|
|
123
|
-
const tx = await (0, svm_1.getTransferNativeTransaction)(mainWallet, pocket.address,
|
|
131
|
+
const tx = await (0, svm_1.getTransferNativeTransaction)(mainWallet, pocket.address, this.toSafeNumberAmount(amount, 'Native transfer amount'), this.client);
|
|
124
132
|
const hash = await (0, svm_1.signAndSendTransaction)(tx, this.client, mainWallet);
|
|
125
133
|
return { success: true, hash };
|
|
126
134
|
}
|
|
@@ -130,7 +138,7 @@ class SVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
130
138
|
throw new Error(`Amount must be a positive bigint, got: ${amount}`);
|
|
131
139
|
}
|
|
132
140
|
const pocket = this.getPocket(pocketIndex);
|
|
133
|
-
const tx = await (0, svm_1.getTransferTokenTransaction)(mainWallet, pocket.address, tokenInfo,
|
|
141
|
+
const tx = await (0, svm_1.getTransferTokenTransaction)(mainWallet, pocket.address, tokenInfo, this.toSafeNumberAmount(amount, 'Token transfer amount'), this.client);
|
|
134
142
|
const hash = await (0, svm_1.signAndSendTransaction)(tx, this.client, mainWallet);
|
|
135
143
|
return { success: true, hash };
|
|
136
144
|
}
|
|
@@ -160,11 +168,11 @@ class SVMSavingsManager extends savings_manager_1.SavingsManager {
|
|
|
160
168
|
const pocket = this.getPocket(pocketIndex);
|
|
161
169
|
const mainWalletAddress = this.getMainWalletAddress();
|
|
162
170
|
if (token === "native") {
|
|
163
|
-
const tx = await (0, svm_1.getTransferNativeTransaction)(pocket.privateKey, mainWalletAddress,
|
|
171
|
+
const tx = await (0, svm_1.getTransferNativeTransaction)(pocket.privateKey, mainWalletAddress, this.toSafeNumberAmount(amount, 'Native withdrawal amount'), this.client);
|
|
164
172
|
const hash = await (0, svm_1.signAndSendTransaction)(tx, this.client, pocket.privateKey);
|
|
165
173
|
return { success: true, hash };
|
|
166
174
|
}
|
|
167
|
-
const tx = await (0, svm_1.getTransferTokenTransaction)(pocket.privateKey, mainWalletAddress, token,
|
|
175
|
+
const tx = await (0, svm_1.getTransferTokenTransaction)(pocket.privateKey, mainWalletAddress, token, this.toSafeNumberAmount(amount, 'Token withdrawal amount'), this.client);
|
|
168
176
|
const hash = await (0, svm_1.signAndSendTransaction)(tx, this.client, pocket.privateKey);
|
|
169
177
|
return { success: true, hash };
|
|
170
178
|
}
|
package/dist/test.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const web3_js_1 = require("@solana/web3.js");
|
|
4
|
+
const svm_1 = require("./svm");
|
|
4
5
|
const evm_1 = require("./evm");
|
|
5
6
|
const viem_1 = require("viem");
|
|
6
7
|
const chains_1 = require("viem/chains");
|
|
@@ -243,6 +244,7 @@ const testAddressClass = async () => {
|
|
|
243
244
|
const evmAddressClass = new evm_1.EVMChainAddress(evmChainConfig, "0xC9C1D854b82BA9b4FB6f6D58E9EF3d1fAEd601AA", 0);
|
|
244
245
|
const res = await evmAddressClass.getNativeBalance();
|
|
245
246
|
console.log('res: ', res);
|
|
247
|
+
svm_1.SVMVM.generateMnemonicFromPrivateKey;
|
|
246
248
|
};
|
|
247
249
|
testAddressClass();
|
|
248
250
|
const RPC_URL = chainConfig.rpcUrl;
|
package/dist/types.d.ts
CHANGED
package/dist/utils.d.ts
CHANGED
|
@@ -1,2 +1,31 @@
|
|
|
1
|
-
import { vmTypes } from "./types";
|
|
1
|
+
import { ChainWalletConfig, vmTypes } from "./types";
|
|
2
2
|
export declare const getPrivateKeyFromAnother: (privateKey: any, fromVm: vmTypes, toVm: vmTypes) => string | import("@solana/web3.js").Keypair | undefined;
|
|
3
|
+
export interface AddressPortfolioItem {
|
|
4
|
+
tokenAddress: string | "native";
|
|
5
|
+
symbol: string;
|
|
6
|
+
decimals: number;
|
|
7
|
+
balanceRaw: string;
|
|
8
|
+
balanceFormatted: number;
|
|
9
|
+
priceUsd: number | null;
|
|
10
|
+
valueUsd: number | null;
|
|
11
|
+
}
|
|
12
|
+
export interface AddressPortfolioResult {
|
|
13
|
+
address: string;
|
|
14
|
+
vmType: vmTypes;
|
|
15
|
+
chainId: number;
|
|
16
|
+
items: AddressPortfolioItem[];
|
|
17
|
+
totals: {
|
|
18
|
+
valueUsd: number;
|
|
19
|
+
pricedItems: number;
|
|
20
|
+
unpricedItems: number;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface AddressPortfolioParams {
|
|
24
|
+
chain: ChainWalletConfig;
|
|
25
|
+
address: string;
|
|
26
|
+
vmType?: vmTypes;
|
|
27
|
+
includeNative?: boolean;
|
|
28
|
+
tokenAddresses?: string[];
|
|
29
|
+
}
|
|
30
|
+
export declare const detectVmTypeFromAddress: (address: string) => vmTypes;
|
|
31
|
+
export declare const getAddressPortfolioValue: (params: AddressPortfolioParams) => Promise<AddressPortfolioResult>;
|
package/dist/utils.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getPrivateKeyFromAnother = void 0;
|
|
6
|
+
exports.getAddressPortfolioValue = exports.detectVmTypeFromAddress = exports.getPrivateKeyFromAnother = void 0;
|
|
4
7
|
const evm_1 = require("./evm");
|
|
5
8
|
const svm_1 = require("./svm");
|
|
6
9
|
const sha2_1 = require("@noble/hashes/sha2");
|
|
10
|
+
const web3_js_1 = require("@solana/web3.js");
|
|
11
|
+
const utils_1 = require("./evm/utils");
|
|
12
|
+
const utils_2 = require("./svm/utils");
|
|
13
|
+
const bn_js_1 = __importDefault(require("bn.js"));
|
|
14
|
+
const price_1 = require("./price");
|
|
7
15
|
const getPrivateKeyFromAnother = (privateKey, fromVm, toVm) => {
|
|
8
16
|
if (fromVm === "EVM") {
|
|
9
17
|
if (toVm === "SVM") {
|
|
@@ -20,3 +28,193 @@ const getPrivateKeyFromAnother = (privateKey, fromVm, toVm) => {
|
|
|
20
28
|
}
|
|
21
29
|
};
|
|
22
30
|
exports.getPrivateKeyFromAnother = getPrivateKeyFromAnother;
|
|
31
|
+
const EVM_ADDRESS_REGEX = /^0x[a-fA-F0-9]{40}$/;
|
|
32
|
+
const detectVmTypeFromAddress = (address) => {
|
|
33
|
+
if (EVM_ADDRESS_REGEX.test(address)) {
|
|
34
|
+
return "EVM";
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
new web3_js_1.PublicKey(address);
|
|
38
|
+
return "SVM";
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
throw new Error(`Could not infer VM type from address: ${address}`);
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
exports.detectVmTypeFromAddress = detectVmTypeFromAddress;
|
|
45
|
+
const normalizePriceMap = (prices) => {
|
|
46
|
+
const priceMap = new Map();
|
|
47
|
+
for (const item of prices) {
|
|
48
|
+
if (!item?.tokenAddress || typeof item.price !== "number")
|
|
49
|
+
continue;
|
|
50
|
+
priceMap.set(item.tokenAddress.toLowerCase(), item.price);
|
|
51
|
+
}
|
|
52
|
+
return priceMap;
|
|
53
|
+
};
|
|
54
|
+
const enrichWithUsdValues = (items, priceMap) => {
|
|
55
|
+
return items.map((item) => {
|
|
56
|
+
const key = String(item.tokenAddress).toLowerCase();
|
|
57
|
+
const priceUsd = priceMap.get(key) ?? null;
|
|
58
|
+
const valueUsd = priceUsd === null ? null : item.balanceFormatted * priceUsd;
|
|
59
|
+
return {
|
|
60
|
+
...item,
|
|
61
|
+
priceUsd,
|
|
62
|
+
valueUsd,
|
|
63
|
+
};
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const buildTotals = (items) => {
|
|
67
|
+
let valueUsd = 0;
|
|
68
|
+
let pricedItems = 0;
|
|
69
|
+
let unpricedItems = 0;
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
if (item.valueUsd === null) {
|
|
72
|
+
unpricedItems += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
pricedItems += 1;
|
|
76
|
+
valueUsd += item.valueUsd;
|
|
77
|
+
}
|
|
78
|
+
return { valueUsd, pricedItems, unpricedItems };
|
|
79
|
+
};
|
|
80
|
+
const getAddressPortfolioValue = async (params) => {
|
|
81
|
+
const { chain, address, includeNative = true, tokenAddresses } = params;
|
|
82
|
+
const vmType = params.vmType ?? (0, exports.detectVmTypeFromAddress)(address);
|
|
83
|
+
if (vmType === "EVM" && !EVM_ADDRESS_REGEX.test(address)) {
|
|
84
|
+
throw new Error(`Invalid EVM address: ${address}`);
|
|
85
|
+
}
|
|
86
|
+
if (vmType === "SVM") {
|
|
87
|
+
new web3_js_1.PublicKey(address);
|
|
88
|
+
}
|
|
89
|
+
if (vmType === "EVM") {
|
|
90
|
+
const client = (0, utils_1.createPublicClientFromChainConfig)(chain);
|
|
91
|
+
const items = [];
|
|
92
|
+
const priceTargets = new Set();
|
|
93
|
+
if (includeNative) {
|
|
94
|
+
const nativeBalance = await (0, utils_1.getNativeBalance)(address, client);
|
|
95
|
+
const nativeRaw = nativeBalance.balance.toString();
|
|
96
|
+
items.push({
|
|
97
|
+
tokenAddress: "native",
|
|
98
|
+
symbol: chain.nativeToken.symbol,
|
|
99
|
+
decimals: chain.nativeToken.decimals,
|
|
100
|
+
balanceRaw: nativeRaw,
|
|
101
|
+
balanceFormatted: nativeBalance.formatted,
|
|
102
|
+
});
|
|
103
|
+
priceTargets.add("native");
|
|
104
|
+
}
|
|
105
|
+
if (tokenAddresses && tokenAddresses.length > 0) {
|
|
106
|
+
const tokenResults = await Promise.all(tokenAddresses.map(async (tokenAddress) => {
|
|
107
|
+
const balance = await (0, utils_1.getTokenBalance)(tokenAddress, address, client);
|
|
108
|
+
const raw = balance.balance.toString();
|
|
109
|
+
return {
|
|
110
|
+
tokenAddress,
|
|
111
|
+
symbol: tokenAddress,
|
|
112
|
+
decimals: balance.decimal,
|
|
113
|
+
balanceRaw: raw,
|
|
114
|
+
balanceFormatted: balance.formatted,
|
|
115
|
+
};
|
|
116
|
+
}));
|
|
117
|
+
for (const token of tokenResults) {
|
|
118
|
+
items.push(token);
|
|
119
|
+
priceTargets.add(token.tokenAddress);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const discovered = await (0, utils_1.discoverTokens)(address, chain);
|
|
124
|
+
for (const token of discovered) {
|
|
125
|
+
const raw = String(token.balance);
|
|
126
|
+
const decimals = token.decimals ?? 0;
|
|
127
|
+
const rawBn = new bn_js_1.default(raw);
|
|
128
|
+
const divisor = Math.pow(10, decimals);
|
|
129
|
+
const formatted = divisor === 0 ? 0 : Number(rawBn.toString()) / divisor;
|
|
130
|
+
items.push({
|
|
131
|
+
tokenAddress: token.address,
|
|
132
|
+
symbol: token.symbol,
|
|
133
|
+
decimals,
|
|
134
|
+
balanceRaw: raw,
|
|
135
|
+
balanceFormatted: formatted,
|
|
136
|
+
});
|
|
137
|
+
priceTargets.add(token.address);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
const priceResult = await (0, price_1.fetchPrices)({
|
|
141
|
+
vm: "EVM",
|
|
142
|
+
chainId: chain.chainId,
|
|
143
|
+
tokenAddresses: Array.from(priceTargets),
|
|
144
|
+
});
|
|
145
|
+
const priceMap = normalizePriceMap(priceResult.data?.prices ?? []);
|
|
146
|
+
const enrichedItems = enrichWithUsdValues(items, priceMap);
|
|
147
|
+
return {
|
|
148
|
+
address,
|
|
149
|
+
vmType,
|
|
150
|
+
chainId: chain.chainId,
|
|
151
|
+
items: enrichedItems,
|
|
152
|
+
totals: buildTotals(enrichedItems),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
const svmAddress = new web3_js_1.PublicKey(address);
|
|
156
|
+
const connection = new web3_js_1.Connection(chain.rpcUrl);
|
|
157
|
+
const items = [];
|
|
158
|
+
const priceTargets = new Set();
|
|
159
|
+
if (includeNative) {
|
|
160
|
+
const nativeBalance = await (0, utils_2.getSvmNativeBalance)(svmAddress, connection);
|
|
161
|
+
items.push({
|
|
162
|
+
tokenAddress: "native",
|
|
163
|
+
symbol: chain.nativeToken.symbol,
|
|
164
|
+
decimals: chain.nativeToken.decimals,
|
|
165
|
+
balanceRaw: nativeBalance.balance.toString(),
|
|
166
|
+
balanceFormatted: nativeBalance.formatted,
|
|
167
|
+
});
|
|
168
|
+
priceTargets.add("native");
|
|
169
|
+
}
|
|
170
|
+
if (tokenAddresses && tokenAddresses.length > 0) {
|
|
171
|
+
const tokenResults = await Promise.all(tokenAddresses.map(async (tokenAddress) => {
|
|
172
|
+
const pubkey = new web3_js_1.PublicKey(tokenAddress);
|
|
173
|
+
const tokenBalance = await svm_1.SVMVM.getTokenBalance(svmAddress, pubkey, connection);
|
|
174
|
+
return {
|
|
175
|
+
tokenAddress,
|
|
176
|
+
symbol: tokenAddress,
|
|
177
|
+
decimals: tokenBalance.decimal,
|
|
178
|
+
balanceRaw: tokenBalance.balance.toString(),
|
|
179
|
+
balanceFormatted: tokenBalance.formatted,
|
|
180
|
+
};
|
|
181
|
+
}));
|
|
182
|
+
for (const token of tokenResults) {
|
|
183
|
+
items.push(token);
|
|
184
|
+
priceTargets.add(token.tokenAddress);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
const discovered = await (0, utils_2.discoverTokens)(svmAddress, connection);
|
|
189
|
+
for (const token of discovered) {
|
|
190
|
+
const raw = String(token.balance);
|
|
191
|
+
const decimals = token.decimals ?? 0;
|
|
192
|
+
const rawBn = new bn_js_1.default(raw);
|
|
193
|
+
const divisor = Math.pow(10, decimals);
|
|
194
|
+
const formatted = divisor === 0 ? 0 : Number(rawBn.toString()) / divisor;
|
|
195
|
+
items.push({
|
|
196
|
+
tokenAddress: token.address,
|
|
197
|
+
symbol: token.symbol,
|
|
198
|
+
decimals,
|
|
199
|
+
balanceRaw: raw,
|
|
200
|
+
balanceFormatted: formatted,
|
|
201
|
+
});
|
|
202
|
+
priceTargets.add(token.address);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
const priceResult = await (0, price_1.fetchPrices)({
|
|
206
|
+
vm: "SVM",
|
|
207
|
+
chainId: chain.chainId,
|
|
208
|
+
tokenAddresses: Array.from(priceTargets),
|
|
209
|
+
});
|
|
210
|
+
const priceMap = normalizePriceMap(priceResult.data?.prices ?? []);
|
|
211
|
+
const enrichedItems = enrichWithUsdValues(items, priceMap);
|
|
212
|
+
return {
|
|
213
|
+
address,
|
|
214
|
+
vmType,
|
|
215
|
+
chainId: chain.chainId,
|
|
216
|
+
items: enrichedItems,
|
|
217
|
+
totals: buildTotals(enrichedItems),
|
|
218
|
+
};
|
|
219
|
+
};
|
|
220
|
+
exports.getAddressPortfolioValue = getAddressPortfolioValue;
|
package/dist/walletBip32.js
CHANGED
|
@@ -87,7 +87,7 @@ function GenerateSeed(_mnemonic) {
|
|
|
87
87
|
function EVMDeriveChildPrivateKey(seed, index, derivationPath) {
|
|
88
88
|
vm_validation_1.VMValidation.validateSeed(seed);
|
|
89
89
|
vm_validation_1.VMValidation.validateIndex(index, 'Wallet index');
|
|
90
|
-
const path = `${derivationPath}${index}
|
|
90
|
+
const path = derivationPath.endsWith("/") ? `${derivationPath}${index}` : derivationPath;
|
|
91
91
|
const scureNode = bip32_1.HDKey.fromMasterSeed(buffer_1.Buffer.from(seed, "hex"));
|
|
92
92
|
const child = scureNode.derive(path);
|
|
93
93
|
if (!child.privateKey) {
|