@deserialize/multi-vm-wallet 1.4.2 → 1.5.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/.claude/settings.local.json +7 -1
- package/BUILD_OPTIMIZATION_PLAN.md +640 -0
- package/BUILD_RESULTS.md +282 -0
- package/BUN_MIGRATION.md +415 -0
- package/CHANGELOG_SECURITY.md +573 -0
- package/IMPLEMENTATION_SUMMARY.md +494 -0
- package/SECURITY_AUDIT.md +1124 -0
- package/bun.lock +553 -0
- package/dist/IChainWallet.js +0 -5
- package/dist/bip32Old.js +0 -885
- package/dist/bip32Small.js +0 -79
- package/dist/bipTest.js +0 -362
- package/dist/constant.js +0 -17
- package/dist/english.js +0 -1
- package/dist/evm/aa-service/index.d.ts +0 -5
- package/dist/evm/aa-service/index.js +0 -14
- package/dist/evm/aa-service/lib/account-adapter.d.ts +0 -22
- package/dist/evm/aa-service/lib/account-adapter.js +0 -24
- package/dist/evm/aa-service/lib/kernel-account.d.ts +0 -30
- package/dist/evm/aa-service/lib/kernel-account.js +2 -67
- package/dist/evm/aa-service/lib/kernel-modules.d.ts +0 -177
- package/dist/evm/aa-service/lib/kernel-modules.js +4 -202
- package/dist/evm/aa-service/lib/session-keys.d.ts +0 -118
- package/dist/evm/aa-service/lib/session-keys.js +7 -151
- package/dist/evm/aa-service/lib/type.d.ts +0 -55
- package/dist/evm/aa-service/lib/type.js +0 -10
- package/dist/evm/aa-service/services/account-abstraction.d.ts +0 -426
- package/dist/evm/aa-service/services/account-abstraction.js +0 -461
- package/dist/evm/aa-service/services/bundler.d.ts +0 -6
- package/dist/evm/aa-service/services/bundler.js +0 -54
- package/dist/evm/evm.d.ts +9 -51
- package/dist/evm/evm.js +338 -76
- package/dist/evm/index.js +0 -3
- package/dist/evm/script.js +3 -17
- package/dist/evm/smartWallet.d.ts +0 -173
- package/dist/evm/smartWallet.js +0 -206
- package/dist/evm/smartWallet.types.d.ts +0 -6
- package/dist/evm/smartWallet.types.js +0 -8
- package/dist/evm/transaction.utils.d.ts +0 -242
- package/dist/evm/transaction.utils.js +4 -320
- package/dist/evm/transactionParsing.d.ts +0 -11
- package/dist/evm/transactionParsing.js +28 -147
- package/dist/evm/utils.d.ts +0 -46
- package/dist/evm/utils.js +1 -57
- package/dist/helpers/index.d.ts +0 -4
- package/dist/helpers/index.js +8 -44
- package/dist/helpers/routeScan.js +0 -1
- package/dist/index.js +0 -1
- package/dist/old.js +0 -884
- package/dist/price.js +0 -1
- package/dist/price.types.js +0 -2
- package/dist/rate-limiter.d.ts +28 -0
- package/dist/rate-limiter.js +95 -0
- package/dist/retry-logic.d.ts +14 -0
- package/dist/retry-logic.js +120 -0
- package/dist/savings/index.js +0 -1
- package/dist/savings/saving-manager.d.ts +10 -11
- package/dist/savings/saving-manager.js +79 -22
- package/dist/savings/savings-operations.d.ts +39 -0
- package/dist/savings/savings-operations.js +141 -0
- package/dist/savings/smart-savings.d.ts +0 -63
- package/dist/savings/smart-savings.js +0 -78
- package/dist/savings/types.d.ts +0 -69
- package/dist/savings/types.js +0 -7
- package/dist/savings/validation.d.ts +9 -0
- package/dist/savings/validation.js +85 -0
- package/dist/svm/constant.js +0 -1
- package/dist/svm/index.js +0 -1
- package/dist/svm/svm.d.ts +11 -1
- package/dist/svm/svm.js +267 -27
- package/dist/svm/transactionParsing.d.ts +0 -7
- package/dist/svm/transactionParsing.js +3 -41
- package/dist/svm/transactionSender.js +0 -9
- package/dist/svm/utils.d.ts +0 -12
- package/dist/svm/utils.js +9 -60
- package/dist/test.d.ts +0 -4
- package/dist/test.js +6 -98
- package/dist/transaction-utils.d.ts +38 -0
- package/dist/transaction-utils.js +168 -0
- package/dist/types.d.ts +36 -0
- package/dist/types.js +0 -1
- package/dist/utils.js +0 -1
- package/dist/vm-validation.d.ts +11 -0
- package/dist/vm-validation.js +151 -0
- package/dist/vm.d.ts +12 -2
- package/dist/vm.js +61 -16
- package/dist/walletBip32.js +15 -70
- package/package.json +9 -4
- package/test-discovery.ts +235 -0
- package/test-pocket-discovery.ts +84 -0
- package/tsconfig.json +18 -11
- package/tsconfig.prod.json +10 -0
- package/utils/evm/evm.ts +554 -8
- package/utils/rate-limiter.ts +179 -0
- package/utils/retry-logic.ts +271 -0
- package/utils/savings/EXAMPLES.md +883 -0
- package/utils/savings/SECURITY.md +731 -0
- package/utils/savings/saving-manager.ts +526 -16
- package/utils/savings/savings-operations.ts +509 -0
- package/utils/savings/validation.ts +187 -0
- package/utils/svm/svm.ts +476 -5
- package/utils/test.ts +2 -2
- package/utils/transaction-utils.ts +394 -0
- package/utils/types.ts +100 -0
- package/utils/vm-validation.ts +280 -0
- package/utils/vm.ts +197 -10
- package/utils/walletBip32.ts +39 -3
- package/dist/IChainWallet.js.map +0 -1
- package/dist/bip32.d.ts +0 -9
- package/dist/bip32.js +0 -172
- package/dist/bip32.js.map +0 -1
- package/dist/bip32Old.js.map +0 -1
- package/dist/bip32Small.js.map +0 -1
- package/dist/bipTest.js.map +0 -1
- package/dist/constant.js.map +0 -1
- package/dist/english.js.map +0 -1
- package/dist/evm/SMART_WALLET_EXAMPLES.d.ts +0 -20
- package/dist/evm/SMART_WALLET_EXAMPLES.js +0 -451
- package/dist/evm/SMART_WALLET_EXAMPLES.js.map +0 -1
- package/dist/evm/aa-service/index.js.map +0 -1
- package/dist/evm/aa-service/lib/account-adapter.js.map +0 -1
- package/dist/evm/aa-service/lib/kernel-account.js.map +0 -1
- package/dist/evm/aa-service/lib/kernel-modules.js.map +0 -1
- package/dist/evm/aa-service/lib/session-keys.js.map +0 -1
- package/dist/evm/aa-service/lib/type.js.map +0 -1
- package/dist/evm/aa-service/services/account-abstraction.js.map +0 -1
- package/dist/evm/aa-service/services/bundler.js.map +0 -1
- package/dist/evm/evm.js.map +0 -1
- package/dist/evm/index.js.map +0 -1
- package/dist/evm/script.js.map +0 -1
- package/dist/evm/smartWallet.js.map +0 -1
- package/dist/evm/smartWallet.types.js.map +0 -1
- package/dist/evm/transaction.utils.js.map +0 -1
- package/dist/evm/transactionParsing.js.map +0 -1
- package/dist/evm/utils.js.map +0 -1
- package/dist/helpers/index.js.map +0 -1
- package/dist/helpers/routeScan.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/old.js.map +0 -1
- package/dist/price.js.map +0 -1
- package/dist/price.types.js.map +0 -1
- package/dist/privacy/artifact-manager.d.ts +0 -117
- package/dist/privacy/artifact-manager.js +0 -251
- package/dist/privacy/artifact-manager.js.map +0 -1
- package/dist/privacy/broadcaster-client.d.ts +0 -166
- package/dist/privacy/broadcaster-client.js +0 -261
- package/dist/privacy/broadcaster-client.js.map +0 -1
- package/dist/privacy/index.d.ts +0 -34
- package/dist/privacy/index.js +0 -56
- package/dist/privacy/index.js.map +0 -1
- package/dist/privacy/network-config.d.ts +0 -57
- package/dist/privacy/network-config.js +0 -118
- package/dist/privacy/network-config.js.map +0 -1
- package/dist/privacy/poi-helper.d.ts +0 -161
- package/dist/privacy/poi-helper.js +0 -249
- package/dist/privacy/poi-helper.js.map +0 -1
- package/dist/privacy/railgun-engine.d.ts +0 -135
- package/dist/privacy/railgun-engine.js +0 -205
- package/dist/privacy/railgun-engine.js.map +0 -1
- package/dist/privacy/railgun-privacy-wallet.d.ts +0 -288
- package/dist/privacy/railgun-privacy-wallet.js +0 -539
- package/dist/privacy/railgun-privacy-wallet.js.map +0 -1
- package/dist/privacy/types.d.ts +0 -229
- package/dist/privacy/types.js +0 -26
- package/dist/privacy/types.js.map +0 -1
- package/dist/savings/index.js.map +0 -1
- package/dist/savings/saving-actions.d.ts +0 -0
- package/dist/savings/saving-actions.js +0 -78
- package/dist/savings/saving-actions.js.map +0 -1
- package/dist/savings/saving-manager.js.map +0 -1
- package/dist/savings/savings-manager.d.ts +0 -126
- package/dist/savings/savings-manager.js +0 -234
- package/dist/savings/savings-manager.js.map +0 -1
- package/dist/savings/smart-savings.js.map +0 -1
- package/dist/savings/types.js.map +0 -1
- package/dist/svm/constant.js.map +0 -1
- package/dist/svm/index.js.map +0 -1
- package/dist/svm/svm.js.map +0 -1
- package/dist/svm/transactionParsing.js.map +0 -1
- package/dist/svm/transactionSender.js.map +0 -1
- package/dist/svm/utils.js.map +0 -1
- package/dist/test.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/dist/vm.js.map +0 -1
- package/dist/walletBip32.js.map +0 -1
package/dist/svm/svm.js
CHANGED
|
@@ -8,9 +8,11 @@ const web3_js_1 = require("@solana/web3.js");
|
|
|
8
8
|
const walletBip32_1 = require("../walletBip32");
|
|
9
9
|
const vm_1 = require("../vm");
|
|
10
10
|
const IChainWallet_1 = require("../IChainWallet");
|
|
11
|
+
const vm_validation_1 = require("../vm-validation");
|
|
11
12
|
const utils_1 = require("./utils");
|
|
12
13
|
const bn_js_1 = __importDefault(require("bn.js"));
|
|
13
14
|
const tweetnacl_1 = __importDefault(require("tweetnacl"));
|
|
15
|
+
const bs58_1 = __importDefault(require("bs58"));
|
|
14
16
|
const price_1 = require("../price");
|
|
15
17
|
const transactionParsing_1 = require("./transactionParsing");
|
|
16
18
|
class SVMVM extends vm_1.VM {
|
|
@@ -25,7 +27,7 @@ class SVMVM extends vm_1.VM {
|
|
|
25
27
|
return false;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
|
-
derivationPath = "m/44'/501'/";
|
|
30
|
+
derivationPath = "m/44'/501'/";
|
|
29
31
|
constructor(seed) {
|
|
30
32
|
super(seed, "SVM");
|
|
31
33
|
}
|
|
@@ -46,14 +48,19 @@ class SVMVM extends vm_1.VM {
|
|
|
46
48
|
return web3_js_1.Keypair.fromSeed(Buffer.from(entropy));
|
|
47
49
|
};
|
|
48
50
|
generatePrivateKey(index, seed, mnemonic, derivationPath = this.derivationPath) {
|
|
51
|
+
vm_validation_1.VMValidation.validateIndex(index, 'Wallet index');
|
|
52
|
+
vm_validation_1.VMValidation.validateDerivationPath(derivationPath + index + "'", 'SVM');
|
|
49
53
|
let _seed;
|
|
50
54
|
if (seed) {
|
|
55
|
+
vm_validation_1.VMValidation.validateSeed(seed);
|
|
51
56
|
_seed = seed;
|
|
52
57
|
}
|
|
53
58
|
else if (mnemonic) {
|
|
59
|
+
vm_validation_1.VMValidation.validateMnemonic(mnemonic);
|
|
54
60
|
_seed = vm_1.VM.mnemonicToSeed(mnemonic);
|
|
55
61
|
}
|
|
56
62
|
else {
|
|
63
|
+
this.checkNotDisposed();
|
|
57
64
|
_seed = this.seed;
|
|
58
65
|
}
|
|
59
66
|
const privateKey = (0, walletBip32_1.SVMDeriveChildPrivateKey)(_seed, index, derivationPath);
|
|
@@ -63,6 +70,265 @@ class SVMVM extends vm_1.VM {
|
|
|
63
70
|
const seed = vm_1.VM.mnemonicToSeed(mnemonic);
|
|
64
71
|
return new SVMVM(seed);
|
|
65
72
|
}
|
|
73
|
+
deriveSavingsAccount(accountIndex) {
|
|
74
|
+
const derivationPath = `m/44'/501'/${accountIndex}'/0'`;
|
|
75
|
+
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(this.seed, 0, `m/44'/501'/${accountIndex}'/`);
|
|
76
|
+
return {
|
|
77
|
+
privateKey: keypair,
|
|
78
|
+
address: keypair.publicKey,
|
|
79
|
+
derivationPath
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
async discoverWallets(connection, options) {
|
|
83
|
+
const startTime = Date.now();
|
|
84
|
+
const { startIndex = 0, maxIndex = 100, gapLimit = 20, minBalance = BigInt(0), includeZeroBalance = false, includePrivateKeys = false, checkInParallel = true, batchSize = 10, checkDelay = checkInParallel ? 200 : 50, onProgress, onDiscovered } = options || {};
|
|
85
|
+
const discovered = [];
|
|
86
|
+
let consecutiveEmpty = 0;
|
|
87
|
+
let scannedIndices = 0;
|
|
88
|
+
let stoppedByGapLimit = false;
|
|
89
|
+
if (checkInParallel) {
|
|
90
|
+
for (let i = startIndex; i <= maxIndex; i += batchSize) {
|
|
91
|
+
const batchEnd = Math.min(i + batchSize, maxIndex + 1);
|
|
92
|
+
const batchPromises = [];
|
|
93
|
+
for (let j = i; j < batchEnd; j++) {
|
|
94
|
+
batchPromises.push(this.checkWalletBalance(j, connection));
|
|
95
|
+
}
|
|
96
|
+
const batchResults = await Promise.all(batchPromises);
|
|
97
|
+
for (let k = 0; k < batchResults.length; k++) {
|
|
98
|
+
const index = i + k;
|
|
99
|
+
const wallet = batchResults[k];
|
|
100
|
+
scannedIndices++;
|
|
101
|
+
if (wallet) {
|
|
102
|
+
const hasBalance = wallet.nativeBalance.amount > minBalance;
|
|
103
|
+
if (hasBalance || includeZeroBalance) {
|
|
104
|
+
if (!includePrivateKeys) {
|
|
105
|
+
delete wallet.privateKey;
|
|
106
|
+
}
|
|
107
|
+
discovered.push(wallet);
|
|
108
|
+
consecutiveEmpty = 0;
|
|
109
|
+
onDiscovered?.(wallet);
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
consecutiveEmpty++;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
consecutiveEmpty++;
|
|
117
|
+
}
|
|
118
|
+
onProgress?.(scannedIndices, maxIndex - startIndex + 1, discovered.length);
|
|
119
|
+
if (consecutiveEmpty >= gapLimit) {
|
|
120
|
+
stoppedByGapLimit = true;
|
|
121
|
+
break;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (stoppedByGapLimit) {
|
|
125
|
+
break;
|
|
126
|
+
}
|
|
127
|
+
if (batchEnd <= maxIndex) {
|
|
128
|
+
await this.sleep(checkDelay);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
for (let i = startIndex; i <= maxIndex; i++) {
|
|
134
|
+
const wallet = await this.checkWalletBalance(i, connection);
|
|
135
|
+
scannedIndices++;
|
|
136
|
+
if (wallet) {
|
|
137
|
+
const hasBalance = wallet.nativeBalance.amount > minBalance;
|
|
138
|
+
if (hasBalance || includeZeroBalance) {
|
|
139
|
+
if (!includePrivateKeys) {
|
|
140
|
+
delete wallet.privateKey;
|
|
141
|
+
}
|
|
142
|
+
discovered.push(wallet);
|
|
143
|
+
consecutiveEmpty = 0;
|
|
144
|
+
onDiscovered?.(wallet);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
consecutiveEmpty++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
consecutiveEmpty++;
|
|
152
|
+
}
|
|
153
|
+
onProgress?.(scannedIndices, maxIndex - startIndex + 1, discovered.length);
|
|
154
|
+
if (consecutiveEmpty >= gapLimit) {
|
|
155
|
+
stoppedByGapLimit = true;
|
|
156
|
+
break;
|
|
157
|
+
}
|
|
158
|
+
if (i < maxIndex) {
|
|
159
|
+
await this.sleep(checkDelay);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
const totalBalance = discovered.reduce((sum, wallet) => sum + wallet.nativeBalance.amount, BigInt(0));
|
|
164
|
+
const duration = Date.now() - startTime;
|
|
165
|
+
return {
|
|
166
|
+
discovered,
|
|
167
|
+
scannedIndices,
|
|
168
|
+
highestIndex: startIndex + scannedIndices - 1,
|
|
169
|
+
totalBalance,
|
|
170
|
+
stoppedByGapLimit,
|
|
171
|
+
duration
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
async checkWalletBalance(index, connection, maxRetries = 3) {
|
|
175
|
+
const derivationPath = `m/44'/501'/${index}'/0'`;
|
|
176
|
+
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(this.seed, 0, `m/44'/501'/${index}'/`);
|
|
177
|
+
const address = keypair.publicKey;
|
|
178
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
179
|
+
try {
|
|
180
|
+
const balanceLamports = await connection.getBalance(address);
|
|
181
|
+
const balanceSOL = balanceLamports / 1_000_000_000;
|
|
182
|
+
return {
|
|
183
|
+
index,
|
|
184
|
+
address: address.toString(),
|
|
185
|
+
derivationPath,
|
|
186
|
+
nativeBalance: {
|
|
187
|
+
amount: BigInt(balanceLamports),
|
|
188
|
+
formatted: balanceSOL,
|
|
189
|
+
symbol: 'SOL'
|
|
190
|
+
},
|
|
191
|
+
privateKey: bs58_1.default.encode(keypair.secretKey)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (attempt === maxRetries - 1) {
|
|
196
|
+
console.error(`Failed to check balance for index ${index} after ${maxRetries} attempts:`, error);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
const backoffMs = 1000 * Math.pow(2, attempt);
|
|
200
|
+
await this.sleep(backoffMs);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
sleep(ms) {
|
|
206
|
+
return new Promise(resolve => setTimeout(resolve, ms));
|
|
207
|
+
}
|
|
208
|
+
async discoverPockets(connection, options) {
|
|
209
|
+
const startTime = Date.now();
|
|
210
|
+
const { startIndex = 0, maxIndex = 100, gapLimit = 20, minBalance = BigInt(0), includeZeroBalance = false, includePrivateKeys = false, checkInParallel = true, batchSize = 10, checkDelay = checkInParallel ? 200 : 50, onProgress, onDiscovered, walletIndex = 0, } = options || {};
|
|
211
|
+
const discovered = [];
|
|
212
|
+
let consecutiveEmpty = 0;
|
|
213
|
+
let scannedIndices = 0;
|
|
214
|
+
let stoppedByGapLimit = false;
|
|
215
|
+
if (checkInParallel) {
|
|
216
|
+
for (let i = startIndex; i <= maxIndex; i += batchSize) {
|
|
217
|
+
const batchEnd = Math.min(i + batchSize, maxIndex + 1);
|
|
218
|
+
const batchPromises = [];
|
|
219
|
+
for (let j = i; j < batchEnd; j++) {
|
|
220
|
+
batchPromises.push(this.checkPocketBalance(j, walletIndex, connection));
|
|
221
|
+
}
|
|
222
|
+
const batchResults = await Promise.all(batchPromises);
|
|
223
|
+
for (let k = 0; k < batchResults.length; k++) {
|
|
224
|
+
const index = i + k;
|
|
225
|
+
const pocket = batchResults[k];
|
|
226
|
+
scannedIndices++;
|
|
227
|
+
if (pocket) {
|
|
228
|
+
const hasBalance = pocket.nativeBalance.amount > minBalance;
|
|
229
|
+
if (hasBalance || includeZeroBalance) {
|
|
230
|
+
if (!includePrivateKeys) {
|
|
231
|
+
delete pocket.privateKey;
|
|
232
|
+
}
|
|
233
|
+
discovered.push(pocket);
|
|
234
|
+
consecutiveEmpty = 0;
|
|
235
|
+
onDiscovered?.(pocket);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
consecutiveEmpty++;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
consecutiveEmpty++;
|
|
243
|
+
}
|
|
244
|
+
onProgress?.(scannedIndices, maxIndex - startIndex + 1, discovered.length);
|
|
245
|
+
if (consecutiveEmpty >= gapLimit) {
|
|
246
|
+
stoppedByGapLimit = true;
|
|
247
|
+
break;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (stoppedByGapLimit) {
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
if (batchEnd <= maxIndex) {
|
|
254
|
+
await this.sleep(checkDelay);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
else {
|
|
259
|
+
for (let i = startIndex; i <= maxIndex; i++) {
|
|
260
|
+
const pocket = await this.checkPocketBalance(i, walletIndex, connection);
|
|
261
|
+
scannedIndices++;
|
|
262
|
+
if (pocket) {
|
|
263
|
+
const hasBalance = pocket.nativeBalance.amount > minBalance;
|
|
264
|
+
if (hasBalance || includeZeroBalance) {
|
|
265
|
+
if (!includePrivateKeys) {
|
|
266
|
+
delete pocket.privateKey;
|
|
267
|
+
}
|
|
268
|
+
discovered.push(pocket);
|
|
269
|
+
consecutiveEmpty = 0;
|
|
270
|
+
onDiscovered?.(pocket);
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
consecutiveEmpty++;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
consecutiveEmpty++;
|
|
278
|
+
}
|
|
279
|
+
onProgress?.(scannedIndices, maxIndex - startIndex + 1, discovered.length);
|
|
280
|
+
if (consecutiveEmpty >= gapLimit) {
|
|
281
|
+
stoppedByGapLimit = true;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
if (i < maxIndex) {
|
|
285
|
+
await this.sleep(checkDelay);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
const totalBalance = discovered.reduce((sum, pocket) => sum + pocket.nativeBalance.amount, BigInt(0));
|
|
290
|
+
const duration = Date.now() - startTime;
|
|
291
|
+
return {
|
|
292
|
+
discovered,
|
|
293
|
+
scannedIndices,
|
|
294
|
+
highestIndex: startIndex + scannedIndices - 1,
|
|
295
|
+
totalBalance,
|
|
296
|
+
stoppedByGapLimit,
|
|
297
|
+
duration
|
|
298
|
+
};
|
|
299
|
+
}
|
|
300
|
+
async checkPocketBalance(accountIndex, walletIndex, connection, maxRetries = 3) {
|
|
301
|
+
const pocketIndex = accountIndex + 1;
|
|
302
|
+
const derivationPath = `m/44'/501'/${pocketIndex}'/0'`;
|
|
303
|
+
const keypair = (0, walletBip32_1.SVMDeriveChildPrivateKey)(this.seed, 0, `m/44'/501'/${pocketIndex}'/`);
|
|
304
|
+
const address = keypair.publicKey;
|
|
305
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
306
|
+
try {
|
|
307
|
+
const balanceLamports = await connection.getBalance(address);
|
|
308
|
+
const balanceSOL = balanceLamports / 1_000_000_000;
|
|
309
|
+
return {
|
|
310
|
+
index: accountIndex,
|
|
311
|
+
address: address.toString(),
|
|
312
|
+
derivationPath,
|
|
313
|
+
nativeBalance: {
|
|
314
|
+
amount: BigInt(balanceLamports),
|
|
315
|
+
formatted: balanceSOL,
|
|
316
|
+
symbol: 'SOL'
|
|
317
|
+
},
|
|
318
|
+
privateKey: bs58_1.default.encode(keypair.secretKey)
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
catch (error) {
|
|
322
|
+
if (attempt === maxRetries - 1) {
|
|
323
|
+
console.error(`Failed to check pocket at account ${accountIndex} after ${maxRetries} attempts:`, error);
|
|
324
|
+
return null;
|
|
325
|
+
}
|
|
326
|
+
const backoffMs = 1000 * Math.pow(2, attempt);
|
|
327
|
+
await this.sleep(backoffMs);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
66
332
|
}
|
|
67
333
|
exports.SVMVM = SVMVM;
|
|
68
334
|
class SVMChainWallet extends IChainWallet_1.ChainWallet {
|
|
@@ -79,31 +345,25 @@ class SVMChainWallet extends IChainWallet_1.ChainWallet {
|
|
|
79
345
|
return web3_js_1.Keypair.fromSeed(Buffer.from(entropy));
|
|
80
346
|
};
|
|
81
347
|
async getNativeBalance() {
|
|
82
|
-
// Implement native balance retrieval logic here
|
|
83
348
|
return await SVMVM.getNativeBalance(this.address, this.connection);
|
|
84
349
|
}
|
|
85
350
|
async getTokenBalance(tokenAddress) {
|
|
86
|
-
// Implement token balance retrieval logic here
|
|
87
351
|
return await SVMVM.getTokenBalance(this.address, (tokenAddress), this.connection);
|
|
88
352
|
}
|
|
89
353
|
async discoverToken() {
|
|
90
|
-
// Implement token discovery logic here
|
|
91
354
|
const tokens = await (0, utils_1.discoverTokens)(this.address, this.connection);
|
|
92
355
|
return tokens;
|
|
93
356
|
}
|
|
94
357
|
async discoverNFT() {
|
|
95
|
-
// Implement NFT discovery logic here
|
|
96
358
|
const nfts = await (0, utils_1.fetchWalletNfts)(this.address, this.connection);
|
|
97
359
|
return nfts;
|
|
98
360
|
}
|
|
99
361
|
async transferNative(to, amount) {
|
|
100
|
-
// Implement native transfer logic here
|
|
101
362
|
const transaction = await (0, utils_1.getTransferNativeTransaction)(this.privateKey, to, amount, this.connection);
|
|
102
363
|
const hash = await SVMVM.signAndSendTransaction(transaction, this.connection, this.privateKey);
|
|
103
364
|
return { success: true, hash };
|
|
104
365
|
}
|
|
105
366
|
async transferToken(token, to, amount) {
|
|
106
|
-
// Implement token transfer logic here
|
|
107
367
|
const transaction = await (0, utils_1.getTransferTokenTransaction)(this.privateKey, new web3_js_1.PublicKey(to), token, amount, this.connection);
|
|
108
368
|
const hash = await SVMVM.signAndSendTransaction(transaction, this.connection, this.privateKey);
|
|
109
369
|
return { success: true, hash };
|
|
@@ -153,26 +413,7 @@ class SVMChainWallet extends IChainWallet_1.ChainWallet {
|
|
|
153
413
|
}
|
|
154
414
|
const fromTokenMint = new web3_js_1.PublicKey(fromToken.address);
|
|
155
415
|
const toTokenMint = toToken;
|
|
156
|
-
// const validation = await validateJupiterTokens(
|
|
157
|
-
// fromTokenMint.toString(),
|
|
158
|
-
// toTokenMint.toString()
|
|
159
|
-
// );
|
|
160
|
-
// if (!validation.valid) {
|
|
161
|
-
// return {
|
|
162
|
-
// success: false,
|
|
163
|
-
// hash: "",
|
|
164
|
-
// error: validation.message || "Token validation failed"
|
|
165
|
-
// };
|
|
166
|
-
// }
|
|
167
416
|
const baseAmount = (0, utils_1.uiAmountToBaseUnits)(amount, fromToken.decimals);
|
|
168
|
-
// const balance = await this.getTokenBalance(fromTokenMint);
|
|
169
|
-
// if (balance.balance.lt(new BN(baseAmount))) {
|
|
170
|
-
// return {
|
|
171
|
-
// success: false,
|
|
172
|
-
// hash: "",
|
|
173
|
-
// error: "Insufficient balance for swap"
|
|
174
|
-
// };
|
|
175
|
-
// }
|
|
176
417
|
const swapResult = await (0, utils_1.executeJupiterSwap)({
|
|
177
418
|
fromToken: fromTokenMint,
|
|
178
419
|
toToken: toTokenMint,
|
|
@@ -228,4 +469,3 @@ class SVMChainWallet extends IChainWallet_1.ChainWallet {
|
|
|
228
469
|
};
|
|
229
470
|
}
|
|
230
471
|
exports.SVMChainWallet = SVMChainWallet;
|
|
231
|
-
//# sourceMappingURL=svm.js.map
|
|
@@ -18,11 +18,4 @@ export interface TransactionHistoryOptions {
|
|
|
18
18
|
before?: string;
|
|
19
19
|
until?: string;
|
|
20
20
|
}
|
|
21
|
-
/**
|
|
22
|
-
* Fetches and parses transaction history for a Solana wallet address
|
|
23
|
-
* @param connection - Solana RPC connection
|
|
24
|
-
* @param walletAddress - Public key of the wallet (string or PublicKey)
|
|
25
|
-
* @param options - Optional parameters for pagination and filtering
|
|
26
|
-
* @returns Array of parsed transaction history items
|
|
27
|
-
*/
|
|
28
21
|
export declare function getSVMTransactionHistory(connection: Connection, walletAddress: PublicKey, options?: TransactionHistoryOptions): Promise<SVMTransactionHistoryItem[]>;
|
|
@@ -3,36 +3,24 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.getSVMTransactionHistory = getSVMTransactionHistory;
|
|
4
4
|
const web3_js_1 = require("@solana/web3.js");
|
|
5
5
|
const constant_1 = require("../constant");
|
|
6
|
-
/**
|
|
7
|
-
* Fetches and parses transaction history for a Solana wallet address
|
|
8
|
-
* @param connection - Solana RPC connection
|
|
9
|
-
* @param walletAddress - Public key of the wallet (string or PublicKey)
|
|
10
|
-
* @param options - Optional parameters for pagination and filtering
|
|
11
|
-
* @returns Array of parsed transaction history items
|
|
12
|
-
*/
|
|
13
6
|
async function getSVMTransactionHistory(connection, walletAddress, options = {}) {
|
|
14
7
|
const { limit = 50, before, until } = options;
|
|
15
8
|
const publicKey = typeof walletAddress === 'string'
|
|
16
9
|
? new web3_js_1.PublicKey(walletAddress)
|
|
17
10
|
: walletAddress;
|
|
18
11
|
try {
|
|
19
|
-
// Fetch signature info
|
|
20
12
|
const signatures = await connection.getSignaturesForAddress(publicKey, {
|
|
21
13
|
limit,
|
|
22
14
|
before,
|
|
23
15
|
until,
|
|
24
16
|
});
|
|
25
17
|
console.log(`Found ${signatures.length} transactions`);
|
|
26
|
-
|
|
27
|
-
const transactions = await fetchTransactionsInBatches(connection, signatures, 5 // batch size
|
|
28
|
-
);
|
|
29
|
-
// Parse transactions into a user-friendly format
|
|
18
|
+
const transactions = await fetchTransactionsInBatches(connection, signatures, 5);
|
|
30
19
|
const history = [];
|
|
31
20
|
for (let i = 0; i < transactions.length; i++) {
|
|
32
21
|
const tx = transactions[i];
|
|
33
22
|
const sigInfo = signatures[i];
|
|
34
23
|
if (!tx) {
|
|
35
|
-
// Transaction might be null if it's not available
|
|
36
24
|
history.push({
|
|
37
25
|
hash: sigInfo.signature,
|
|
38
26
|
timestamp: sigInfo.blockTime,
|
|
@@ -63,9 +51,6 @@ async function getSVMTransactionHistory(connection, walletAddress, options = {})
|
|
|
63
51
|
throw error;
|
|
64
52
|
}
|
|
65
53
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Fetches transactions in batches to avoid overwhelming the RPC
|
|
68
|
-
*/
|
|
69
54
|
async function fetchTransactionsInBatches(connection, signatures, batchSize) {
|
|
70
55
|
const transactions = [];
|
|
71
56
|
for (let i = 0; i < signatures.length; i += batchSize) {
|
|
@@ -75,23 +60,16 @@ async function fetchTransactionsInBatches(connection, signatures, batchSize) {
|
|
|
75
60
|
}));
|
|
76
61
|
const batchResults = await Promise.all(batchPromises);
|
|
77
62
|
transactions.push(...batchResults);
|
|
78
|
-
// Small delay to avoid rate limiting
|
|
79
63
|
if (i + batchSize < signatures.length) {
|
|
80
64
|
await new Promise(resolve => setTimeout(resolve, 100));
|
|
81
65
|
}
|
|
82
66
|
}
|
|
83
67
|
return transactions;
|
|
84
68
|
}
|
|
85
|
-
/**
|
|
86
|
-
* Parses a transaction into a simplified format
|
|
87
|
-
*/
|
|
88
69
|
function parseTransaction(tx, walletAddress) {
|
|
89
70
|
const fee = tx.meta?.fee || 0;
|
|
90
|
-
// Try to determine transaction type and extract relevant info
|
|
91
71
|
const instructions = tx.transaction.message.instructions;
|
|
92
|
-
// Check for token transfers
|
|
93
72
|
if (tx.meta?.preTokenBalances && tx.meta?.postTokenBalances) {
|
|
94
|
-
// console.log('tx.meta: ', tx.meta);
|
|
95
73
|
const tokenTransfer = findTokenTransfer(tx.meta.preTokenBalances, tx.meta.postTokenBalances, walletAddress);
|
|
96
74
|
if (tokenTransfer) {
|
|
97
75
|
return {
|
|
@@ -104,7 +82,6 @@ function parseTransaction(tx, walletAddress) {
|
|
|
104
82
|
};
|
|
105
83
|
}
|
|
106
84
|
}
|
|
107
|
-
// Check for SOL transfers
|
|
108
85
|
if (tx.meta?.preBalances && tx.meta?.postBalances) {
|
|
109
86
|
const solTransfer = findSolTransfer(tx.meta.preBalances, tx.meta.postBalances, tx.transaction.message.accountKeys, walletAddress);
|
|
110
87
|
if (solTransfer) {
|
|
@@ -118,9 +95,7 @@ function parseTransaction(tx, walletAddress) {
|
|
|
118
95
|
};
|
|
119
96
|
}
|
|
120
97
|
}
|
|
121
|
-
// Check for memo
|
|
122
98
|
const memo = extractMemo(instructions);
|
|
123
|
-
// Determine general type based on instructions
|
|
124
99
|
const type = determineTransactionType(instructions);
|
|
125
100
|
return {
|
|
126
101
|
fee,
|
|
@@ -128,9 +103,6 @@ function parseTransaction(tx, walletAddress) {
|
|
|
128
103
|
memo,
|
|
129
104
|
};
|
|
130
105
|
}
|
|
131
|
-
/**
|
|
132
|
-
* Finds token transfers in the transaction
|
|
133
|
-
*/
|
|
134
106
|
function findTokenTransfer(preBalances, postBalances, walletAddress) {
|
|
135
107
|
for (let i = 0; i < postBalances.length; i++) {
|
|
136
108
|
const post = postBalances[i];
|
|
@@ -158,27 +130,21 @@ function findTokenTransfer(preBalances, postBalances, walletAddress) {
|
|
|
158
130
|
}
|
|
159
131
|
return null;
|
|
160
132
|
}
|
|
161
|
-
/**
|
|
162
|
-
* Finds SOL transfers in the transaction
|
|
163
|
-
*/
|
|
164
133
|
function findSolTransfer(preBalances, postBalances, accountKeys, walletAddress) {
|
|
165
134
|
for (let i = 0; i < preBalances.length; i++) {
|
|
166
135
|
const diff = postBalances[i] - preBalances[i];
|
|
167
136
|
const account = accountKeys[i];
|
|
168
137
|
const accountPubkey = typeof account === 'string' ? account : account.pubkey.toBase58();
|
|
169
|
-
if (Math.abs(diff) > 5000 && accountPubkey === walletAddress) {
|
|
138
|
+
if (Math.abs(diff) > 5000 && accountPubkey === walletAddress) {
|
|
170
139
|
return {
|
|
171
140
|
from: diff < 0 ? accountPubkey : 'unknown',
|
|
172
141
|
to: diff > 0 ? accountPubkey : 'unknown',
|
|
173
|
-
amount: Math.abs(diff) / 1e9,
|
|
142
|
+
amount: Math.abs(diff) / 1e9,
|
|
174
143
|
};
|
|
175
144
|
}
|
|
176
145
|
}
|
|
177
146
|
return null;
|
|
178
147
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Extracts memo from transaction instructions
|
|
181
|
-
*/
|
|
182
148
|
function extractMemo(instructions) {
|
|
183
149
|
for (const instruction of instructions) {
|
|
184
150
|
if (instruction.program === 'spl-memo' || instruction.programId?.toBase58() === 'MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr') {
|
|
@@ -187,9 +153,6 @@ function extractMemo(instructions) {
|
|
|
187
153
|
}
|
|
188
154
|
return undefined;
|
|
189
155
|
}
|
|
190
|
-
/**
|
|
191
|
-
* Determines the general type of transaction
|
|
192
|
-
*/
|
|
193
156
|
function determineTransactionType(instructions) {
|
|
194
157
|
if (instructions.length === 0)
|
|
195
158
|
return constant_1.TRANSACTION_TYPE.UNKNOWN;
|
|
@@ -204,4 +167,3 @@ function determineTransactionType(instructions) {
|
|
|
204
167
|
return constant_1.TRANSACTION_TYPE.STAKING;
|
|
205
168
|
return constant_1.TRANSACTION_TYPE.PROGRAM_INTERACTION;
|
|
206
169
|
}
|
|
207
|
-
//# sourceMappingURL=transactionParsing.js.map
|
|
@@ -31,8 +31,6 @@ async function transactionSenderAndConfirmationWaiter({ connection, serializedTr
|
|
|
31
31
|
try {
|
|
32
32
|
abortableResender();
|
|
33
33
|
const lastValidBlockHeight = blockhashWithExpiryBlockHeight.lastValidBlockHeight - 150;
|
|
34
|
-
// this would throw TransactionExpiredBlockheightExceededError
|
|
35
|
-
// console.log("conforming the transaction ....")
|
|
36
34
|
const res = await Promise.race([
|
|
37
35
|
connection.confirmTransaction({
|
|
38
36
|
...blockhashWithExpiryBlockHeight,
|
|
@@ -41,7 +39,6 @@ async function transactionSenderAndConfirmationWaiter({ connection, serializedTr
|
|
|
41
39
|
abortSignal,
|
|
42
40
|
}, "confirmed"),
|
|
43
41
|
new Promise(async (resolve) => {
|
|
44
|
-
// in case ws socket died
|
|
45
42
|
while (!abortSignal.aborted) {
|
|
46
43
|
await wait(2_000);
|
|
47
44
|
const tx = await connection.getSignatureStatus(txid, {
|
|
@@ -56,20 +53,15 @@ async function transactionSenderAndConfirmationWaiter({ connection, serializedTr
|
|
|
56
53
|
console.log('res: ', res);
|
|
57
54
|
}
|
|
58
55
|
catch (e) {
|
|
59
|
-
// console.log('e: ', e);
|
|
60
56
|
if (e instanceof web3_js_1.TransactionExpiredBlockheightExceededError) {
|
|
61
|
-
// we consume this error and getTransaction would return null
|
|
62
|
-
// return null;
|
|
63
57
|
}
|
|
64
58
|
else {
|
|
65
|
-
// invalid state from web3.js
|
|
66
59
|
throw e;
|
|
67
60
|
}
|
|
68
61
|
}
|
|
69
62
|
finally {
|
|
70
63
|
controller.abort();
|
|
71
64
|
}
|
|
72
|
-
// in case rpc is not synced yet, we add some retries
|
|
73
65
|
const response = (0, promise_retry_1.default)(async (retry) => {
|
|
74
66
|
const response = await connection.getTransaction(txid, {
|
|
75
67
|
commitment: "confirmed",
|
|
@@ -85,4 +77,3 @@ async function transactionSenderAndConfirmationWaiter({ connection, serializedTr
|
|
|
85
77
|
});
|
|
86
78
|
return response;
|
|
87
79
|
}
|
|
88
|
-
//# sourceMappingURL=transactionSender.js.map
|
package/dist/svm/utils.d.ts
CHANGED
|
@@ -91,17 +91,5 @@ export declare const validateJupiterTokens: (inputMint: string, outputMint: stri
|
|
|
91
91
|
}>;
|
|
92
92
|
export declare const transformSolanaNFTToUnified: (nft: SolanaNFT) => NFT;
|
|
93
93
|
export declare const fetchWalletNfts: (walletAddress: PublicKey, connection: Connection) => Promise<NFT[]>;
|
|
94
|
-
/**
|
|
95
|
-
* Get NFT collection details for a specific collection on Solana
|
|
96
|
-
* @param walletAddress - User's wallet public key
|
|
97
|
-
* @param collectionAddress - The NFT collection address (can be collection mint or update authority)
|
|
98
|
-
* @param connection - Solana connection
|
|
99
|
-
* @returns NFTCollection object with collection details and user's NFTs in that collection
|
|
100
|
-
*
|
|
101
|
-
* Note: On Solana, collections can be identified by:
|
|
102
|
-
* - Collection mint address (from collection field in NFT metadata)
|
|
103
|
-
* - Update authority (who can modify the NFT metadata)
|
|
104
|
-
* This function filters by the collection.address field which is typically the collection mint
|
|
105
|
-
*/
|
|
106
94
|
export declare const getNFTCollection: (walletAddress: PublicKey, collectionAddress: string, connection: Connection) => Promise<NFTCollection | null>;
|
|
107
95
|
export {};
|