@zubari/sdk 0.5.2 → 0.5.3
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/index.js +227 -797
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +225 -795
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.js +175 -745
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +173 -743
- package/dist/react/index.mjs.map +1 -1
- package/dist/services/index.js +113 -707
- package/dist/services/index.js.map +1 -1
- package/dist/services/index.mjs +111 -705
- package/dist/services/index.mjs.map +1 -1
- package/dist/wallet/index.js +176 -746
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/index.mjs +174 -744
- package/dist/wallet/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -4,11 +4,8 @@ var react = require('react');
|
|
|
4
4
|
var ethers = require('ethers');
|
|
5
5
|
var bip39 = require('@scure/bip39');
|
|
6
6
|
var english = require('@scure/bip39/wordlists/english');
|
|
7
|
-
var
|
|
8
|
-
var
|
|
9
|
-
var legacy_js = require('@noble/hashes/legacy.js');
|
|
10
|
-
var sha2_js = require('@noble/hashes/sha2.js');
|
|
11
|
-
var utils_js = require('@noble/hashes/utils.js');
|
|
7
|
+
var bip32 = require('@scure/bip32');
|
|
8
|
+
var base = require('@scure/base');
|
|
12
9
|
var sha256 = require('@noble/hashes/sha256');
|
|
13
10
|
var ripemd160 = require('@noble/hashes/ripemd160');
|
|
14
11
|
var viem = require('viem');
|
|
@@ -137,8 +134,8 @@ var TESTNET_NETWORKS = {
|
|
|
137
134
|
var USDT_ADDRESSES = {
|
|
138
135
|
ethereum: {
|
|
139
136
|
mainnet: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
|
|
140
|
-
testnet: "
|
|
141
|
-
// Sepolia
|
|
137
|
+
testnet: "0x7169D38820dfd117C3FA1f22a697dBA58d90BA06"
|
|
138
|
+
// Sepolia (Test Tether USD)
|
|
142
139
|
},
|
|
143
140
|
tron: {
|
|
144
141
|
mainnet: "TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t",
|
|
@@ -219,14 +216,14 @@ var WdkApiClient = class {
|
|
|
219
216
|
/**
|
|
220
217
|
* Derive address for a specific chain using Tether WDK
|
|
221
218
|
*/
|
|
222
|
-
async deriveAddress(seed,
|
|
219
|
+
async deriveAddress(seed, chain, network = "mainnet") {
|
|
223
220
|
try {
|
|
224
221
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/derive-address`, {
|
|
225
222
|
method: "POST",
|
|
226
223
|
headers: {
|
|
227
224
|
"Content-Type": "application/json"
|
|
228
225
|
},
|
|
229
|
-
body: JSON.stringify({ seed, chain
|
|
226
|
+
body: JSON.stringify({ seed, chain, network })
|
|
230
227
|
});
|
|
231
228
|
return await response.json();
|
|
232
229
|
} catch (error) {
|
|
@@ -259,14 +256,14 @@ var WdkApiClient = class {
|
|
|
259
256
|
/**
|
|
260
257
|
* Send a transaction on a specific chain using Tether WDK
|
|
261
258
|
*/
|
|
262
|
-
async sendTransaction(seed,
|
|
259
|
+
async sendTransaction(seed, chain, to, amount, network = "mainnet") {
|
|
263
260
|
try {
|
|
264
261
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/send`, {
|
|
265
262
|
method: "POST",
|
|
266
263
|
headers: {
|
|
267
264
|
"Content-Type": "application/json"
|
|
268
265
|
},
|
|
269
|
-
body: JSON.stringify({ seed, chain
|
|
266
|
+
body: JSON.stringify({ seed, chain, to, amount, network })
|
|
270
267
|
});
|
|
271
268
|
return await response.json();
|
|
272
269
|
} catch (error) {
|
|
@@ -280,14 +277,14 @@ var WdkApiClient = class {
|
|
|
280
277
|
* Get transaction history for an address on a specific chain
|
|
281
278
|
* Fetches from blockchain explorers (Etherscan, mempool.space, etc.)
|
|
282
279
|
*/
|
|
283
|
-
async getTransactionHistory(seed,
|
|
280
|
+
async getTransactionHistory(seed, chain, network = "mainnet", limit = 10) {
|
|
284
281
|
try {
|
|
285
282
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/history`, {
|
|
286
283
|
method: "POST",
|
|
287
284
|
headers: {
|
|
288
285
|
"Content-Type": "application/json"
|
|
289
286
|
},
|
|
290
|
-
body: JSON.stringify({ seed, chain
|
|
287
|
+
body: JSON.stringify({ seed, chain, network, limit })
|
|
291
288
|
});
|
|
292
289
|
return await response.json();
|
|
293
290
|
} catch (error) {
|
|
@@ -301,14 +298,14 @@ var WdkApiClient = class {
|
|
|
301
298
|
* Get transaction status by hash
|
|
302
299
|
* Fetches from blockchain explorers to check confirmation status
|
|
303
300
|
*/
|
|
304
|
-
async getTransactionStatus(txHash,
|
|
301
|
+
async getTransactionStatus(txHash, chain, network = "mainnet") {
|
|
305
302
|
try {
|
|
306
303
|
const response = await fetch(`${this.config.baseUrl}/api/wallets/wdk/tx-status`, {
|
|
307
304
|
method: "POST",
|
|
308
305
|
headers: {
|
|
309
306
|
"Content-Type": "application/json"
|
|
310
307
|
},
|
|
311
|
-
body: JSON.stringify({ txHash, chain
|
|
308
|
+
body: JSON.stringify({ txHash, chain, network })
|
|
312
309
|
});
|
|
313
310
|
return await response.json();
|
|
314
311
|
} catch (error) {
|
|
@@ -329,589 +326,6 @@ function getWdkApiClient(baseUrl) {
|
|
|
329
326
|
}
|
|
330
327
|
return wdkApiClient;
|
|
331
328
|
}
|
|
332
|
-
|
|
333
|
-
// node_modules/@scure/base/index.js
|
|
334
|
-
function isBytes(a) {
|
|
335
|
-
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
336
|
-
}
|
|
337
|
-
function isArrayOf(isString, arr) {
|
|
338
|
-
if (!Array.isArray(arr))
|
|
339
|
-
return false;
|
|
340
|
-
if (arr.length === 0)
|
|
341
|
-
return true;
|
|
342
|
-
if (isString) {
|
|
343
|
-
return arr.every((item) => typeof item === "string");
|
|
344
|
-
} else {
|
|
345
|
-
return arr.every((item) => Number.isSafeInteger(item));
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
function afn(input) {
|
|
349
|
-
if (typeof input !== "function")
|
|
350
|
-
throw new Error("function expected");
|
|
351
|
-
return true;
|
|
352
|
-
}
|
|
353
|
-
function astr(label, input) {
|
|
354
|
-
if (typeof input !== "string")
|
|
355
|
-
throw new Error(`${label}: string expected`);
|
|
356
|
-
return true;
|
|
357
|
-
}
|
|
358
|
-
function anumber(n) {
|
|
359
|
-
if (!Number.isSafeInteger(n))
|
|
360
|
-
throw new Error(`invalid integer: ${n}`);
|
|
361
|
-
}
|
|
362
|
-
function aArr(input) {
|
|
363
|
-
if (!Array.isArray(input))
|
|
364
|
-
throw new Error("array expected");
|
|
365
|
-
}
|
|
366
|
-
function astrArr(label, input) {
|
|
367
|
-
if (!isArrayOf(true, input))
|
|
368
|
-
throw new Error(`${label}: array of strings expected`);
|
|
369
|
-
}
|
|
370
|
-
function anumArr(label, input) {
|
|
371
|
-
if (!isArrayOf(false, input))
|
|
372
|
-
throw new Error(`${label}: array of numbers expected`);
|
|
373
|
-
}
|
|
374
|
-
// @__NO_SIDE_EFFECTS__
|
|
375
|
-
function chain(...args) {
|
|
376
|
-
const id = (a) => a;
|
|
377
|
-
const wrap = (a, b) => (c) => a(b(c));
|
|
378
|
-
const encode = args.map((x) => x.encode).reduceRight(wrap, id);
|
|
379
|
-
const decode = args.map((x) => x.decode).reduce(wrap, id);
|
|
380
|
-
return { encode, decode };
|
|
381
|
-
}
|
|
382
|
-
// @__NO_SIDE_EFFECTS__
|
|
383
|
-
function alphabet(letters) {
|
|
384
|
-
const lettersA = typeof letters === "string" ? letters.split("") : letters;
|
|
385
|
-
const len = lettersA.length;
|
|
386
|
-
astrArr("alphabet", lettersA);
|
|
387
|
-
const indexes = new Map(lettersA.map((l, i) => [l, i]));
|
|
388
|
-
return {
|
|
389
|
-
encode: (digits) => {
|
|
390
|
-
aArr(digits);
|
|
391
|
-
return digits.map((i) => {
|
|
392
|
-
if (!Number.isSafeInteger(i) || i < 0 || i >= len)
|
|
393
|
-
throw new Error(`alphabet.encode: digit index outside alphabet "${i}". Allowed: ${letters}`);
|
|
394
|
-
return lettersA[i];
|
|
395
|
-
});
|
|
396
|
-
},
|
|
397
|
-
decode: (input) => {
|
|
398
|
-
aArr(input);
|
|
399
|
-
return input.map((letter) => {
|
|
400
|
-
astr("alphabet.decode", letter);
|
|
401
|
-
const i = indexes.get(letter);
|
|
402
|
-
if (i === void 0)
|
|
403
|
-
throw new Error(`Unknown letter: "${letter}". Allowed: ${letters}`);
|
|
404
|
-
return i;
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
}
|
|
409
|
-
// @__NO_SIDE_EFFECTS__
|
|
410
|
-
function join(separator = "") {
|
|
411
|
-
astr("join", separator);
|
|
412
|
-
return {
|
|
413
|
-
encode: (from) => {
|
|
414
|
-
astrArr("join.decode", from);
|
|
415
|
-
return from.join(separator);
|
|
416
|
-
},
|
|
417
|
-
decode: (to) => {
|
|
418
|
-
astr("join.decode", to);
|
|
419
|
-
return to.split(separator);
|
|
420
|
-
}
|
|
421
|
-
};
|
|
422
|
-
}
|
|
423
|
-
function convertRadix(data, from, to) {
|
|
424
|
-
if (from < 2)
|
|
425
|
-
throw new Error(`convertRadix: invalid from=${from}, base cannot be less than 2`);
|
|
426
|
-
if (to < 2)
|
|
427
|
-
throw new Error(`convertRadix: invalid to=${to}, base cannot be less than 2`);
|
|
428
|
-
aArr(data);
|
|
429
|
-
if (!data.length)
|
|
430
|
-
return [];
|
|
431
|
-
let pos = 0;
|
|
432
|
-
const res = [];
|
|
433
|
-
const digits = Array.from(data, (d) => {
|
|
434
|
-
anumber(d);
|
|
435
|
-
if (d < 0 || d >= from)
|
|
436
|
-
throw new Error(`invalid integer: ${d}`);
|
|
437
|
-
return d;
|
|
438
|
-
});
|
|
439
|
-
const dlen = digits.length;
|
|
440
|
-
while (true) {
|
|
441
|
-
let carry = 0;
|
|
442
|
-
let done = true;
|
|
443
|
-
for (let i = pos; i < dlen; i++) {
|
|
444
|
-
const digit = digits[i];
|
|
445
|
-
const fromCarry = from * carry;
|
|
446
|
-
const digitBase = fromCarry + digit;
|
|
447
|
-
if (!Number.isSafeInteger(digitBase) || fromCarry / from !== carry || digitBase - digit !== fromCarry) {
|
|
448
|
-
throw new Error("convertRadix: carry overflow");
|
|
449
|
-
}
|
|
450
|
-
const div = digitBase / to;
|
|
451
|
-
carry = digitBase % to;
|
|
452
|
-
const rounded = Math.floor(div);
|
|
453
|
-
digits[i] = rounded;
|
|
454
|
-
if (!Number.isSafeInteger(rounded) || rounded * to + carry !== digitBase)
|
|
455
|
-
throw new Error("convertRadix: carry overflow");
|
|
456
|
-
if (!done)
|
|
457
|
-
continue;
|
|
458
|
-
else if (!rounded)
|
|
459
|
-
pos = i;
|
|
460
|
-
else
|
|
461
|
-
done = false;
|
|
462
|
-
}
|
|
463
|
-
res.push(carry);
|
|
464
|
-
if (done)
|
|
465
|
-
break;
|
|
466
|
-
}
|
|
467
|
-
for (let i = 0; i < data.length - 1 && data[i] === 0; i++)
|
|
468
|
-
res.push(0);
|
|
469
|
-
return res.reverse();
|
|
470
|
-
}
|
|
471
|
-
var gcd = (a, b) => b === 0 ? a : gcd(b, a % b);
|
|
472
|
-
var radix2carry = /* @__NO_SIDE_EFFECTS__ */ (from, to) => from + (to - gcd(from, to));
|
|
473
|
-
var powers = /* @__PURE__ */ (() => {
|
|
474
|
-
let res = [];
|
|
475
|
-
for (let i = 0; i < 40; i++)
|
|
476
|
-
res.push(2 ** i);
|
|
477
|
-
return res;
|
|
478
|
-
})();
|
|
479
|
-
function convertRadix2(data, from, to, padding) {
|
|
480
|
-
aArr(data);
|
|
481
|
-
if (from <= 0 || from > 32)
|
|
482
|
-
throw new Error(`convertRadix2: wrong from=${from}`);
|
|
483
|
-
if (to <= 0 || to > 32)
|
|
484
|
-
throw new Error(`convertRadix2: wrong to=${to}`);
|
|
485
|
-
if (/* @__PURE__ */ radix2carry(from, to) > 32) {
|
|
486
|
-
throw new Error(`convertRadix2: carry overflow from=${from} to=${to} carryBits=${/* @__PURE__ */ radix2carry(from, to)}`);
|
|
487
|
-
}
|
|
488
|
-
let carry = 0;
|
|
489
|
-
let pos = 0;
|
|
490
|
-
const max = powers[from];
|
|
491
|
-
const mask = powers[to] - 1;
|
|
492
|
-
const res = [];
|
|
493
|
-
for (const n of data) {
|
|
494
|
-
anumber(n);
|
|
495
|
-
if (n >= max)
|
|
496
|
-
throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
|
|
497
|
-
carry = carry << from | n;
|
|
498
|
-
if (pos + from > 32)
|
|
499
|
-
throw new Error(`convertRadix2: carry overflow pos=${pos} from=${from}`);
|
|
500
|
-
pos += from;
|
|
501
|
-
for (; pos >= to; pos -= to)
|
|
502
|
-
res.push((carry >> pos - to & mask) >>> 0);
|
|
503
|
-
const pow = powers[pos];
|
|
504
|
-
if (pow === void 0)
|
|
505
|
-
throw new Error("invalid carry");
|
|
506
|
-
carry &= pow - 1;
|
|
507
|
-
}
|
|
508
|
-
carry = carry << to - pos & mask;
|
|
509
|
-
if (!padding && pos >= from)
|
|
510
|
-
throw new Error("Excess padding");
|
|
511
|
-
if (!padding && carry > 0)
|
|
512
|
-
throw new Error(`Non-zero padding: ${carry}`);
|
|
513
|
-
if (padding && pos > 0)
|
|
514
|
-
res.push(carry >>> 0);
|
|
515
|
-
return res;
|
|
516
|
-
}
|
|
517
|
-
// @__NO_SIDE_EFFECTS__
|
|
518
|
-
function radix(num) {
|
|
519
|
-
anumber(num);
|
|
520
|
-
const _256 = 2 ** 8;
|
|
521
|
-
return {
|
|
522
|
-
encode: (bytes) => {
|
|
523
|
-
if (!isBytes(bytes))
|
|
524
|
-
throw new Error("radix.encode input should be Uint8Array");
|
|
525
|
-
return convertRadix(Array.from(bytes), _256, num);
|
|
526
|
-
},
|
|
527
|
-
decode: (digits) => {
|
|
528
|
-
anumArr("radix.decode", digits);
|
|
529
|
-
return Uint8Array.from(convertRadix(digits, num, _256));
|
|
530
|
-
}
|
|
531
|
-
};
|
|
532
|
-
}
|
|
533
|
-
// @__NO_SIDE_EFFECTS__
|
|
534
|
-
function radix2(bits, revPadding = false) {
|
|
535
|
-
anumber(bits);
|
|
536
|
-
if (/* @__PURE__ */ radix2carry(8, bits) > 32 || /* @__PURE__ */ radix2carry(bits, 8) > 32)
|
|
537
|
-
throw new Error("radix2: carry overflow");
|
|
538
|
-
return {
|
|
539
|
-
encode: (bytes) => {
|
|
540
|
-
if (!isBytes(bytes))
|
|
541
|
-
throw new Error("radix2.encode input should be Uint8Array");
|
|
542
|
-
return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
|
|
543
|
-
},
|
|
544
|
-
decode: (digits) => {
|
|
545
|
-
anumArr("radix2.decode", digits);
|
|
546
|
-
return Uint8Array.from(convertRadix2(digits, bits, 8, revPadding));
|
|
547
|
-
}
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function unsafeWrapper(fn) {
|
|
551
|
-
afn(fn);
|
|
552
|
-
return function(...args) {
|
|
553
|
-
try {
|
|
554
|
-
return fn.apply(null, args);
|
|
555
|
-
} catch (e) {
|
|
556
|
-
}
|
|
557
|
-
};
|
|
558
|
-
}
|
|
559
|
-
function checksum(len, fn) {
|
|
560
|
-
anumber(len);
|
|
561
|
-
afn(fn);
|
|
562
|
-
return {
|
|
563
|
-
encode(data) {
|
|
564
|
-
if (!isBytes(data))
|
|
565
|
-
throw new Error("checksum.encode: input should be Uint8Array");
|
|
566
|
-
const sum = fn(data).slice(0, len);
|
|
567
|
-
const res = new Uint8Array(data.length + len);
|
|
568
|
-
res.set(data);
|
|
569
|
-
res.set(sum, data.length);
|
|
570
|
-
return res;
|
|
571
|
-
},
|
|
572
|
-
decode(data) {
|
|
573
|
-
if (!isBytes(data))
|
|
574
|
-
throw new Error("checksum.decode: input should be Uint8Array");
|
|
575
|
-
const payload = data.slice(0, -len);
|
|
576
|
-
const oldChecksum = data.slice(-len);
|
|
577
|
-
const newChecksum = fn(payload).slice(0, len);
|
|
578
|
-
for (let i = 0; i < len; i++)
|
|
579
|
-
if (newChecksum[i] !== oldChecksum[i])
|
|
580
|
-
throw new Error("Invalid checksum");
|
|
581
|
-
return payload;
|
|
582
|
-
}
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
var genBase58 = /* @__NO_SIDE_EFFECTS__ */ (abc) => /* @__PURE__ */ chain(/* @__PURE__ */ radix(58), /* @__PURE__ */ alphabet(abc), /* @__PURE__ */ join(""));
|
|
586
|
-
var base58 = /* @__PURE__ */ genBase58("123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz");
|
|
587
|
-
var createBase58check = (sha2563) => /* @__PURE__ */ chain(checksum(4, (data) => sha2563(sha2563(data))), base58);
|
|
588
|
-
var base58check = createBase58check;
|
|
589
|
-
var BECH_ALPHABET = /* @__PURE__ */ chain(/* @__PURE__ */ alphabet("qpzry9x8gf2tvdw0s3jn54khce6mua7l"), /* @__PURE__ */ join(""));
|
|
590
|
-
var POLYMOD_GENERATORS = [996825010, 642813549, 513874426, 1027748829, 705979059];
|
|
591
|
-
function bech32Polymod(pre) {
|
|
592
|
-
const b = pre >> 25;
|
|
593
|
-
let chk = (pre & 33554431) << 5;
|
|
594
|
-
for (let i = 0; i < POLYMOD_GENERATORS.length; i++) {
|
|
595
|
-
if ((b >> i & 1) === 1)
|
|
596
|
-
chk ^= POLYMOD_GENERATORS[i];
|
|
597
|
-
}
|
|
598
|
-
return chk;
|
|
599
|
-
}
|
|
600
|
-
function bechChecksum(prefix, words, encodingConst = 1) {
|
|
601
|
-
const len = prefix.length;
|
|
602
|
-
let chk = 1;
|
|
603
|
-
for (let i = 0; i < len; i++) {
|
|
604
|
-
const c = prefix.charCodeAt(i);
|
|
605
|
-
if (c < 33 || c > 126)
|
|
606
|
-
throw new Error(`Invalid prefix (${prefix})`);
|
|
607
|
-
chk = bech32Polymod(chk) ^ c >> 5;
|
|
608
|
-
}
|
|
609
|
-
chk = bech32Polymod(chk);
|
|
610
|
-
for (let i = 0; i < len; i++)
|
|
611
|
-
chk = bech32Polymod(chk) ^ prefix.charCodeAt(i) & 31;
|
|
612
|
-
for (let v of words)
|
|
613
|
-
chk = bech32Polymod(chk) ^ v;
|
|
614
|
-
for (let i = 0; i < 6; i++)
|
|
615
|
-
chk = bech32Polymod(chk);
|
|
616
|
-
chk ^= encodingConst;
|
|
617
|
-
return BECH_ALPHABET.encode(convertRadix2([chk % powers[30]], 30, 5, false));
|
|
618
|
-
}
|
|
619
|
-
// @__NO_SIDE_EFFECTS__
|
|
620
|
-
function genBech32(encoding) {
|
|
621
|
-
const ENCODING_CONST = 1 ;
|
|
622
|
-
const _words = /* @__PURE__ */ radix2(5);
|
|
623
|
-
const fromWords = _words.decode;
|
|
624
|
-
const toWords = _words.encode;
|
|
625
|
-
const fromWordsUnsafe = unsafeWrapper(fromWords);
|
|
626
|
-
function encode(prefix, words, limit = 90) {
|
|
627
|
-
astr("bech32.encode prefix", prefix);
|
|
628
|
-
if (isBytes(words))
|
|
629
|
-
words = Array.from(words);
|
|
630
|
-
anumArr("bech32.encode", words);
|
|
631
|
-
const plen = prefix.length;
|
|
632
|
-
if (plen === 0)
|
|
633
|
-
throw new TypeError(`Invalid prefix length ${plen}`);
|
|
634
|
-
const actualLength = plen + 7 + words.length;
|
|
635
|
-
if (limit !== false && actualLength > limit)
|
|
636
|
-
throw new TypeError(`Length ${actualLength} exceeds limit ${limit}`);
|
|
637
|
-
const lowered = prefix.toLowerCase();
|
|
638
|
-
const sum = bechChecksum(lowered, words, ENCODING_CONST);
|
|
639
|
-
return `${lowered}1${BECH_ALPHABET.encode(words)}${sum}`;
|
|
640
|
-
}
|
|
641
|
-
function decode(str, limit = 90) {
|
|
642
|
-
astr("bech32.decode input", str);
|
|
643
|
-
const slen = str.length;
|
|
644
|
-
if (slen < 8 || limit !== false && slen > limit)
|
|
645
|
-
throw new TypeError(`invalid string length: ${slen} (${str}). Expected (8..${limit})`);
|
|
646
|
-
const lowered = str.toLowerCase();
|
|
647
|
-
if (str !== lowered && str !== str.toUpperCase())
|
|
648
|
-
throw new Error(`String must be lowercase or uppercase`);
|
|
649
|
-
const sepIndex = lowered.lastIndexOf("1");
|
|
650
|
-
if (sepIndex === 0 || sepIndex === -1)
|
|
651
|
-
throw new Error(`Letter "1" must be present between prefix and data only`);
|
|
652
|
-
const prefix = lowered.slice(0, sepIndex);
|
|
653
|
-
const data = lowered.slice(sepIndex + 1);
|
|
654
|
-
if (data.length < 6)
|
|
655
|
-
throw new Error("Data must be at least 6 characters long");
|
|
656
|
-
const words = BECH_ALPHABET.decode(data).slice(0, -6);
|
|
657
|
-
const sum = bechChecksum(prefix, words, ENCODING_CONST);
|
|
658
|
-
if (!data.endsWith(sum))
|
|
659
|
-
throw new Error(`Invalid checksum in ${str}: expected "${sum}"`);
|
|
660
|
-
return { prefix, words };
|
|
661
|
-
}
|
|
662
|
-
const decodeUnsafe = unsafeWrapper(decode);
|
|
663
|
-
function decodeToBytes(str) {
|
|
664
|
-
const { prefix, words } = decode(str, false);
|
|
665
|
-
return { prefix, words, bytes: fromWords(words) };
|
|
666
|
-
}
|
|
667
|
-
function encodeFromBytes(prefix, bytes) {
|
|
668
|
-
return encode(prefix, toWords(bytes));
|
|
669
|
-
}
|
|
670
|
-
return {
|
|
671
|
-
encode,
|
|
672
|
-
decode,
|
|
673
|
-
encodeFromBytes,
|
|
674
|
-
decodeToBytes,
|
|
675
|
-
decodeUnsafe,
|
|
676
|
-
fromWords,
|
|
677
|
-
fromWordsUnsafe,
|
|
678
|
-
toWords
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
var bech32 = /* @__PURE__ */ genBech32();
|
|
682
|
-
|
|
683
|
-
// node_modules/@scure/bip32/index.js
|
|
684
|
-
var Point = secp256k1_js.secp256k1.Point;
|
|
685
|
-
var { Fn } = Point;
|
|
686
|
-
var base58check2 = createBase58check(sha2_js.sha256);
|
|
687
|
-
var MASTER_SECRET = Uint8Array.from("Bitcoin seed".split(""), (char) => char.charCodeAt(0));
|
|
688
|
-
var BITCOIN_VERSIONS = { private: 76066276, public: 76067358 };
|
|
689
|
-
var HARDENED_OFFSET = 2147483648;
|
|
690
|
-
var hash160 = (data) => legacy_js.ripemd160(sha2_js.sha256(data));
|
|
691
|
-
var fromU32 = (data) => utils_js.createView(data).getUint32(0, false);
|
|
692
|
-
var toU32 = (n) => {
|
|
693
|
-
if (!Number.isSafeInteger(n) || n < 0 || n > 2 ** 32 - 1) {
|
|
694
|
-
throw new Error("invalid number, should be from 0 to 2**32-1, got " + n);
|
|
695
|
-
}
|
|
696
|
-
const buf = new Uint8Array(4);
|
|
697
|
-
utils_js.createView(buf).setUint32(0, n, false);
|
|
698
|
-
return buf;
|
|
699
|
-
};
|
|
700
|
-
var HDKey = class _HDKey {
|
|
701
|
-
get fingerprint() {
|
|
702
|
-
if (!this.pubHash) {
|
|
703
|
-
throw new Error("No publicKey set!");
|
|
704
|
-
}
|
|
705
|
-
return fromU32(this.pubHash);
|
|
706
|
-
}
|
|
707
|
-
get identifier() {
|
|
708
|
-
return this.pubHash;
|
|
709
|
-
}
|
|
710
|
-
get pubKeyHash() {
|
|
711
|
-
return this.pubHash;
|
|
712
|
-
}
|
|
713
|
-
get privateKey() {
|
|
714
|
-
return this._privateKey || null;
|
|
715
|
-
}
|
|
716
|
-
get publicKey() {
|
|
717
|
-
return this._publicKey || null;
|
|
718
|
-
}
|
|
719
|
-
get privateExtendedKey() {
|
|
720
|
-
const priv = this._privateKey;
|
|
721
|
-
if (!priv) {
|
|
722
|
-
throw new Error("No private key");
|
|
723
|
-
}
|
|
724
|
-
return base58check2.encode(this.serialize(this.versions.private, utils_js.concatBytes(Uint8Array.of(0), priv)));
|
|
725
|
-
}
|
|
726
|
-
get publicExtendedKey() {
|
|
727
|
-
if (!this._publicKey) {
|
|
728
|
-
throw new Error("No public key");
|
|
729
|
-
}
|
|
730
|
-
return base58check2.encode(this.serialize(this.versions.public, this._publicKey));
|
|
731
|
-
}
|
|
732
|
-
static fromMasterSeed(seed, versions = BITCOIN_VERSIONS) {
|
|
733
|
-
utils_js.abytes(seed);
|
|
734
|
-
if (8 * seed.length < 128 || 8 * seed.length > 512) {
|
|
735
|
-
throw new Error("HDKey: seed length must be between 128 and 512 bits; 256 bits is advised, got " + seed.length);
|
|
736
|
-
}
|
|
737
|
-
const I = hmac_js.hmac(sha2_js.sha512, MASTER_SECRET, seed);
|
|
738
|
-
const privateKey = I.slice(0, 32);
|
|
739
|
-
const chainCode = I.slice(32);
|
|
740
|
-
return new _HDKey({ versions, chainCode, privateKey });
|
|
741
|
-
}
|
|
742
|
-
static fromExtendedKey(base58key, versions = BITCOIN_VERSIONS) {
|
|
743
|
-
const keyBuffer = base58check2.decode(base58key);
|
|
744
|
-
const keyView = utils_js.createView(keyBuffer);
|
|
745
|
-
const version = keyView.getUint32(0, false);
|
|
746
|
-
const opt = {
|
|
747
|
-
versions,
|
|
748
|
-
depth: keyBuffer[4],
|
|
749
|
-
parentFingerprint: keyView.getUint32(5, false),
|
|
750
|
-
index: keyView.getUint32(9, false),
|
|
751
|
-
chainCode: keyBuffer.slice(13, 45)
|
|
752
|
-
};
|
|
753
|
-
const key = keyBuffer.slice(45);
|
|
754
|
-
const isPriv = key[0] === 0;
|
|
755
|
-
if (version !== versions[isPriv ? "private" : "public"]) {
|
|
756
|
-
throw new Error("Version mismatch");
|
|
757
|
-
}
|
|
758
|
-
if (isPriv) {
|
|
759
|
-
return new _HDKey({ ...opt, privateKey: key.slice(1) });
|
|
760
|
-
} else {
|
|
761
|
-
return new _HDKey({ ...opt, publicKey: key });
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
static fromJSON(json) {
|
|
765
|
-
return _HDKey.fromExtendedKey(json.xpriv);
|
|
766
|
-
}
|
|
767
|
-
versions;
|
|
768
|
-
depth = 0;
|
|
769
|
-
index = 0;
|
|
770
|
-
chainCode = null;
|
|
771
|
-
parentFingerprint = 0;
|
|
772
|
-
_privateKey;
|
|
773
|
-
_publicKey;
|
|
774
|
-
pubHash;
|
|
775
|
-
constructor(opt) {
|
|
776
|
-
if (!opt || typeof opt !== "object") {
|
|
777
|
-
throw new Error("HDKey.constructor must not be called directly");
|
|
778
|
-
}
|
|
779
|
-
this.versions = opt.versions || BITCOIN_VERSIONS;
|
|
780
|
-
this.depth = opt.depth || 0;
|
|
781
|
-
this.chainCode = opt.chainCode || null;
|
|
782
|
-
this.index = opt.index || 0;
|
|
783
|
-
this.parentFingerprint = opt.parentFingerprint || 0;
|
|
784
|
-
if (!this.depth) {
|
|
785
|
-
if (this.parentFingerprint || this.index) {
|
|
786
|
-
throw new Error("HDKey: zero depth with non-zero index/parent fingerprint");
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
if (this.depth > 255) {
|
|
790
|
-
throw new Error("HDKey: depth exceeds the serializable value 255");
|
|
791
|
-
}
|
|
792
|
-
if (opt.publicKey && opt.privateKey) {
|
|
793
|
-
throw new Error("HDKey: publicKey and privateKey at same time.");
|
|
794
|
-
}
|
|
795
|
-
if (opt.privateKey) {
|
|
796
|
-
if (!secp256k1_js.secp256k1.utils.isValidSecretKey(opt.privateKey))
|
|
797
|
-
throw new Error("Invalid private key");
|
|
798
|
-
this._privateKey = opt.privateKey;
|
|
799
|
-
this._publicKey = secp256k1_js.secp256k1.getPublicKey(opt.privateKey, true);
|
|
800
|
-
} else if (opt.publicKey) {
|
|
801
|
-
this._publicKey = Point.fromBytes(opt.publicKey).toBytes(true);
|
|
802
|
-
} else {
|
|
803
|
-
throw new Error("HDKey: no public or private key provided");
|
|
804
|
-
}
|
|
805
|
-
this.pubHash = hash160(this._publicKey);
|
|
806
|
-
}
|
|
807
|
-
derive(path) {
|
|
808
|
-
if (!/^[mM]'?/.test(path)) {
|
|
809
|
-
throw new Error('Path must start with "m" or "M"');
|
|
810
|
-
}
|
|
811
|
-
if (/^[mM]'?$/.test(path)) {
|
|
812
|
-
return this;
|
|
813
|
-
}
|
|
814
|
-
const parts = path.replace(/^[mM]'?\//, "").split("/");
|
|
815
|
-
let child = this;
|
|
816
|
-
for (const c of parts) {
|
|
817
|
-
const m = /^(\d+)('?)$/.exec(c);
|
|
818
|
-
const m1 = m && m[1];
|
|
819
|
-
if (!m || m.length !== 3 || typeof m1 !== "string")
|
|
820
|
-
throw new Error("invalid child index: " + c);
|
|
821
|
-
let idx = +m1;
|
|
822
|
-
if (!Number.isSafeInteger(idx) || idx >= HARDENED_OFFSET) {
|
|
823
|
-
throw new Error("Invalid index");
|
|
824
|
-
}
|
|
825
|
-
if (m[2] === "'") {
|
|
826
|
-
idx += HARDENED_OFFSET;
|
|
827
|
-
}
|
|
828
|
-
child = child.deriveChild(idx);
|
|
829
|
-
}
|
|
830
|
-
return child;
|
|
831
|
-
}
|
|
832
|
-
deriveChild(index) {
|
|
833
|
-
if (!this._publicKey || !this.chainCode) {
|
|
834
|
-
throw new Error("No publicKey or chainCode set");
|
|
835
|
-
}
|
|
836
|
-
let data = toU32(index);
|
|
837
|
-
if (index >= HARDENED_OFFSET) {
|
|
838
|
-
const priv = this._privateKey;
|
|
839
|
-
if (!priv) {
|
|
840
|
-
throw new Error("Could not derive hardened child key");
|
|
841
|
-
}
|
|
842
|
-
data = utils_js.concatBytes(Uint8Array.of(0), priv, data);
|
|
843
|
-
} else {
|
|
844
|
-
data = utils_js.concatBytes(this._publicKey, data);
|
|
845
|
-
}
|
|
846
|
-
const I = hmac_js.hmac(sha2_js.sha512, this.chainCode, data);
|
|
847
|
-
const childTweak = I.slice(0, 32);
|
|
848
|
-
const chainCode = I.slice(32);
|
|
849
|
-
if (!secp256k1_js.secp256k1.utils.isValidSecretKey(childTweak)) {
|
|
850
|
-
throw new Error("Tweak bigger than curve order");
|
|
851
|
-
}
|
|
852
|
-
const opt = {
|
|
853
|
-
versions: this.versions,
|
|
854
|
-
chainCode,
|
|
855
|
-
depth: this.depth + 1,
|
|
856
|
-
parentFingerprint: this.fingerprint,
|
|
857
|
-
index
|
|
858
|
-
};
|
|
859
|
-
const ctweak = Fn.fromBytes(childTweak);
|
|
860
|
-
try {
|
|
861
|
-
if (this._privateKey) {
|
|
862
|
-
const added = Fn.create(Fn.fromBytes(this._privateKey) + ctweak);
|
|
863
|
-
if (!Fn.isValidNot0(added)) {
|
|
864
|
-
throw new Error("The tweak was out of range or the resulted private key is invalid");
|
|
865
|
-
}
|
|
866
|
-
opt.privateKey = Fn.toBytes(added);
|
|
867
|
-
} else {
|
|
868
|
-
const added = Point.fromBytes(this._publicKey).add(Point.BASE.multiply(ctweak));
|
|
869
|
-
if (added.equals(Point.ZERO)) {
|
|
870
|
-
throw new Error("The tweak was equal to negative P, which made the result key invalid");
|
|
871
|
-
}
|
|
872
|
-
opt.publicKey = added.toBytes(true);
|
|
873
|
-
}
|
|
874
|
-
return new _HDKey(opt);
|
|
875
|
-
} catch (err) {
|
|
876
|
-
return this.deriveChild(index + 1);
|
|
877
|
-
}
|
|
878
|
-
}
|
|
879
|
-
sign(hash) {
|
|
880
|
-
if (!this._privateKey) {
|
|
881
|
-
throw new Error("No privateKey set!");
|
|
882
|
-
}
|
|
883
|
-
utils_js.abytes(hash, 32);
|
|
884
|
-
return secp256k1_js.secp256k1.sign(hash, this._privateKey, { prehash: false });
|
|
885
|
-
}
|
|
886
|
-
verify(hash, signature) {
|
|
887
|
-
utils_js.abytes(hash, 32);
|
|
888
|
-
utils_js.abytes(signature, 64);
|
|
889
|
-
if (!this._publicKey) {
|
|
890
|
-
throw new Error("No publicKey set!");
|
|
891
|
-
}
|
|
892
|
-
return secp256k1_js.secp256k1.verify(signature, hash, this._publicKey, { prehash: false });
|
|
893
|
-
}
|
|
894
|
-
wipePrivateData() {
|
|
895
|
-
if (this._privateKey) {
|
|
896
|
-
this._privateKey.fill(0);
|
|
897
|
-
this._privateKey = void 0;
|
|
898
|
-
}
|
|
899
|
-
return this;
|
|
900
|
-
}
|
|
901
|
-
toJSON() {
|
|
902
|
-
return {
|
|
903
|
-
xpriv: this.privateExtendedKey,
|
|
904
|
-
xpub: this.publicExtendedKey
|
|
905
|
-
};
|
|
906
|
-
}
|
|
907
|
-
serialize(version, key) {
|
|
908
|
-
if (!this.chainCode) {
|
|
909
|
-
throw new Error("No chainCode set");
|
|
910
|
-
}
|
|
911
|
-
utils_js.abytes(key, 33);
|
|
912
|
-
return utils_js.concatBytes(toU32(version), new Uint8Array([this.depth]), toU32(this.parentFingerprint), toU32(this.index), this.chainCode, key);
|
|
913
|
-
}
|
|
914
|
-
};
|
|
915
329
|
var DERIVATION_PATHS2 = {
|
|
916
330
|
ethereum: "m/44'/60'/0'/0/0",
|
|
917
331
|
bitcoin_mainnet: "m/84'/0'/0'/0/0",
|
|
@@ -928,7 +342,7 @@ function deriveEthereumAddress(seed) {
|
|
|
928
342
|
function deriveBitcoinAddress(seed, network = "mainnet") {
|
|
929
343
|
try {
|
|
930
344
|
const seedBytes = bip39.mnemonicToSeedSync(seed);
|
|
931
|
-
const hdKey = HDKey.fromMasterSeed(seedBytes);
|
|
345
|
+
const hdKey = bip32.HDKey.fromMasterSeed(seedBytes);
|
|
932
346
|
const path = network === "testnet" ? DERIVATION_PATHS2.bitcoin_testnet : DERIVATION_PATHS2.bitcoin_mainnet;
|
|
933
347
|
const child = hdKey.derive(path);
|
|
934
348
|
if (!child.publicKey) {
|
|
@@ -936,10 +350,10 @@ function deriveBitcoinAddress(seed, network = "mainnet") {
|
|
|
936
350
|
}
|
|
937
351
|
const pubKeyHash = ripemd160.ripemd160(sha256.sha256(child.publicKey));
|
|
938
352
|
const witnessVersion = 0;
|
|
939
|
-
const words = bech32.toWords(pubKeyHash);
|
|
353
|
+
const words = base.bech32.toWords(pubKeyHash);
|
|
940
354
|
words.unshift(witnessVersion);
|
|
941
355
|
const hrp = network === "testnet" ? "tb" : "bc";
|
|
942
|
-
const address = bech32.encode(hrp, words);
|
|
356
|
+
const address = base.bech32.encode(hrp, words);
|
|
943
357
|
return address;
|
|
944
358
|
} catch (error) {
|
|
945
359
|
console.error("Bitcoin address derivation failed:", error);
|
|
@@ -1012,7 +426,7 @@ function deriveTronAddress(seed) {
|
|
|
1012
426
|
for (let i = 0; i < 20; i++) {
|
|
1013
427
|
addressBytes[i + 1] = parseInt(ethAddressHex.slice(i * 2, i * 2 + 2), 16);
|
|
1014
428
|
}
|
|
1015
|
-
const tronBase58check = base58check(sha256.sha256);
|
|
429
|
+
const tronBase58check = base.base58check(sha256.sha256);
|
|
1016
430
|
return tronBase58check.encode(addressBytes);
|
|
1017
431
|
} catch (error) {
|
|
1018
432
|
console.error("TRON address derivation failed:", error);
|
|
@@ -1022,17 +436,17 @@ function deriveTronAddress(seed) {
|
|
|
1022
436
|
function deriveSparkAddress(seed, network = "mainnet") {
|
|
1023
437
|
try {
|
|
1024
438
|
const seedBytes = bip39.mnemonicToSeedSync(seed);
|
|
1025
|
-
const hdKey = HDKey.fromMasterSeed(seedBytes);
|
|
439
|
+
const hdKey = bip32.HDKey.fromMasterSeed(seedBytes);
|
|
1026
440
|
const child = hdKey.derive(DERIVATION_PATHS2.spark);
|
|
1027
441
|
if (!child.publicKey) {
|
|
1028
442
|
throw new Error("Failed to derive public key");
|
|
1029
443
|
}
|
|
1030
444
|
const pubKeyHash = ripemd160.ripemd160(sha256.sha256(child.publicKey));
|
|
1031
445
|
const witnessVersion = 0;
|
|
1032
|
-
const words = bech32.toWords(pubKeyHash);
|
|
446
|
+
const words = base.bech32.toWords(pubKeyHash);
|
|
1033
447
|
words.unshift(witnessVersion);
|
|
1034
448
|
const hrp = network === "testnet" ? "tsp" : "sp";
|
|
1035
|
-
const address = bech32.encode(hrp, words);
|
|
449
|
+
const address = base.bech32.encode(hrp, words);
|
|
1036
450
|
return address;
|
|
1037
451
|
} catch (error) {
|
|
1038
452
|
console.error("Spark address derivation failed:", error);
|
|
@@ -1128,9 +542,9 @@ var CHAIN_ERROR_MESSAGES = {
|
|
|
1128
542
|
"no route": "NETWORK_ERROR"
|
|
1129
543
|
}
|
|
1130
544
|
};
|
|
1131
|
-
function parseChainError(
|
|
545
|
+
function parseChainError(chain, errorMessage) {
|
|
1132
546
|
const errorLower = errorMessage.toLowerCase();
|
|
1133
|
-
const chainErrors = CHAIN_ERROR_MESSAGES[
|
|
547
|
+
const chainErrors = CHAIN_ERROR_MESSAGES[chain];
|
|
1134
548
|
for (const [pattern, code] of Object.entries(chainErrors)) {
|
|
1135
549
|
if (errorLower.includes(pattern)) {
|
|
1136
550
|
return code;
|
|
@@ -1268,38 +682,38 @@ var ZubariWdkService = class {
|
|
|
1268
682
|
* For Ethereum, falls back to local derivation if API fails.
|
|
1269
683
|
* For other chains, WDK API is required - no placeholder fallback.
|
|
1270
684
|
*/
|
|
1271
|
-
async deriveAddress(seed,
|
|
685
|
+
async deriveAddress(seed, chain) {
|
|
1272
686
|
await this.initialize();
|
|
1273
|
-
const path = this.getDerivationPath(
|
|
687
|
+
const path = this.getDerivationPath(chain);
|
|
1274
688
|
try {
|
|
1275
|
-
const response = await this.apiClient.deriveAddress(seed,
|
|
689
|
+
const response = await this.apiClient.deriveAddress(seed, chain, this.config.network);
|
|
1276
690
|
if (response.success && response.address) {
|
|
1277
691
|
return {
|
|
1278
|
-
chain
|
|
692
|
+
chain,
|
|
1279
693
|
address: response.address,
|
|
1280
694
|
path: response.path || path
|
|
1281
695
|
};
|
|
1282
696
|
}
|
|
1283
697
|
} catch (error) {
|
|
1284
|
-
console.warn(`API address derivation failed for ${
|
|
1285
|
-
if (
|
|
1286
|
-
return this.deriveBrowserAddress(seed,
|
|
698
|
+
console.warn(`API address derivation failed for ${chain}:`, error);
|
|
699
|
+
if (chain === "ethereum") {
|
|
700
|
+
return this.deriveBrowserAddress(seed, chain);
|
|
1287
701
|
}
|
|
1288
702
|
}
|
|
1289
703
|
if (this.useNativeWdk && this.nativeWdkService) {
|
|
1290
704
|
try {
|
|
1291
705
|
const wdk = this.nativeWdkService;
|
|
1292
706
|
await wdk.initialize(seed);
|
|
1293
|
-
return await wdk.deriveAddress(
|
|
707
|
+
return await wdk.deriveAddress(chain);
|
|
1294
708
|
} catch (error) {
|
|
1295
|
-
console.warn(`Native WDK address derivation failed for ${
|
|
709
|
+
console.warn(`Native WDK address derivation failed for ${chain}:`, error);
|
|
1296
710
|
}
|
|
1297
711
|
}
|
|
1298
|
-
if (
|
|
1299
|
-
return this.deriveBrowserAddress(seed,
|
|
712
|
+
if (chain === "ethereum") {
|
|
713
|
+
return this.deriveBrowserAddress(seed, chain);
|
|
1300
714
|
}
|
|
1301
715
|
throw new Error(
|
|
1302
|
-
`WDK API required for ${
|
|
716
|
+
`WDK API required for ${chain} address derivation. Ensure the backend is running.`
|
|
1303
717
|
);
|
|
1304
718
|
}
|
|
1305
719
|
/**
|
|
@@ -1379,13 +793,13 @@ var ZubariWdkService = class {
|
|
|
1379
793
|
/**
|
|
1380
794
|
* Get fee rates for a chain
|
|
1381
795
|
*/
|
|
1382
|
-
async getFeeRates(seed,
|
|
796
|
+
async getFeeRates(seed, chain) {
|
|
1383
797
|
await this.initialize();
|
|
1384
798
|
try {
|
|
1385
799
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/fee-rates`, {
|
|
1386
800
|
method: "POST",
|
|
1387
801
|
headers: { "Content-Type": "application/json" },
|
|
1388
|
-
body: JSON.stringify({ seed, chain
|
|
802
|
+
body: JSON.stringify({ seed, chain, network: this.config.network })
|
|
1389
803
|
});
|
|
1390
804
|
if (response.ok) {
|
|
1391
805
|
const data = await response.json();
|
|
@@ -1394,20 +808,20 @@ var ZubariWdkService = class {
|
|
|
1394
808
|
}
|
|
1395
809
|
}
|
|
1396
810
|
} catch (error) {
|
|
1397
|
-
console.warn(`Failed to fetch fee rates for ${
|
|
811
|
+
console.warn(`Failed to fetch fee rates for ${chain}:`, error);
|
|
1398
812
|
}
|
|
1399
813
|
return { slow: "0", normal: "0", fast: "0" };
|
|
1400
814
|
}
|
|
1401
815
|
/**
|
|
1402
816
|
* Estimate transaction fee
|
|
1403
817
|
*/
|
|
1404
|
-
async estimateFee(seed,
|
|
818
|
+
async estimateFee(seed, chain, to, amount) {
|
|
1405
819
|
await this.initialize();
|
|
1406
820
|
try {
|
|
1407
821
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/estimate-fee`, {
|
|
1408
822
|
method: "POST",
|
|
1409
823
|
headers: { "Content-Type": "application/json" },
|
|
1410
|
-
body: JSON.stringify({ seed, chain
|
|
824
|
+
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1411
825
|
});
|
|
1412
826
|
if (response.ok) {
|
|
1413
827
|
const data = await response.json();
|
|
@@ -1416,9 +830,9 @@ var ZubariWdkService = class {
|
|
|
1416
830
|
}
|
|
1417
831
|
}
|
|
1418
832
|
} catch (error) {
|
|
1419
|
-
console.warn(`Failed to estimate fee for ${
|
|
833
|
+
console.warn(`Failed to estimate fee for ${chain}:`, error);
|
|
1420
834
|
}
|
|
1421
|
-
return { fee: "0", symbol: this.getChainSymbol(
|
|
835
|
+
return { fee: "0", symbol: this.getChainSymbol(chain) };
|
|
1422
836
|
}
|
|
1423
837
|
/**
|
|
1424
838
|
* Send a transaction on any supported chain
|
|
@@ -1429,10 +843,10 @@ var ZubariWdkService = class {
|
|
|
1429
843
|
* @param amount - Amount to send (in native units: ETH, BTC, SOL, etc.)
|
|
1430
844
|
* @returns Transaction result with hash on success, or error details on failure
|
|
1431
845
|
*/
|
|
1432
|
-
async sendTransaction(seed,
|
|
846
|
+
async sendTransaction(seed, chain, to, amount) {
|
|
1433
847
|
await this.initialize();
|
|
1434
848
|
const startTime = Date.now();
|
|
1435
|
-
console.log(`[ZubariWdkService] Sending ${
|
|
849
|
+
console.log(`[ZubariWdkService] Sending ${chain} transaction`, {
|
|
1436
850
|
to: `${to.slice(0, 10)}...${to.slice(-6)}`,
|
|
1437
851
|
amount,
|
|
1438
852
|
network: this.config.network
|
|
@@ -1441,7 +855,7 @@ var ZubariWdkService = class {
|
|
|
1441
855
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/send`, {
|
|
1442
856
|
method: "POST",
|
|
1443
857
|
headers: { "Content-Type": "application/json" },
|
|
1444
|
-
body: JSON.stringify({ seed, chain
|
|
858
|
+
body: JSON.stringify({ seed, chain, to, amount, network: this.config.network })
|
|
1445
859
|
});
|
|
1446
860
|
const elapsed = Date.now() - startTime;
|
|
1447
861
|
if (response.ok) {
|
|
@@ -1451,22 +865,22 @@ var ZubariWdkService = class {
|
|
|
1451
865
|
txHash = txHash.hash;
|
|
1452
866
|
}
|
|
1453
867
|
if (txHash) {
|
|
1454
|
-
const isValid = this.validateTxHash(
|
|
868
|
+
const isValid = this.validateTxHash(chain, txHash);
|
|
1455
869
|
if (!isValid) {
|
|
1456
|
-
console.warn(`[ZubariWdkService] Invalid ${
|
|
870
|
+
console.warn(`[ZubariWdkService] Invalid ${chain} tx hash format:`, txHash);
|
|
1457
871
|
}
|
|
1458
872
|
}
|
|
1459
|
-
console.log(`[ZubariWdkService] ${
|
|
873
|
+
console.log(`[ZubariWdkService] ${chain} transaction ${data.success ? "SUCCESS" : "FAILED"}`, {
|
|
1460
874
|
txHash: txHash ? `${txHash.slice(0, 16)}...` : "N/A",
|
|
1461
875
|
elapsed: `${elapsed}ms`
|
|
1462
876
|
});
|
|
1463
877
|
if (!data.success) {
|
|
1464
|
-
const errorCode2 = parseChainError(
|
|
878
|
+
const errorCode2 = parseChainError(chain, data.error || "");
|
|
1465
879
|
return {
|
|
1466
880
|
success: false,
|
|
1467
881
|
error: data.error,
|
|
1468
882
|
errorCode: errorCode2,
|
|
1469
|
-
chain
|
|
883
|
+
chain
|
|
1470
884
|
};
|
|
1471
885
|
}
|
|
1472
886
|
return {
|
|
@@ -1475,14 +889,14 @@ var ZubariWdkService = class {
|
|
|
1475
889
|
from: data.from,
|
|
1476
890
|
to: data.to,
|
|
1477
891
|
amount: data.amount,
|
|
1478
|
-
chain: data.chain ||
|
|
892
|
+
chain: data.chain || chain,
|
|
1479
893
|
network: data.network || this.config.network
|
|
1480
894
|
};
|
|
1481
895
|
}
|
|
1482
896
|
const errorData = await response.json().catch(() => ({}));
|
|
1483
897
|
const errorMessage = errorData.error || `HTTP ${response.status}`;
|
|
1484
|
-
const errorCode = parseChainError(
|
|
1485
|
-
console.error(`[ZubariWdkService] ${
|
|
898
|
+
const errorCode = parseChainError(chain, errorMessage);
|
|
899
|
+
console.error(`[ZubariWdkService] ${chain} transaction FAILED`, {
|
|
1486
900
|
status: response.status,
|
|
1487
901
|
error: errorMessage,
|
|
1488
902
|
errorCode,
|
|
@@ -1492,13 +906,13 @@ var ZubariWdkService = class {
|
|
|
1492
906
|
success: false,
|
|
1493
907
|
error: errorMessage,
|
|
1494
908
|
errorCode,
|
|
1495
|
-
chain
|
|
909
|
+
chain
|
|
1496
910
|
};
|
|
1497
911
|
} catch (error) {
|
|
1498
912
|
const elapsed = Date.now() - startTime;
|
|
1499
913
|
const errorMessage = error instanceof Error ? error.message : "Transaction failed";
|
|
1500
|
-
const errorCode = parseChainError(
|
|
1501
|
-
console.error(`[ZubariWdkService] ${
|
|
914
|
+
const errorCode = parseChainError(chain, errorMessage);
|
|
915
|
+
console.error(`[ZubariWdkService] ${chain} transaction ERROR`, {
|
|
1502
916
|
error: errorMessage,
|
|
1503
917
|
errorCode,
|
|
1504
918
|
elapsed: `${elapsed}ms`
|
|
@@ -1507,15 +921,15 @@ var ZubariWdkService = class {
|
|
|
1507
921
|
success: false,
|
|
1508
922
|
error: errorMessage,
|
|
1509
923
|
errorCode,
|
|
1510
|
-
chain
|
|
924
|
+
chain
|
|
1511
925
|
};
|
|
1512
926
|
}
|
|
1513
927
|
}
|
|
1514
928
|
/**
|
|
1515
929
|
* Validate transaction hash format for a specific chain
|
|
1516
930
|
*/
|
|
1517
|
-
validateTxHash(
|
|
1518
|
-
switch (
|
|
931
|
+
validateTxHash(chain, txHash) {
|
|
932
|
+
switch (chain) {
|
|
1519
933
|
case "ethereum":
|
|
1520
934
|
return /^0x[a-fA-F0-9]{64}$/.test(txHash);
|
|
1521
935
|
case "bitcoin":
|
|
@@ -1547,7 +961,7 @@ var ZubariWdkService = class {
|
|
|
1547
961
|
// ==========================================
|
|
1548
962
|
// Private Helper Methods
|
|
1549
963
|
// ==========================================
|
|
1550
|
-
getDerivationPath(
|
|
964
|
+
getDerivationPath(chain) {
|
|
1551
965
|
const paths = {
|
|
1552
966
|
bitcoin: this.config.network === "testnet" ? "m/84'/1'/0'/0/0" : "m/84'/0'/0'/0/0",
|
|
1553
967
|
ethereum: "m/44'/60'/0'/0/0",
|
|
@@ -1556,9 +970,9 @@ var ZubariWdkService = class {
|
|
|
1556
970
|
solana: "m/44'/501'/0'/0'",
|
|
1557
971
|
spark: "m/44'/998'/0'/0/0"
|
|
1558
972
|
};
|
|
1559
|
-
return paths[
|
|
973
|
+
return paths[chain];
|
|
1560
974
|
}
|
|
1561
|
-
getChainSymbol(
|
|
975
|
+
getChainSymbol(chain) {
|
|
1562
976
|
const symbols = {
|
|
1563
977
|
ethereum: "ETH",
|
|
1564
978
|
bitcoin: "BTC",
|
|
@@ -1567,16 +981,16 @@ var ZubariWdkService = class {
|
|
|
1567
981
|
solana: "SOL",
|
|
1568
982
|
spark: "SAT"
|
|
1569
983
|
};
|
|
1570
|
-
return symbols[
|
|
984
|
+
return symbols[chain];
|
|
1571
985
|
}
|
|
1572
986
|
/**
|
|
1573
987
|
* Derive address using browser-compatible libraries
|
|
1574
988
|
*/
|
|
1575
|
-
async deriveBrowserAddress(seed,
|
|
1576
|
-
const path = this.getDerivationPath(
|
|
989
|
+
async deriveBrowserAddress(seed, chain) {
|
|
990
|
+
const path = this.getDerivationPath(chain);
|
|
1577
991
|
try {
|
|
1578
992
|
let address;
|
|
1579
|
-
switch (
|
|
993
|
+
switch (chain) {
|
|
1580
994
|
case "ethereum":
|
|
1581
995
|
address = deriveEthereumAddress(seed);
|
|
1582
996
|
break;
|
|
@@ -1596,11 +1010,11 @@ var ZubariWdkService = class {
|
|
|
1596
1010
|
address = await deriveTonAddress(seed);
|
|
1597
1011
|
break;
|
|
1598
1012
|
default:
|
|
1599
|
-
throw new Error(`Unsupported chain: ${
|
|
1013
|
+
throw new Error(`Unsupported chain: ${chain}`);
|
|
1600
1014
|
}
|
|
1601
|
-
return { chain
|
|
1015
|
+
return { chain, address, path };
|
|
1602
1016
|
} catch (error) {
|
|
1603
|
-
console.error(`Browser derivation failed for ${
|
|
1017
|
+
console.error(`Browser derivation failed for ${chain}:`, error);
|
|
1604
1018
|
throw error;
|
|
1605
1019
|
}
|
|
1606
1020
|
}
|
|
@@ -1613,7 +1027,7 @@ var ZubariWdkService = class {
|
|
|
1613
1027
|
};
|
|
1614
1028
|
var defaultService = null;
|
|
1615
1029
|
function getZubariWdkService(config) {
|
|
1616
|
-
if (!defaultService || config && config.network !== defaultService.getNetwork()) {
|
|
1030
|
+
if (!defaultService || config && (config.network !== defaultService.getNetwork() || config.apiUrl && config.apiUrl !== defaultService.getApiUrl())) {
|
|
1617
1031
|
defaultService = new ZubariWdkService(config);
|
|
1618
1032
|
}
|
|
1619
1033
|
return defaultService;
|
|
@@ -2002,8 +1416,8 @@ async function fetchPrices() {
|
|
|
2002
1416
|
if (response.ok) {
|
|
2003
1417
|
const data = await response.json();
|
|
2004
1418
|
const prices = {};
|
|
2005
|
-
for (const [
|
|
2006
|
-
prices[
|
|
1419
|
+
for (const [chain, geckoId] of Object.entries(COINGECKO_IDS)) {
|
|
1420
|
+
prices[chain] = data[geckoId]?.usd || 0;
|
|
2007
1421
|
}
|
|
2008
1422
|
priceCache = { prices, timestamp: Date.now() };
|
|
2009
1423
|
return prices;
|
|
@@ -2013,9 +1427,22 @@ async function fetchPrices() {
|
|
|
2013
1427
|
}
|
|
2014
1428
|
return priceCache?.prices || {};
|
|
2015
1429
|
}
|
|
2016
|
-
async function getPriceForChain(
|
|
1430
|
+
async function getPriceForChain(chain) {
|
|
2017
1431
|
const prices = await fetchPrices();
|
|
2018
|
-
return prices[
|
|
1432
|
+
return prices[chain] || 0;
|
|
1433
|
+
}
|
|
1434
|
+
function tonFriendlyToRaw(addr) {
|
|
1435
|
+
if (addr.includes(":")) return addr;
|
|
1436
|
+
try {
|
|
1437
|
+
const b64 = addr.replace(/-/g, "+").replace(/_/g, "/");
|
|
1438
|
+
const bytes = Uint8Array.from(atob(b64), (c) => c.charCodeAt(0));
|
|
1439
|
+
if (bytes.length !== 36) return addr;
|
|
1440
|
+
const workchain = bytes[1] === 255 ? -1 : bytes[1];
|
|
1441
|
+
const hash = Array.from(bytes.slice(2, 34)).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1442
|
+
return `${workchain}:${hash}`;
|
|
1443
|
+
} catch {
|
|
1444
|
+
return addr;
|
|
1445
|
+
}
|
|
2019
1446
|
}
|
|
2020
1447
|
var STORAGE_KEYS = {
|
|
2021
1448
|
ENCRYPTED_SEED: "encrypted_seed",
|
|
@@ -2221,9 +1648,9 @@ var WalletManager = class _WalletManager {
|
|
|
2221
1648
|
if (!this.derivedAddress) {
|
|
2222
1649
|
throw new Error("Wallet not initialized");
|
|
2223
1650
|
}
|
|
2224
|
-
const
|
|
1651
|
+
const chain = this.config.network === "mainnet" ? chains.mainnet : chains.sepolia;
|
|
2225
1652
|
const client = viem.createPublicClient({
|
|
2226
|
-
chain
|
|
1653
|
+
chain,
|
|
2227
1654
|
transport: viem.http(this.config.rpcUrl, {
|
|
2228
1655
|
timeout: 15e3,
|
|
2229
1656
|
// 15 second timeout
|
|
@@ -2245,9 +1672,9 @@ var WalletManager = class _WalletManager {
|
|
|
2245
1672
|
* Create viem public client for the current network
|
|
2246
1673
|
*/
|
|
2247
1674
|
getPublicClient() {
|
|
2248
|
-
const
|
|
1675
|
+
const chain = this.config.network === "mainnet" ? chains.mainnet : chains.sepolia;
|
|
2249
1676
|
return viem.createPublicClient({
|
|
2250
|
-
chain
|
|
1677
|
+
chain,
|
|
2251
1678
|
transport: viem.http(this.config.rpcUrl, {
|
|
2252
1679
|
timeout: 15e3,
|
|
2253
1680
|
// 15 second timeout
|
|
@@ -2301,11 +1728,11 @@ var WalletManager = class _WalletManager {
|
|
|
2301
1728
|
*
|
|
2302
1729
|
* No fallback to placeholder addresses - WDK API is required for real addresses.
|
|
2303
1730
|
*/
|
|
2304
|
-
static async deriveAddressForChainAsync(seed,
|
|
2305
|
-
if (
|
|
1731
|
+
static async deriveAddressForChainAsync(seed, chain, network = "mainnet", apiUrl) {
|
|
1732
|
+
if (chain === "ethereum") {
|
|
2306
1733
|
try {
|
|
2307
1734
|
const wdkService2 = getZubariWdkService({ network, apiUrl });
|
|
2308
|
-
const result2 = await wdkService2.deriveAddress(seed,
|
|
1735
|
+
const result2 = await wdkService2.deriveAddress(seed, chain);
|
|
2309
1736
|
return result2.address;
|
|
2310
1737
|
} catch (error) {
|
|
2311
1738
|
console.warn("WDK service failed for Ethereum, using local derivation:", error);
|
|
@@ -2313,7 +1740,7 @@ var WalletManager = class _WalletManager {
|
|
|
2313
1740
|
}
|
|
2314
1741
|
}
|
|
2315
1742
|
const wdkService = getZubariWdkService({ network, apiUrl });
|
|
2316
|
-
const result = await wdkService.deriveAddress(seed,
|
|
1743
|
+
const result = await wdkService.deriveAddress(seed, chain);
|
|
2317
1744
|
return result.address;
|
|
2318
1745
|
}
|
|
2319
1746
|
/**
|
|
@@ -2322,14 +1749,14 @@ var WalletManager = class _WalletManager {
|
|
|
2322
1749
|
*
|
|
2323
1750
|
* @throws Error for non-Ethereum chains - use WDK API instead
|
|
2324
1751
|
*/
|
|
2325
|
-
static deriveAddressForChain(seed,
|
|
2326
|
-
if (
|
|
1752
|
+
static deriveAddressForChain(seed, chain) {
|
|
1753
|
+
if (chain === "ethereum") {
|
|
2327
1754
|
const ethPath = DERIVATION_PATHS["ethereum"];
|
|
2328
1755
|
const ethNode = ethers.HDNodeWallet.fromPhrase(seed, void 0, `${ethPath}/0`);
|
|
2329
1756
|
return ethNode.address;
|
|
2330
1757
|
}
|
|
2331
1758
|
throw new Error(
|
|
2332
|
-
`Sync derivation not supported for ${
|
|
1759
|
+
`Sync derivation not supported for ${chain}. Use deriveAddressForChainAsync() with WDK API.`
|
|
2333
1760
|
);
|
|
2334
1761
|
}
|
|
2335
1762
|
/**
|
|
@@ -2361,9 +1788,9 @@ var WalletManager = class _WalletManager {
|
|
|
2361
1788
|
const wdkAddresses = await this.wdkService.deriveAllAddresses(this.currentSeed);
|
|
2362
1789
|
const enabledChainsSet = new Set(this.config.enabledChains);
|
|
2363
1790
|
const addresses = {};
|
|
2364
|
-
for (const [
|
|
2365
|
-
if (enabledChainsSet.has(
|
|
2366
|
-
addresses[
|
|
1791
|
+
for (const [chain, address] of Object.entries(wdkAddresses)) {
|
|
1792
|
+
if (enabledChainsSet.has(chain) && address) {
|
|
1793
|
+
addresses[chain] = address;
|
|
2367
1794
|
}
|
|
2368
1795
|
}
|
|
2369
1796
|
this.derivedAddresses = addresses;
|
|
@@ -2404,10 +1831,10 @@ var WalletManager = class _WalletManager {
|
|
|
2404
1831
|
*/
|
|
2405
1832
|
normalizeAddresses(addresses) {
|
|
2406
1833
|
const normalized = {};
|
|
2407
|
-
for (const [
|
|
1834
|
+
for (const [chain, value] of Object.entries(addresses)) {
|
|
2408
1835
|
const addr = this.normalizeAddress(value);
|
|
2409
1836
|
if (addr) {
|
|
2410
|
-
normalized[
|
|
1837
|
+
normalized[chain] = addr;
|
|
2411
1838
|
}
|
|
2412
1839
|
}
|
|
2413
1840
|
return normalized;
|
|
@@ -2460,20 +1887,20 @@ var WalletManager = class _WalletManager {
|
|
|
2460
1887
|
* Get address for a specific chain
|
|
2461
1888
|
* Returns cached address or null - use deriveAllAddressesAsync to derive addresses
|
|
2462
1889
|
*/
|
|
2463
|
-
getAddressForChain(
|
|
2464
|
-
const cachedValue = this.derivedAddresses[
|
|
1890
|
+
getAddressForChain(chain) {
|
|
1891
|
+
const cachedValue = this.derivedAddresses[chain];
|
|
2465
1892
|
if (cachedValue) {
|
|
2466
|
-
console.log(`[WalletManager] getAddressForChain(${
|
|
1893
|
+
console.log(`[WalletManager] getAddressForChain(${chain}) cached value:`, cachedValue, "type:", typeof cachedValue);
|
|
2467
1894
|
const addr = this.normalizeAddress(cachedValue);
|
|
2468
|
-
console.log(`[WalletManager] getAddressForChain(${
|
|
1895
|
+
console.log(`[WalletManager] getAddressForChain(${chain}) normalized:`, addr);
|
|
2469
1896
|
if (addr) {
|
|
2470
|
-
this.derivedAddresses[
|
|
1897
|
+
this.derivedAddresses[chain] = addr;
|
|
2471
1898
|
return addr;
|
|
2472
1899
|
}
|
|
2473
1900
|
}
|
|
2474
|
-
if (
|
|
2475
|
-
this.derivedAddresses[
|
|
2476
|
-
return this.derivedAddresses[
|
|
1901
|
+
if (chain === "ethereum" && this.currentSeed) {
|
|
1902
|
+
this.derivedAddresses[chain] = _WalletManager.deriveAddressForChain(this.currentSeed, chain);
|
|
1903
|
+
return this.derivedAddresses[chain];
|
|
2477
1904
|
}
|
|
2478
1905
|
return null;
|
|
2479
1906
|
}
|
|
@@ -2486,11 +1913,11 @@ var WalletManager = class _WalletManager {
|
|
|
2486
1913
|
/**
|
|
2487
1914
|
* Set the selected chain
|
|
2488
1915
|
*/
|
|
2489
|
-
setSelectedChain(
|
|
2490
|
-
if (!this.config.enabledChains.includes(
|
|
2491
|
-
throw new Error(`Chain ${
|
|
1916
|
+
setSelectedChain(chain) {
|
|
1917
|
+
if (!this.config.enabledChains.includes(chain)) {
|
|
1918
|
+
throw new Error(`Chain ${chain} is not enabled`);
|
|
2492
1919
|
}
|
|
2493
|
-
this.selectedChain =
|
|
1920
|
+
this.selectedChain = chain;
|
|
2494
1921
|
}
|
|
2495
1922
|
/**
|
|
2496
1923
|
* Get the currently selected chain
|
|
@@ -2507,22 +1934,22 @@ var WalletManager = class _WalletManager {
|
|
|
2507
1934
|
/**
|
|
2508
1935
|
* Get chain configuration
|
|
2509
1936
|
*/
|
|
2510
|
-
getChainConfig(
|
|
2511
|
-
return getNetworkConfig(
|
|
1937
|
+
getChainConfig(chain) {
|
|
1938
|
+
return getNetworkConfig(chain, this.config.network === "testnet");
|
|
2512
1939
|
}
|
|
2513
1940
|
/**
|
|
2514
1941
|
* Fetch balance for a specific chain
|
|
2515
1942
|
* Note: Currently only Ethereum is implemented
|
|
2516
1943
|
*/
|
|
2517
|
-
async fetchBalanceForChain(
|
|
2518
|
-
const address = this.getAddressForChain(
|
|
1944
|
+
async fetchBalanceForChain(chain) {
|
|
1945
|
+
const address = this.getAddressForChain(chain);
|
|
2519
1946
|
if (!address) {
|
|
2520
|
-
throw new Error(`No address for chain ${
|
|
1947
|
+
throw new Error(`No address for chain ${chain}`);
|
|
2521
1948
|
}
|
|
2522
|
-
const networkConfig = this.getChainConfig(
|
|
1949
|
+
const networkConfig = this.getChainConfig(chain);
|
|
2523
1950
|
let balance = "0";
|
|
2524
1951
|
const tokenBalances = {};
|
|
2525
|
-
if (
|
|
1952
|
+
if (chain === "ethereum") {
|
|
2526
1953
|
const viemChain = this.config.network === "mainnet" ? chains.mainnet : chains.sepolia;
|
|
2527
1954
|
const isTestnet = this.config.network !== "mainnet";
|
|
2528
1955
|
const client = viem.createPublicClient({
|
|
@@ -2569,7 +1996,7 @@ var WalletManager = class _WalletManager {
|
|
|
2569
1996
|
} else if (usdtResult.status === "rejected") {
|
|
2570
1997
|
console.warn("[WalletManager] Failed to fetch ETH USDT balance:", usdtResult.reason);
|
|
2571
1998
|
}
|
|
2572
|
-
} else if (
|
|
1999
|
+
} else if (chain === "bitcoin") {
|
|
2573
2000
|
const isMainnet = this.config.network === "mainnet" || address.startsWith("bc1") || address.startsWith("1") || address.startsWith("3");
|
|
2574
2001
|
const apisToTry = isMainnet ? ["https://mempool.space/api"] : [
|
|
2575
2002
|
"https://mempool.space/testnet/api",
|
|
@@ -2601,7 +2028,7 @@ var WalletManager = class _WalletManager {
|
|
|
2601
2028
|
console.warn(`Failed to fetch from ${apiUrl}:`, error);
|
|
2602
2029
|
}
|
|
2603
2030
|
}
|
|
2604
|
-
} else if (
|
|
2031
|
+
} else if (chain === "solana") {
|
|
2605
2032
|
const rpcUrl = this.config.network === "mainnet" ? "https://api.mainnet-beta.solana.com" : "https://api.devnet.solana.com";
|
|
2606
2033
|
try {
|
|
2607
2034
|
const response = await fetch(rpcUrl, {
|
|
@@ -2621,7 +2048,7 @@ var WalletManager = class _WalletManager {
|
|
|
2621
2048
|
}
|
|
2622
2049
|
}
|
|
2623
2050
|
} catch (error) {
|
|
2624
|
-
console.warn(`Failed to fetch ${
|
|
2051
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
2625
2052
|
}
|
|
2626
2053
|
const isTestnet = this.config.network !== "mainnet";
|
|
2627
2054
|
const usdtMint = USDT_ADDRESSES.solana?.[isTestnet ? "testnet" : "mainnet"];
|
|
@@ -2655,7 +2082,7 @@ var WalletManager = class _WalletManager {
|
|
|
2655
2082
|
console.warn("Failed to fetch Solana USDT balance:", error);
|
|
2656
2083
|
}
|
|
2657
2084
|
}
|
|
2658
|
-
} else if (
|
|
2085
|
+
} else if (chain === "tron") {
|
|
2659
2086
|
const tronConfig = getNetworkConfig("tron", this.config.network !== "mainnet");
|
|
2660
2087
|
const baseUrl = tronConfig.rpcUrl;
|
|
2661
2088
|
try {
|
|
@@ -2684,9 +2111,9 @@ var WalletManager = class _WalletManager {
|
|
|
2684
2111
|
}
|
|
2685
2112
|
}
|
|
2686
2113
|
} catch (error) {
|
|
2687
|
-
console.warn(`Failed to fetch ${
|
|
2114
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
2688
2115
|
}
|
|
2689
|
-
} else if (
|
|
2116
|
+
} else if (chain === "ton") {
|
|
2690
2117
|
const isTestnet = this.config.network !== "mainnet";
|
|
2691
2118
|
const baseUrl = isTestnet ? "https://testnet.toncenter.com/api/v2" : "https://toncenter.com/api/v2";
|
|
2692
2119
|
try {
|
|
@@ -2702,25 +2129,36 @@ var WalletManager = class _WalletManager {
|
|
|
2702
2129
|
}
|
|
2703
2130
|
}
|
|
2704
2131
|
} catch (error) {
|
|
2705
|
-
console.warn(`Failed to fetch ${
|
|
2132
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
2706
2133
|
}
|
|
2707
2134
|
const usdtJetton = USDT_ADDRESSES.ton?.[isTestnet ? "testnet" : "mainnet"];
|
|
2708
2135
|
if (usdtJetton) {
|
|
2709
|
-
const
|
|
2136
|
+
const tonapiBaseUrl = isTestnet ? "https://testnet.tonapi.io/v2" : "https://tonapi.io/v2";
|
|
2710
2137
|
try {
|
|
2138
|
+
const rawAddr = tonFriendlyToRaw(address);
|
|
2711
2139
|
const jettonResponse = await fetch(
|
|
2712
|
-
`${
|
|
2140
|
+
`${tonapiBaseUrl}/accounts/${encodeURIComponent(rawAddr)}/jettons?currencies=usd`,
|
|
2713
2141
|
{ headers: { "Accept": "application/json" } }
|
|
2714
2142
|
);
|
|
2715
2143
|
if (jettonResponse.ok) {
|
|
2716
2144
|
const jettonData = await jettonResponse.json();
|
|
2717
|
-
const
|
|
2718
|
-
if (
|
|
2719
|
-
const
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2145
|
+
const balances = jettonData.balances;
|
|
2146
|
+
if (balances && balances.length > 0) {
|
|
2147
|
+
for (const jb of balances) {
|
|
2148
|
+
const jettonAddr = jb.jetton?.address;
|
|
2149
|
+
if (jettonAddr) {
|
|
2150
|
+
const usdtRaw = tonFriendlyToRaw(usdtJetton);
|
|
2151
|
+
if (jettonAddr.toLowerCase() === usdtRaw.toLowerCase()) {
|
|
2152
|
+
const rawBalance = jb.balance;
|
|
2153
|
+
if (rawBalance) {
|
|
2154
|
+
const decimals = jb.jetton?.decimals || 6;
|
|
2155
|
+
const usdtAmount = Number(BigInt(rawBalance)) / Math.pow(10, decimals);
|
|
2156
|
+
if (usdtAmount > 0) {
|
|
2157
|
+
tokenBalances.USDT = { balance: usdtAmount.toFixed(6), balanceUsd: usdtAmount };
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
break;
|
|
2161
|
+
}
|
|
2724
2162
|
}
|
|
2725
2163
|
}
|
|
2726
2164
|
}
|
|
@@ -2729,7 +2167,7 @@ var WalletManager = class _WalletManager {
|
|
|
2729
2167
|
console.warn("Failed to fetch TON USDT jetton balance:", error);
|
|
2730
2168
|
}
|
|
2731
2169
|
}
|
|
2732
|
-
} else if (
|
|
2170
|
+
} else if (chain === "spark") {
|
|
2733
2171
|
try {
|
|
2734
2172
|
const response = await fetch(`${this.config.apiUrl}/api/wallets/wdk/balance`, {
|
|
2735
2173
|
method: "POST",
|
|
@@ -2748,14 +2186,14 @@ var WalletManager = class _WalletManager {
|
|
|
2748
2186
|
}
|
|
2749
2187
|
}
|
|
2750
2188
|
} catch (error) {
|
|
2751
|
-
console.warn(`Failed to fetch ${
|
|
2189
|
+
console.warn(`Failed to fetch ${chain} balance:`, error);
|
|
2752
2190
|
}
|
|
2753
2191
|
}
|
|
2754
|
-
const priceUsd = await getPriceForChain(
|
|
2192
|
+
const priceUsd = await getPriceForChain(chain);
|
|
2755
2193
|
const balanceNum = parseFloat(balance) || 0;
|
|
2756
2194
|
const balanceUsd = balanceNum * priceUsd;
|
|
2757
2195
|
return {
|
|
2758
|
-
chain
|
|
2196
|
+
chain,
|
|
2759
2197
|
symbol: networkConfig.nativeCurrency.symbol,
|
|
2760
2198
|
balance,
|
|
2761
2199
|
balanceUsd,
|
|
@@ -2769,19 +2207,19 @@ var WalletManager = class _WalletManager {
|
|
|
2769
2207
|
*/
|
|
2770
2208
|
async fetchAllBalances() {
|
|
2771
2209
|
const balances = [];
|
|
2772
|
-
for (const
|
|
2210
|
+
for (const chain of this.config.enabledChains) {
|
|
2773
2211
|
try {
|
|
2774
|
-
const balance = await this.fetchBalanceForChain(
|
|
2212
|
+
const balance = await this.fetchBalanceForChain(chain);
|
|
2775
2213
|
balances.push(balance);
|
|
2776
2214
|
} catch (error) {
|
|
2777
|
-
console.error(`Failed to fetch balance for ${
|
|
2778
|
-
const networkConfig = this.getChainConfig(
|
|
2215
|
+
console.error(`Failed to fetch balance for ${chain}:`, error);
|
|
2216
|
+
const networkConfig = this.getChainConfig(chain);
|
|
2779
2217
|
balances.push({
|
|
2780
|
-
chain
|
|
2218
|
+
chain,
|
|
2781
2219
|
symbol: networkConfig.nativeCurrency.symbol,
|
|
2782
2220
|
balance: "0",
|
|
2783
2221
|
balanceUsd: 0,
|
|
2784
|
-
address: this.getAddressForChain(
|
|
2222
|
+
address: this.getAddressForChain(chain) || "",
|
|
2785
2223
|
decimals: networkConfig.nativeCurrency.decimals
|
|
2786
2224
|
});
|
|
2787
2225
|
}
|
|
@@ -2811,13 +2249,13 @@ var WalletManager = class _WalletManager {
|
|
|
2811
2249
|
* @param token - Optional token symbol (e.g., 'USDT' for stablecoins)
|
|
2812
2250
|
* @returns Transaction result with hash and status
|
|
2813
2251
|
*/
|
|
2814
|
-
async sendTransaction(
|
|
2252
|
+
async sendTransaction(chain, to, amount, token) {
|
|
2815
2253
|
if (!this.currentSeed) {
|
|
2816
2254
|
return { success: false, error: "Wallet is locked" };
|
|
2817
2255
|
}
|
|
2818
|
-
const fromAddress = this.getAddressForChain(
|
|
2256
|
+
const fromAddress = this.getAddressForChain(chain);
|
|
2819
2257
|
if (!fromAddress) {
|
|
2820
|
-
return { success: false, error: `No address for chain ${
|
|
2258
|
+
return { success: false, error: `No address for chain ${chain}` };
|
|
2821
2259
|
}
|
|
2822
2260
|
try {
|
|
2823
2261
|
const headers = {
|
|
@@ -2831,7 +2269,7 @@ var WalletManager = class _WalletManager {
|
|
|
2831
2269
|
headers,
|
|
2832
2270
|
body: JSON.stringify({
|
|
2833
2271
|
seed: this.currentSeed,
|
|
2834
|
-
chain
|
|
2272
|
+
chain,
|
|
2835
2273
|
to,
|
|
2836
2274
|
amount,
|
|
2837
2275
|
token,
|
|
@@ -2840,12 +2278,12 @@ var WalletManager = class _WalletManager {
|
|
|
2840
2278
|
});
|
|
2841
2279
|
if (response.ok) {
|
|
2842
2280
|
const data = await response.json();
|
|
2843
|
-
console.log(`Transaction sent on ${
|
|
2281
|
+
console.log(`Transaction sent on ${chain}:`, data);
|
|
2844
2282
|
let txHash = data.txHash || data.transactionHash || data.hash;
|
|
2845
2283
|
if (txHash && typeof txHash === "object" && "hash" in txHash) {
|
|
2846
2284
|
txHash = txHash.hash;
|
|
2847
2285
|
}
|
|
2848
|
-
if (
|
|
2286
|
+
if (chain === "ethereum" && txHash && (typeof txHash !== "string" || !txHash.startsWith("0x") || txHash.length !== 66)) {
|
|
2849
2287
|
console.warn(`Invalid Ethereum tx hash format: ${txHash} (length: ${txHash?.length}, expected: 66)`);
|
|
2850
2288
|
}
|
|
2851
2289
|
return {
|
|
@@ -2854,7 +2292,7 @@ var WalletManager = class _WalletManager {
|
|
|
2854
2292
|
from: fromAddress,
|
|
2855
2293
|
to,
|
|
2856
2294
|
amount,
|
|
2857
|
-
chain
|
|
2295
|
+
chain
|
|
2858
2296
|
};
|
|
2859
2297
|
}
|
|
2860
2298
|
const errorData = await response.json().catch(() => ({}));
|
|
@@ -2863,7 +2301,7 @@ var WalletManager = class _WalletManager {
|
|
|
2863
2301
|
error: errorData.error || `HTTP ${response.status}`
|
|
2864
2302
|
};
|
|
2865
2303
|
} catch (error) {
|
|
2866
|
-
console.error(`Transaction failed on ${
|
|
2304
|
+
console.error(`Transaction failed on ${chain}:`, error);
|
|
2867
2305
|
return {
|
|
2868
2306
|
success: false,
|
|
2869
2307
|
error: error instanceof Error ? error.message : "Transaction failed"
|
|
@@ -2873,7 +2311,7 @@ var WalletManager = class _WalletManager {
|
|
|
2873
2311
|
/**
|
|
2874
2312
|
* Estimate transaction fee using Tether WDK
|
|
2875
2313
|
*/
|
|
2876
|
-
async estimateFee(
|
|
2314
|
+
async estimateFee(chain, to, amount, token) {
|
|
2877
2315
|
try {
|
|
2878
2316
|
const headers = {
|
|
2879
2317
|
"Content-Type": "application/json"
|
|
@@ -2885,7 +2323,7 @@ var WalletManager = class _WalletManager {
|
|
|
2885
2323
|
method: "POST",
|
|
2886
2324
|
headers,
|
|
2887
2325
|
body: JSON.stringify({
|
|
2888
|
-
chain
|
|
2326
|
+
chain,
|
|
2889
2327
|
to,
|
|
2890
2328
|
amount,
|
|
2891
2329
|
token,
|
|
@@ -3094,12 +2532,12 @@ function useWalletManager(options = {}) {
|
|
|
3094
2532
|
setIsLoading(false);
|
|
3095
2533
|
}
|
|
3096
2534
|
}, [manager]);
|
|
3097
|
-
const setSelectedChain = react.useCallback((
|
|
3098
|
-
manager.setSelectedChain(
|
|
3099
|
-
setSelectedChainState(
|
|
2535
|
+
const setSelectedChain = react.useCallback((chain) => {
|
|
2536
|
+
manager.setSelectedChain(chain);
|
|
2537
|
+
setSelectedChainState(chain);
|
|
3100
2538
|
}, [manager]);
|
|
3101
2539
|
const getAddressForChain = react.useCallback(
|
|
3102
|
-
(
|
|
2540
|
+
(chain) => manager.getAddressForChain(chain),
|
|
3103
2541
|
[manager]
|
|
3104
2542
|
);
|
|
3105
2543
|
const getAllAddresses = react.useCallback(
|
|
@@ -3109,10 +2547,10 @@ function useWalletManager(options = {}) {
|
|
|
3109
2547
|
const hasWallet = react.useCallback(() => manager.hasWallet(), [manager]);
|
|
3110
2548
|
const getSeed = react.useCallback(() => manager.getSeed(), [manager]);
|
|
3111
2549
|
const sendTransaction = react.useCallback(
|
|
3112
|
-
async (
|
|
2550
|
+
async (chain, to, amount, token) => {
|
|
3113
2551
|
setIsLoading(true);
|
|
3114
2552
|
try {
|
|
3115
|
-
const result = await manager.sendTransaction(
|
|
2553
|
+
const result = await manager.sendTransaction(chain, to, amount, token);
|
|
3116
2554
|
if (result.success) {
|
|
3117
2555
|
try {
|
|
3118
2556
|
const balances = await manager.fetchAllBalances();
|
|
@@ -3129,8 +2567,8 @@ function useWalletManager(options = {}) {
|
|
|
3129
2567
|
[manager]
|
|
3130
2568
|
);
|
|
3131
2569
|
const estimateFee = react.useCallback(
|
|
3132
|
-
async (
|
|
3133
|
-
return manager.estimateFee(
|
|
2570
|
+
async (chain, to, amount, token) => {
|
|
2571
|
+
return manager.estimateFee(chain, to, amount, token);
|
|
3134
2572
|
},
|
|
3135
2573
|
[manager]
|
|
3136
2574
|
);
|
|
@@ -3164,14 +2602,6 @@ function useWalletManager(options = {}) {
|
|
|
3164
2602
|
manager
|
|
3165
2603
|
};
|
|
3166
2604
|
}
|
|
3167
|
-
/*! Bundled license information:
|
|
3168
|
-
|
|
3169
|
-
@scure/base/index.js:
|
|
3170
|
-
(*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
3171
|
-
|
|
3172
|
-
@scure/bip32/index.js:
|
|
3173
|
-
(*! scure-bip32 - MIT License (c) 2022 Patricio Palladino, Paul Miller (paulmillr.com) *)
|
|
3174
|
-
*/
|
|
3175
2605
|
|
|
3176
2606
|
exports.SUPPORTED_CHAINS = SUPPORTED_CHAINS;
|
|
3177
2607
|
exports.useWalletManager = useWalletManager;
|