hd-wallet-wasm 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/hd-wallet-wasi.wasm +0 -0
- package/dist/hd-wallet.js +1 -1
- package/dist/runtime/aligned.mjs +28 -18
- package/dist/runtime/index.d.ts +31 -13
- package/dist/runtime/index.mjs +478 -378
- package/dist/runtime/input-validation.mjs +107 -8
- package/package.json +2 -2
package/dist/runtime/index.mjs
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* - Transaction building and signing
|
|
10
10
|
*
|
|
11
11
|
* @module hd-wallet-wasm
|
|
12
|
-
* @version 2.1.
|
|
12
|
+
* @version 2.1.2
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
// Import aligned API for batch operations
|
|
@@ -557,6 +557,59 @@ function decodeBech32Fallback(str) {
|
|
|
557
557
|
return { hrp, data: out };
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
+
/** %TypedArray%.prototype.fill, captured at load (uses the internal length). */
|
|
561
|
+
const TYPED_ARRAY_FILL = Object.getPrototypeOf(Uint8Array.prototype).fill;
|
|
562
|
+
|
|
563
|
+
// Internal-slot getters, captured at load: they work on objects of any realm
|
|
564
|
+
// and cannot be overridden by the object.
|
|
565
|
+
const slotGetter = (prototype, name) => Object.getOwnPropertyDescriptor(prototype, name)?.get;
|
|
566
|
+
const TYPED_ARRAY_SLOTS = ['buffer', 'byteOffset', 'byteLength']
|
|
567
|
+
.map((name) => slotGetter(Object.getPrototypeOf(Uint8Array.prototype), name));
|
|
568
|
+
const DATA_VIEW_SLOTS = ['buffer', 'byteOffset', 'byteLength'].map((name) => slotGetter(DataView.prototype, name));
|
|
569
|
+
const ARRAY_BUFFER_BYTE_LENGTH = slotGetter(ArrayBuffer.prototype, 'byteLength');
|
|
570
|
+
const ARRAY_BUFFER_DETACHED = slotGetter(ArrayBuffer.prototype, 'detached');
|
|
571
|
+
const SHARED_BUFFER_BYTE_LENGTH = typeof SharedArrayBuffer === 'function'
|
|
572
|
+
? slotGetter(SharedArrayBuffer.prototype, 'byteLength')
|
|
573
|
+
: undefined;
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* The bytes under binary data of any kind and realm: { buffer, offset,
|
|
577
|
+
* length, detached }, or null for anything that is not binary data.
|
|
578
|
+
*/
|
|
579
|
+
function binaryRegion(value) {
|
|
580
|
+
const read = (getters) => {
|
|
581
|
+
try {
|
|
582
|
+
const [buffer, offset, length] = getters.map((get) => get.call(value));
|
|
583
|
+
return { buffer, offset, length };
|
|
584
|
+
} catch {
|
|
585
|
+
return null;
|
|
586
|
+
}
|
|
587
|
+
};
|
|
588
|
+
let region = read(TYPED_ARRAY_SLOTS) ?? read(DATA_VIEW_SLOTS);
|
|
589
|
+
if (region === null) {
|
|
590
|
+
for (const byteLength of [ARRAY_BUFFER_BYTE_LENGTH, SHARED_BUFFER_BYTE_LENGTH]) {
|
|
591
|
+
if (!byteLength) continue;
|
|
592
|
+
try {
|
|
593
|
+
region = { buffer: value, offset: 0, length: byteLength.call(value) };
|
|
594
|
+
break;
|
|
595
|
+
} catch {
|
|
596
|
+
// Not that kind of buffer.
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
if (region === null) return null;
|
|
601
|
+
let detached = false;
|
|
602
|
+
try {
|
|
603
|
+
detached = ARRAY_BUFFER_DETACHED ? ARRAY_BUFFER_DETACHED.call(region.buffer) : false;
|
|
604
|
+
} catch {
|
|
605
|
+
detached = false; // A SharedArrayBuffer cannot be detached.
|
|
606
|
+
}
|
|
607
|
+
return { ...region, detached };
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/** The largest Ethereum chain ID (EIP-2294). */
|
|
611
|
+
const ETH_MAX_CHAIN_ID = 9223372036854775771n;
|
|
612
|
+
|
|
560
613
|
// =============================================================================
|
|
561
614
|
// Memory Helpers
|
|
562
615
|
// =============================================================================
|
|
@@ -565,19 +618,23 @@ function decodeBech32Fallback(str) {
|
|
|
565
618
|
* Allocate memory and copy data
|
|
566
619
|
* @param {WebAssembly.Module} wasm - WASM module
|
|
567
620
|
* @param {Uint8Array} data - Data to copy
|
|
568
|
-
* @returns {number}
|
|
621
|
+
* @returns {{ptr: number, len: number}} Heap pointer and the copied length
|
|
569
622
|
*/
|
|
570
623
|
function allocAndCopy(wasm, data) {
|
|
571
624
|
// Only binary data reaches the heap (a string or array would be coerced).
|
|
572
625
|
V.bytes(data, 'data');
|
|
626
|
+
// One copy from the array's own bytes and length: the caller's `length`
|
|
627
|
+
// (a subclass getter, an own property) is never read again. Callers pass
|
|
628
|
+
// the returned `len` to native code.
|
|
629
|
+
const copy = new Uint8Array(data);
|
|
630
|
+
const len = copy.length;
|
|
573
631
|
// Many C++ implementations assume pointers are non-null even when `len == 0`.
|
|
574
632
|
// Allocate a 1-byte placeholder in that case to avoid passing NULL into WASM.
|
|
575
|
-
const
|
|
576
|
-
const allocLen = len === 0 ? 1 : len;
|
|
577
|
-
const ptr = wasm._hd_alloc(allocLen);
|
|
633
|
+
const ptr = wasm._hd_alloc(len === 0 ? 1 : len);
|
|
578
634
|
if (!ptr) throw new HDWalletError(ErrorCode.OUT_OF_MEMORY);
|
|
579
|
-
|
|
580
|
-
|
|
635
|
+
wasm.HEAPU8.set(copy, ptr);
|
|
636
|
+
copy.fill(0);
|
|
637
|
+
return { ptr, len };
|
|
581
638
|
}
|
|
582
639
|
|
|
583
640
|
/**
|
|
@@ -714,17 +771,10 @@ function callDynamicStringResult(wasm, invoke, options = {}) {
|
|
|
714
771
|
}
|
|
715
772
|
}
|
|
716
773
|
|
|
774
|
+
// Binary data is a Uint8Array in every family: a DataView, an ArrayBuffer or
|
|
775
|
+
// another typed array is refused, as everywhere else.
|
|
717
776
|
function toUint8Array(data, name = 'data') {
|
|
718
|
-
|
|
719
|
-
return data;
|
|
720
|
-
}
|
|
721
|
-
if (ArrayBuffer.isView(data)) {
|
|
722
|
-
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength).slice();
|
|
723
|
-
}
|
|
724
|
-
if (data instanceof ArrayBuffer) {
|
|
725
|
-
return new Uint8Array(data.slice(0));
|
|
726
|
-
}
|
|
727
|
-
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, `${name} must be binary data`);
|
|
777
|
+
return V.bytes(data, name);
|
|
728
778
|
}
|
|
729
779
|
|
|
730
780
|
function curveToName(curve) {
|
|
@@ -981,7 +1031,7 @@ class HDKey {
|
|
|
981
1031
|
publicKeyUncompressed() {
|
|
982
1032
|
this._checkDestroyed();
|
|
983
1033
|
const compressed = this.publicKey();
|
|
984
|
-
const inPtr = allocAndCopy(this._wasm, compressed);
|
|
1034
|
+
const { ptr: inPtr, len: inLen } = allocAndCopy(this._wasm, compressed);
|
|
985
1035
|
const outPtr = this._wasm._hd_alloc(65);
|
|
986
1036
|
try {
|
|
987
1037
|
const result = this._wasm._hd_curve_decompress_pubkey(inPtr, Curve.SECP256K1, outPtr, 65);
|
|
@@ -1133,11 +1183,11 @@ class HDKey {
|
|
|
1133
1183
|
peerId() {
|
|
1134
1184
|
this._checkDestroyed();
|
|
1135
1185
|
const pubKey = this.publicKey();
|
|
1136
|
-
const pubPtr = allocAndCopy(this._wasm, pubKey);
|
|
1186
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(this._wasm, pubKey);
|
|
1137
1187
|
const outPtr = this._wasm._hd_alloc(64);
|
|
1138
1188
|
try {
|
|
1139
1189
|
const result = checkLengthWithin(
|
|
1140
|
-
this._wasm._hd_libp2p_peer_id(pubPtr,
|
|
1190
|
+
this._wasm._hd_libp2p_peer_id(pubPtr, pubLen, this.curve, outPtr, 64), 1, 64);
|
|
1141
1191
|
return readBytes(this._wasm, outPtr, result);
|
|
1142
1192
|
} finally {
|
|
1143
1193
|
this._wasm._hd_dealloc(pubPtr);
|
|
@@ -1152,10 +1202,10 @@ class HDKey {
|
|
|
1152
1202
|
peerIdString() {
|
|
1153
1203
|
this._checkDestroyed();
|
|
1154
1204
|
const pubKey = this.publicKey();
|
|
1155
|
-
const pubPtr = allocAndCopy(this._wasm, pubKey);
|
|
1205
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(this._wasm, pubKey);
|
|
1156
1206
|
const outPtr = this._wasm._hd_alloc(128);
|
|
1157
1207
|
try {
|
|
1158
|
-
const result = this._wasm._hd_libp2p_peer_id_string(pubPtr,
|
|
1208
|
+
const result = this._wasm._hd_libp2p_peer_id_string(pubPtr, pubLen, this.curve, outPtr, 128);
|
|
1159
1209
|
checkResult(result);
|
|
1160
1210
|
return readString(this._wasm, outPtr);
|
|
1161
1211
|
} finally {
|
|
@@ -1171,10 +1221,10 @@ class HDKey {
|
|
|
1171
1221
|
ipnsHash() {
|
|
1172
1222
|
this._checkDestroyed();
|
|
1173
1223
|
const pubKey = this.publicKey();
|
|
1174
|
-
const pubPtr = allocAndCopy(this._wasm, pubKey);
|
|
1224
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(this._wasm, pubKey);
|
|
1175
1225
|
const outPtr = this._wasm._hd_alloc(128);
|
|
1176
1226
|
try {
|
|
1177
|
-
const result = this._wasm._hd_libp2p_ipns_hash(pubPtr,
|
|
1227
|
+
const result = this._wasm._hd_libp2p_ipns_hash(pubPtr, pubLen, this.curve, outPtr, 128);
|
|
1178
1228
|
checkResult(result);
|
|
1179
1229
|
return readString(this._wasm, outPtr);
|
|
1180
1230
|
} finally {
|
|
@@ -1434,15 +1484,15 @@ function createModule(wasm) {
|
|
|
1434
1484
|
fromEntropy(entropy, language = Language.ENGLISH) {
|
|
1435
1485
|
V.bytes(entropy, 'entropy', ErrorCode.INVALID_ENTROPY_LENGTH);
|
|
1436
1486
|
V.integer(language, 'language', 0, 0x7fffffff);
|
|
1437
|
-
const entropyPtr = allocAndCopy(wasm, entropy);
|
|
1487
|
+
const { ptr: entropyPtr, len: entropyLen } = allocAndCopy(wasm, entropy);
|
|
1438
1488
|
const outputPtr = wasm._hd_alloc(1024);
|
|
1439
1489
|
try {
|
|
1440
|
-
const result = wasm._hd_entropy_to_mnemonic(entropyPtr,
|
|
1490
|
+
const result = wasm._hd_entropy_to_mnemonic(entropyPtr, entropyLen, language, outputPtr, 1024);
|
|
1441
1491
|
checkResult(result);
|
|
1442
1492
|
return readString(wasm, outputPtr);
|
|
1443
1493
|
} finally {
|
|
1444
1494
|
// SECURITY FIX [HIGH-04]: Wipe sensitive data before deallocation
|
|
1445
|
-
wasm._hd_secure_wipe(entropyPtr,
|
|
1495
|
+
wasm._hd_secure_wipe(entropyPtr, entropyLen);
|
|
1446
1496
|
wasm._hd_dealloc(entropyPtr);
|
|
1447
1497
|
// Wipe mnemonic output buffer
|
|
1448
1498
|
wasm._hd_secure_wipe(outputPtr, 1024);
|
|
@@ -1530,15 +1580,15 @@ function createModule(wasm) {
|
|
|
1530
1580
|
// BIP-32 allows 128-512 bits (16-64 bytes)
|
|
1531
1581
|
V.bytesInRange(seed, 16, 64, 'Seed', ErrorCode.INVALID_SEED);
|
|
1532
1582
|
V.curve(curve);
|
|
1533
|
-
const seedPtr = allocAndCopy(wasm, seed);
|
|
1583
|
+
const { ptr: seedPtr, len: seedLen } = allocAndCopy(wasm, seed);
|
|
1534
1584
|
try {
|
|
1535
|
-
const handle = wasm._hd_key_from_seed(seedPtr,
|
|
1585
|
+
const handle = wasm._hd_key_from_seed(seedPtr, seedLen, curve);
|
|
1536
1586
|
if (!handle) {
|
|
1537
1587
|
throw new HDWalletError(ErrorCode.INVALID_SEED);
|
|
1538
1588
|
}
|
|
1539
1589
|
return new HDKey(wasm, handle, 'm');
|
|
1540
1590
|
} finally {
|
|
1541
|
-
wasm._hd_secure_wipe(seedPtr,
|
|
1591
|
+
wasm._hd_secure_wipe(seedPtr, seedLen);
|
|
1542
1592
|
wasm._hd_dealloc(seedPtr);
|
|
1543
1593
|
}
|
|
1544
1594
|
},
|
|
@@ -1659,7 +1709,7 @@ function createModule(wasm) {
|
|
|
1659
1709
|
publicKeyFromPrivate(privateKey, curve) {
|
|
1660
1710
|
const pubFromPrivFn = requireWasmFunction(wasm, '_hd_curve_pubkey_from_privkey');
|
|
1661
1711
|
V.privateKey(wasm, privateKey, curve);
|
|
1662
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
1712
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
1663
1713
|
const pubPtr = wasm._hd_alloc(65);
|
|
1664
1714
|
try {
|
|
1665
1715
|
// Returns the key length; a private key outside 0 < d < n fails.
|
|
@@ -1667,7 +1717,7 @@ function createModule(wasm) {
|
|
|
1667
1717
|
checkLength(pubFromPrivFn(privPtr, curve, pubPtr, 65), expectedLen);
|
|
1668
1718
|
return readBytes(wasm, pubPtr, expectedLen);
|
|
1669
1719
|
} finally {
|
|
1670
|
-
wasm._hd_secure_wipe(privPtr,
|
|
1720
|
+
wasm._hd_secure_wipe(privPtr, privLen);
|
|
1671
1721
|
wasm._hd_dealloc(privPtr);
|
|
1672
1722
|
wasm._hd_dealloc(pubPtr);
|
|
1673
1723
|
}
|
|
@@ -1702,7 +1752,7 @@ function createModule(wasm) {
|
|
|
1702
1752
|
const decompressFn = requireWasmFunction(wasm, '_hd_curve_decompress_pubkey');
|
|
1703
1753
|
// The export reads exactly 33 bytes: a valid compressed key only.
|
|
1704
1754
|
V.publicKey(wasm, publicKey, curve, 'publicKey', [curve === Curve.P384 ? 49 : 33]);
|
|
1705
|
-
const inPtr = allocAndCopy(wasm, publicKey);
|
|
1755
|
+
const { ptr: inPtr, len: inLen } = allocAndCopy(wasm, publicKey);
|
|
1706
1756
|
const outPtr = wasm._hd_alloc(97);
|
|
1707
1757
|
try {
|
|
1708
1758
|
// Status export: 0 on success (secp256k1 only), -Error otherwise.
|
|
@@ -1732,17 +1782,17 @@ function createModule(wasm) {
|
|
|
1732
1782
|
V.curve(curve, [Curve.SECP256K1, Curve.P256, Curve.P384, Curve.X25519]);
|
|
1733
1783
|
V.privateKey(wasm, privateKey, curve);
|
|
1734
1784
|
V.publicKey(wasm, publicKey, curve);
|
|
1735
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
1736
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
1785
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
1786
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
1737
1787
|
const secretSize = curve === Curve.P384 ? 48 : 32;
|
|
1738
1788
|
const secretPtr = wasm._hd_alloc(secretSize);
|
|
1739
1789
|
try {
|
|
1740
|
-
const result = ecdhFn(curve, privPtr,
|
|
1790
|
+
const result = ecdhFn(curve, privPtr, privLen, pubPtr, pubLen, secretPtr, secretSize);
|
|
1741
1791
|
// Returns the secret length (the curve's field size); -1 on failure.
|
|
1742
1792
|
if (result !== secretSize) throw new HDWalletError(ErrorCode.INTERNAL, 'ECDH key exchange failed');
|
|
1743
1793
|
return readBytes(wasm, secretPtr, secretSize);
|
|
1744
1794
|
} finally {
|
|
1745
|
-
wasm._hd_secure_wipe(privPtr,
|
|
1795
|
+
wasm._hd_secure_wipe(privPtr, privLen);
|
|
1746
1796
|
wasm._hd_secure_wipe(secretPtr, secretSize);
|
|
1747
1797
|
wasm._hd_dealloc(privPtr);
|
|
1748
1798
|
wasm._hd_dealloc(pubPtr);
|
|
@@ -1766,12 +1816,12 @@ function createModule(wasm) {
|
|
|
1766
1816
|
sign(message, privateKey) {
|
|
1767
1817
|
V.bytes(message, 'message');
|
|
1768
1818
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
1769
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1770
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
1819
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
1820
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
1771
1821
|
const sigPtr = wasm._hd_alloc(72);
|
|
1772
1822
|
try {
|
|
1773
1823
|
// Returns 64 (compact r||s); a private key outside 0 < d < n fails.
|
|
1774
|
-
checkLength(wasm._hd_secp256k1_sign(msgPtr,
|
|
1824
|
+
checkLength(wasm._hd_secp256k1_sign(msgPtr, msgLen, keyPtr, sigPtr, 72), 64);
|
|
1775
1825
|
return readBytes(wasm, sigPtr, 64);
|
|
1776
1826
|
} finally {
|
|
1777
1827
|
wasm._hd_secure_wipe(keyPtr, 32);
|
|
@@ -1793,14 +1843,14 @@ function createModule(wasm) {
|
|
|
1793
1843
|
const signRecoverableFn = requireWasmFunction(wasm, '_hd_secp256k1_sign_recoverable');
|
|
1794
1844
|
V.bytesOfLength(message, 32, 'message hash');
|
|
1795
1845
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
1796
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1797
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
1846
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
1847
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
1798
1848
|
const sigPtr = wasm._hd_alloc(65);
|
|
1799
1849
|
try {
|
|
1800
1850
|
// C signature: int32_t hd_secp256k1_sign_recoverable(hash, hash_len, privkey, out_sig65)
|
|
1801
1851
|
// Returns 65 on success (bytes written), -Error on failure.
|
|
1802
1852
|
// out_sig65 = r[32] + s[32] + v[1], recovery ID is at byte[64].
|
|
1803
|
-
checkLength(signRecoverableFn(msgPtr,
|
|
1853
|
+
checkLength(signRecoverableFn(msgPtr, msgLen, keyPtr, sigPtr), 65);
|
|
1804
1854
|
const recoveryId = wasm.HEAPU8[sigPtr + 64];
|
|
1805
1855
|
if (recoveryId > 3) throw new HDWalletError(ErrorCode.INVALID_SIGNATURE);
|
|
1806
1856
|
const signature = readBytes(wasm, sigPtr, 64);
|
|
@@ -1826,14 +1876,14 @@ function createModule(wasm) {
|
|
|
1826
1876
|
V.bytes(signature, 'signature');
|
|
1827
1877
|
V.bytes(publicKey, 'publicKey');
|
|
1828
1878
|
// Compact r||s (64 bytes) or DER (8-72 bytes); a key of either SEC1 size.
|
|
1829
|
-
if (signature
|
|
1879
|
+
if (V.byteLength(signature) < 8 || V.byteLength(signature) > 72 || !V.hasLength(publicKey, [33, 65])) {
|
|
1830
1880
|
return false;
|
|
1831
1881
|
}
|
|
1832
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1833
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
1834
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
1882
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
1883
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
1884
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
1835
1885
|
try {
|
|
1836
|
-
const result = wasm._hd_secp256k1_verify(msgPtr,
|
|
1886
|
+
const result = wasm._hd_secp256k1_verify(msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen);
|
|
1837
1887
|
return result === 1;
|
|
1838
1888
|
} finally {
|
|
1839
1889
|
wasm._hd_dealloc(msgPtr);
|
|
@@ -1857,18 +1907,18 @@ function createModule(wasm) {
|
|
|
1857
1907
|
if (!Number.isInteger(recoveryId) || recoveryId < 0 || recoveryId > 3) {
|
|
1858
1908
|
throw new HDWalletError(ErrorCode.INVALID_SIGNATURE, 'recoveryId must be 0, 1, 2 or 3');
|
|
1859
1909
|
}
|
|
1860
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1910
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
1861
1911
|
// Build 65-byte sig buffer: r[32] + s[32] + v[1]
|
|
1862
1912
|
// C signature: int32_t hd_secp256k1_recover(hash, hash_len, sig65, out_pubkey33)
|
|
1863
1913
|
const sig65 = new Uint8Array(65);
|
|
1864
1914
|
sig65.set(signature.subarray(0, 64));
|
|
1865
1915
|
sig65[64] = recoveryId;
|
|
1866
|
-
const sigPtr = allocAndCopy(wasm, sig65);
|
|
1916
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, sig65);
|
|
1867
1917
|
const pubPtr = wasm._hd_alloc(33);
|
|
1868
1918
|
try {
|
|
1869
1919
|
// Returns 33 on success; a signature no key recovers from (ids 2
|
|
1870
1920
|
// and 3 when r + n >= p included) fails, so this throws.
|
|
1871
|
-
checkLength(recoverFn(msgPtr,
|
|
1921
|
+
checkLength(recoverFn(msgPtr, msgLen, sigPtr, pubPtr), 33);
|
|
1872
1922
|
return readBytes(wasm, pubPtr, 33);
|
|
1873
1923
|
} finally {
|
|
1874
1924
|
wasm._hd_dealloc(msgPtr);
|
|
@@ -1886,11 +1936,11 @@ function createModule(wasm) {
|
|
|
1886
1936
|
ecdh(privateKey, publicKey) {
|
|
1887
1937
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
1888
1938
|
V.publicKey(wasm, publicKey, Curve.SECP256K1);
|
|
1889
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
1890
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
1939
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
1940
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
1891
1941
|
const secretPtr = wasm._hd_alloc(32);
|
|
1892
1942
|
try {
|
|
1893
|
-
checkLength(wasm._hd_ecdh_secp256k1(privPtr, pubPtr,
|
|
1943
|
+
checkLength(wasm._hd_ecdh_secp256k1(privPtr, pubPtr, pubLen, secretPtr, 32), 32);
|
|
1894
1944
|
return readBytes(wasm, secretPtr, 32);
|
|
1895
1945
|
} finally {
|
|
1896
1946
|
wasm._hd_secure_wipe(privPtr, 32);
|
|
@@ -1913,7 +1963,7 @@ function createModule(wasm) {
|
|
|
1913
1963
|
*/
|
|
1914
1964
|
publicKeyFromSeed(seed) {
|
|
1915
1965
|
V.privateKey(wasm, seed, Curve.ED25519, 'seed');
|
|
1916
|
-
const seedPtr = allocAndCopy(wasm, seed);
|
|
1966
|
+
const { ptr: seedPtr, len: seedLen } = allocAndCopy(wasm, seed);
|
|
1917
1967
|
const pubPtr = wasm._hd_alloc(32);
|
|
1918
1968
|
try {
|
|
1919
1969
|
checkResult(wasm._hd_ed25519_pubkey_from_seed(seedPtr, pubPtr, 32));
|
|
@@ -1934,11 +1984,11 @@ function createModule(wasm) {
|
|
|
1934
1984
|
sign(message, privateKey) {
|
|
1935
1985
|
V.bytes(message, 'message');
|
|
1936
1986
|
V.privateKey(wasm, privateKey, Curve.ED25519);
|
|
1937
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1938
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
1987
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
1988
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
1939
1989
|
const sigPtr = wasm._hd_alloc(64);
|
|
1940
1990
|
try {
|
|
1941
|
-
checkLength(wasm._hd_ed25519_sign(msgPtr,
|
|
1991
|
+
checkLength(wasm._hd_ed25519_sign(msgPtr, msgLen, keyPtr, sigPtr, 64), 64);
|
|
1942
1992
|
return readBytes(wasm, sigPtr, 64);
|
|
1943
1993
|
} finally {
|
|
1944
1994
|
wasm._hd_secure_wipe(keyPtr, 32);
|
|
@@ -1959,13 +2009,13 @@ function createModule(wasm) {
|
|
|
1959
2009
|
V.bytes(message, 'message');
|
|
1960
2010
|
V.bytes(signature, 'signature');
|
|
1961
2011
|
V.bytes(publicKey, 'publicKey');
|
|
1962
|
-
if (signature
|
|
1963
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1964
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
1965
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2012
|
+
if (V.byteLength(signature) !== 64 || V.byteLength(publicKey) !== 32) return false;
|
|
2013
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2014
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
2015
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
1966
2016
|
try {
|
|
1967
2017
|
// RFC 8032 strict: S < L, A and R canonical and not of small order.
|
|
1968
|
-
const result = wasm._hd_ed25519_verify(msgPtr,
|
|
2018
|
+
const result = wasm._hd_ed25519_verify(msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen);
|
|
1969
2019
|
return result === 1;
|
|
1970
2020
|
} finally {
|
|
1971
2021
|
wasm._hd_dealloc(msgPtr);
|
|
@@ -1989,11 +2039,11 @@ function createModule(wasm) {
|
|
|
1989
2039
|
sign(message, privateKey) {
|
|
1990
2040
|
V.bytes(message, 'message');
|
|
1991
2041
|
V.privateKey(wasm, privateKey, Curve.P256);
|
|
1992
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
1993
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2042
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2043
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
1994
2044
|
const sigPtr = wasm._hd_alloc(72);
|
|
1995
2045
|
try {
|
|
1996
|
-
checkLength(wasm._hd_p256_sign(msgPtr,
|
|
2046
|
+
checkLength(wasm._hd_p256_sign(msgPtr, msgLen, keyPtr, sigPtr, 72), 64);
|
|
1997
2047
|
return readBytes(wasm, sigPtr, 64);
|
|
1998
2048
|
} finally {
|
|
1999
2049
|
wasm._hd_secure_wipe(keyPtr, 32);
|
|
@@ -2015,13 +2065,13 @@ function createModule(wasm) {
|
|
|
2015
2065
|
V.bytes(message, 'message');
|
|
2016
2066
|
V.bytes(signature, 'signature');
|
|
2017
2067
|
// The export reads exactly 64 signature bytes and takes no length.
|
|
2018
|
-
if (signature
|
|
2019
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
2020
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
2021
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2068
|
+
if (V.byteLength(signature) !== 64 || !V.isPublicKey(wasm, publicKey, Curve.P256)) return false;
|
|
2069
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2070
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
2071
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2022
2072
|
try {
|
|
2023
2073
|
// C: hd_p256_verify(message, message_len, public_key, public_key_len, signature)
|
|
2024
|
-
return verifyFn(msgPtr,
|
|
2074
|
+
return verifyFn(msgPtr, msgLen, pubPtr, pubLen, sigPtr) === 0;
|
|
2025
2075
|
} finally {
|
|
2026
2076
|
wasm._hd_dealloc(msgPtr);
|
|
2027
2077
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -2032,11 +2082,11 @@ function createModule(wasm) {
|
|
|
2032
2082
|
ecdh(privateKey, publicKey) {
|
|
2033
2083
|
V.privateKey(wasm, privateKey, Curve.P256);
|
|
2034
2084
|
V.publicKey(wasm, publicKey, Curve.P256);
|
|
2035
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
2036
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2085
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
2086
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2037
2087
|
const secretPtr = wasm._hd_alloc(32);
|
|
2038
2088
|
try {
|
|
2039
|
-
checkLength(wasm._hd_ecdh_p256(privPtr, pubPtr,
|
|
2089
|
+
checkLength(wasm._hd_ecdh_p256(privPtr, pubPtr, pubLen, secretPtr, 32), 32);
|
|
2040
2090
|
return readBytes(wasm, secretPtr, 32);
|
|
2041
2091
|
} finally {
|
|
2042
2092
|
wasm._hd_secure_wipe(privPtr, 32);
|
|
@@ -2062,11 +2112,11 @@ function createModule(wasm) {
|
|
|
2062
2112
|
sign(message, privateKey) {
|
|
2063
2113
|
V.bytes(message, 'message');
|
|
2064
2114
|
V.privateKey(wasm, privateKey, Curve.P384);
|
|
2065
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
2066
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2115
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2116
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2067
2117
|
const sigPtr = wasm._hd_alloc(104);
|
|
2068
2118
|
try {
|
|
2069
|
-
checkLength(wasm._hd_p384_sign(msgPtr,
|
|
2119
|
+
checkLength(wasm._hd_p384_sign(msgPtr, msgLen, keyPtr, sigPtr, 104), 96);
|
|
2070
2120
|
return readBytes(wasm, sigPtr, 96);
|
|
2071
2121
|
} finally {
|
|
2072
2122
|
wasm._hd_secure_wipe(keyPtr, 48);
|
|
@@ -2088,13 +2138,13 @@ function createModule(wasm) {
|
|
|
2088
2138
|
V.bytes(message, 'message');
|
|
2089
2139
|
V.bytes(signature, 'signature');
|
|
2090
2140
|
// The export reads exactly 96 signature bytes and takes no length.
|
|
2091
|
-
if (signature
|
|
2092
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
2093
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
2094
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2141
|
+
if (V.byteLength(signature) !== 96 || !V.isPublicKey(wasm, publicKey, Curve.P384)) return false;
|
|
2142
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2143
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
2144
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2095
2145
|
try {
|
|
2096
2146
|
// C: hd_p384_verify(message, message_len, public_key, public_key_len, signature)
|
|
2097
|
-
return verifyFn(msgPtr,
|
|
2147
|
+
return verifyFn(msgPtr, msgLen, pubPtr, pubLen, sigPtr) === 0;
|
|
2098
2148
|
} finally {
|
|
2099
2149
|
wasm._hd_dealloc(msgPtr);
|
|
2100
2150
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -2105,11 +2155,11 @@ function createModule(wasm) {
|
|
|
2105
2155
|
ecdh(privateKey, publicKey) {
|
|
2106
2156
|
V.privateKey(wasm, privateKey, Curve.P384);
|
|
2107
2157
|
V.publicKey(wasm, publicKey, Curve.P384);
|
|
2108
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
2109
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2158
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
2159
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2110
2160
|
const secretPtr = wasm._hd_alloc(48);
|
|
2111
2161
|
try {
|
|
2112
|
-
checkLength(wasm._hd_ecdh_p384(privPtr, pubPtr,
|
|
2162
|
+
checkLength(wasm._hd_ecdh_p384(privPtr, pubPtr, pubLen, secretPtr, 48), 48);
|
|
2113
2163
|
return readBytes(wasm, secretPtr, 48);
|
|
2114
2164
|
} finally {
|
|
2115
2165
|
wasm._hd_secure_wipe(privPtr, 48);
|
|
@@ -2132,7 +2182,7 @@ function createModule(wasm) {
|
|
|
2132
2182
|
*/
|
|
2133
2183
|
publicKey(privateKey) {
|
|
2134
2184
|
V.privateKey(wasm, privateKey, Curve.X25519);
|
|
2135
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
2185
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
2136
2186
|
const pubPtr = wasm._hd_alloc(32);
|
|
2137
2187
|
try {
|
|
2138
2188
|
checkResult(wasm._hd_x25519_pubkey(privPtr, pubPtr, 32));
|
|
@@ -2153,8 +2203,8 @@ function createModule(wasm) {
|
|
|
2153
2203
|
ecdh(privateKey, publicKey) {
|
|
2154
2204
|
V.privateKey(wasm, privateKey, Curve.X25519);
|
|
2155
2205
|
V.publicKey(wasm, publicKey, Curve.X25519);
|
|
2156
|
-
const privPtr = allocAndCopy(wasm, privateKey);
|
|
2157
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2206
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, privateKey);
|
|
2207
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2158
2208
|
const secretPtr = wasm._hd_alloc(32);
|
|
2159
2209
|
try {
|
|
2160
2210
|
checkResult(wasm._hd_ecdh_x25519(privPtr, pubPtr, secretPtr, 32));
|
|
@@ -2233,10 +2283,10 @@ function createModule(wasm) {
|
|
|
2233
2283
|
const fn = requireWasmFunction(wasm, '_hd_coin_address_from_pubkey');
|
|
2234
2284
|
publicKey = coinPublicKey(coinType, publicKey);
|
|
2235
2285
|
V.oneOf(network, [Network.MAINNET, Network.TESTNET], 'network');
|
|
2236
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2286
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2237
2287
|
const outPtr = wasm._hd_alloc(128);
|
|
2238
2288
|
try {
|
|
2239
|
-
const result = fn(coinType, network, pubPtr,
|
|
2289
|
+
const result = fn(coinType, network, pubPtr, pubLen, outPtr, 128);
|
|
2240
2290
|
checkResult(result);
|
|
2241
2291
|
return readString(wasm, outPtr);
|
|
2242
2292
|
} finally {
|
|
@@ -2276,20 +2326,20 @@ function createModule(wasm) {
|
|
|
2276
2326
|
const fn = requireWasmFunction(wasm, '_hd_coin_sign_message');
|
|
2277
2327
|
V.bytes(message, 'message');
|
|
2278
2328
|
V.privateKey(wasm, privateKey, coinCurve(coinType));
|
|
2279
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
2280
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2329
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2330
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2281
2331
|
const sigLenPtr = wasm._hd_alloc(4);
|
|
2282
2332
|
// Pre-allocate enough for the largest possible signature (65 bytes for ECDSA recoverable)
|
|
2283
2333
|
const maxSigLen = 128;
|
|
2284
2334
|
wasm.setValue(sigLenPtr, maxSigLen, 'i32');
|
|
2285
2335
|
const sigPtr = wasm._hd_alloc(maxSigLen);
|
|
2286
2336
|
try {
|
|
2287
|
-
const result = fn(coinType, msgPtr,
|
|
2337
|
+
const result = fn(coinType, msgPtr, msgLen, keyPtr, sigPtr, sigLenPtr);
|
|
2288
2338
|
checkResult(result);
|
|
2289
2339
|
const actualLen = checkLengthWithin(wasm.getValue(sigLenPtr, 'i32'), 1, maxSigLen);
|
|
2290
2340
|
return readBytes(wasm, sigPtr, actualLen);
|
|
2291
2341
|
} finally {
|
|
2292
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
2342
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
2293
2343
|
wasm._hd_dealloc(msgPtr);
|
|
2294
2344
|
wasm._hd_dealloc(keyPtr);
|
|
2295
2345
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -2311,13 +2361,13 @@ function createModule(wasm) {
|
|
|
2311
2361
|
V.bytes(message, 'message');
|
|
2312
2362
|
V.bytes(signature, 'signature');
|
|
2313
2363
|
V.bytes(publicKey, 'publicKey');
|
|
2314
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
2315
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
2316
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2364
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
2365
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
2366
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2317
2367
|
try {
|
|
2318
2368
|
// The export takes every length: any failure (a malformed signature
|
|
2319
2369
|
// or key included) is "not verified".
|
|
2320
|
-
return fn(coinType, msgPtr,
|
|
2370
|
+
return fn(coinType, msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen) === 1;
|
|
2321
2371
|
} finally {
|
|
2322
2372
|
wasm._hd_dealloc(msgPtr);
|
|
2323
2373
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -2370,7 +2420,7 @@ function createModule(wasm) {
|
|
|
2370
2420
|
default:
|
|
2371
2421
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'Invalid address type');
|
|
2372
2422
|
}
|
|
2373
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2423
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2374
2424
|
const outPtr = wasm._hd_alloc(128);
|
|
2375
2425
|
try {
|
|
2376
2426
|
let fnName;
|
|
@@ -2394,7 +2444,7 @@ function createModule(wasm) {
|
|
|
2394
2444
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'Invalid address type');
|
|
2395
2445
|
}
|
|
2396
2446
|
const addressFn = requireWasmFunction(wasm, fnName);
|
|
2397
|
-
const result = addressFn(pubPtr,
|
|
2447
|
+
const result = addressFn(pubPtr, pubLen, network, outPtr, 128);
|
|
2398
2448
|
checkResult(result);
|
|
2399
2449
|
return readString(wasm, outPtr);
|
|
2400
2450
|
} finally {
|
|
@@ -2462,7 +2512,7 @@ function createModule(wasm) {
|
|
|
2462
2512
|
const toWifFn = requireWasmFunction(wasm, '_hd_btc_to_wif');
|
|
2463
2513
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
2464
2514
|
V.oneOf(network, [Network.MAINNET, Network.TESTNET], 'network');
|
|
2465
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2515
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2466
2516
|
const outPtr = wasm._hd_alloc(64);
|
|
2467
2517
|
try {
|
|
2468
2518
|
const result = toWifFn(keyPtr, compressed ? 1 : 0, network, outPtr, 64);
|
|
@@ -2500,7 +2550,7 @@ function createModule(wasm) {
|
|
|
2500
2550
|
V.string(message, 'message');
|
|
2501
2551
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
2502
2552
|
const msgPtr = allocString(wasm, message);
|
|
2503
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2553
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2504
2554
|
const sigPtr = wasm._hd_alloc(65);
|
|
2505
2555
|
try {
|
|
2506
2556
|
const result = signFn(msgPtr, keyPtr, compressed ? 1 : 0, sigPtr, 65);
|
|
@@ -2528,12 +2578,12 @@ function createModule(wasm) {
|
|
|
2528
2578
|
} catch {
|
|
2529
2579
|
return false;
|
|
2530
2580
|
}
|
|
2531
|
-
if (sigBytes
|
|
2581
|
+
if (V.byteLength(sigBytes) !== 65) return false;
|
|
2532
2582
|
const msgPtr = allocString(wasm, message);
|
|
2533
|
-
const sigPtr = allocAndCopy(wasm, sigBytes);
|
|
2583
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, sigBytes);
|
|
2534
2584
|
const addrPtr = allocString(wasm, address);
|
|
2535
2585
|
try {
|
|
2536
|
-
const result = verifyFn(msgPtr, sigPtr,
|
|
2586
|
+
const result = verifyFn(msgPtr, sigPtr, sigLen, addrPtr, network);
|
|
2537
2587
|
return result === 1;
|
|
2538
2588
|
} finally {
|
|
2539
2589
|
wasm._hd_dealloc(msgPtr);
|
|
@@ -2556,26 +2606,28 @@ function createModule(wasm) {
|
|
|
2556
2606
|
if (input === null || typeof input !== 'object') {
|
|
2557
2607
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'input must be an object');
|
|
2558
2608
|
}
|
|
2609
|
+
// Each field is read once; only these values are used below.
|
|
2610
|
+
const { txid, vout, amount: amountArg, scriptType: scriptTypeArg, sequence: sequenceArg, pubkey } = input;
|
|
2559
2611
|
// The txid: 32 bytes as 64 hex digits, in the given byte order.
|
|
2560
|
-
const txidBytes = typeof
|
|
2561
|
-
? hexOrNull(
|
|
2612
|
+
const txidBytes = typeof txid === 'string' && txid.length === 64
|
|
2613
|
+
? hexOrNull(txid)
|
|
2562
2614
|
: null;
|
|
2563
2615
|
if (txidBytes === null) {
|
|
2564
2616
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'txid must be 64 hex digits');
|
|
2565
2617
|
}
|
|
2566
|
-
V.uint32(
|
|
2567
|
-
const amount = V.unsignedBigInt(
|
|
2568
|
-
const scriptType =
|
|
2618
|
+
V.uint32(vout, 'vout');
|
|
2619
|
+
const amount = V.unsignedBigInt(amountArg, 'amount', 64);
|
|
2620
|
+
const scriptType = scriptTypeArg || 0;
|
|
2569
2621
|
V.integer(scriptType, 'scriptType', 0, BitcoinScriptType.MULTISIG);
|
|
2570
|
-
const sequence =
|
|
2622
|
+
const sequence = sequenceArg || 0xffffffff;
|
|
2571
2623
|
V.uint32(sequence, 'sequence');
|
|
2572
2624
|
// The export reads a 33-byte compressed key.
|
|
2573
|
-
V.publicKey(wasm,
|
|
2574
|
-
const txidPtr = allocAndCopy(wasm, txidBytes);
|
|
2575
|
-
const pubPtr = allocAndCopy(wasm,
|
|
2625
|
+
V.publicKey(wasm, pubkey, Curve.SECP256K1, 'pubkey', [33]);
|
|
2626
|
+
const { ptr: txidPtr } = allocAndCopy(wasm, txidBytes);
|
|
2627
|
+
const { ptr: pubPtr } = allocAndCopy(wasm, pubkey);
|
|
2576
2628
|
try {
|
|
2577
2629
|
const result = addInputFn(
|
|
2578
|
-
this._handle, txidPtr,
|
|
2630
|
+
this._handle, txidPtr, vout,
|
|
2579
2631
|
amount, scriptType,
|
|
2580
2632
|
pubPtr, sequence
|
|
2581
2633
|
);
|
|
@@ -2591,6 +2643,9 @@ function createModule(wasm) {
|
|
|
2591
2643
|
addOutput(address, amount, network = Network.MAINNET) {
|
|
2592
2644
|
V.string(address, 'address');
|
|
2593
2645
|
amount = V.unsignedBigInt(amount, 'amount', 64);
|
|
2646
|
+
// The address must be of this network: a mainnet transaction never
|
|
2647
|
+
// pays a testnet address, or the reverse. Regtest is not supported.
|
|
2648
|
+
V.oneOf(network, [Network.MAINNET, Network.TESTNET], 'network');
|
|
2594
2649
|
// Use address-based output helper: decode address to script internally
|
|
2595
2650
|
const addP2wpkhFn = getWasmFunction(wasm, '_hd_btc_tx_add_p2wpkh_output');
|
|
2596
2651
|
const addP2pkhFn = getWasmFunction(wasm, '_hd_btc_tx_add_p2pkh_output');
|
|
@@ -2610,8 +2665,14 @@ function createModule(wasm) {
|
|
|
2610
2665
|
checkResult(decResult);
|
|
2611
2666
|
const addrType = wasm.getValue(typePtr, 'i32');
|
|
2612
2667
|
const hashLen = checkLengthWithin(wasm.getValue(hashLenPtr, 'i32'), 1, 32);
|
|
2613
|
-
|
|
2614
|
-
|
|
2668
|
+
if (wasm.getValue(networkPtr, 'i32') !== network) {
|
|
2669
|
+
throw new HDWalletError(ErrorCode.INVALID_ADDRESS, 'address is not of this transaction\'s network');
|
|
2670
|
+
}
|
|
2671
|
+
// The native decoder types an address by witness version and
|
|
2672
|
+
// program length together; each type has one payload length
|
|
2673
|
+
// (the P2WPKH/P2PKH helpers read a 20-byte key hash).
|
|
2674
|
+
const payloadLength = [20, 20, 20, 32, 32][addrType];
|
|
2675
|
+
if (payloadLength === undefined || hashLen !== payloadLength) {
|
|
2615
2676
|
throw new HDWalletError(ErrorCode.INVALID_ADDRESS);
|
|
2616
2677
|
}
|
|
2617
2678
|
// P2WPKH = 2, P2PKH = 0
|
|
@@ -2640,9 +2701,9 @@ function createModule(wasm) {
|
|
|
2640
2701
|
} else {
|
|
2641
2702
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'Unsupported address type');
|
|
2642
2703
|
}
|
|
2643
|
-
const scriptPtr = allocAndCopy(wasm, script);
|
|
2704
|
+
const { ptr: scriptPtr, len: scriptLen } = allocAndCopy(wasm, script);
|
|
2644
2705
|
try {
|
|
2645
|
-
const result = addOutputFn(this._handle, BigInt(amount), scriptPtr,
|
|
2706
|
+
const result = addOutputFn(this._handle, BigInt(amount), scriptPtr, scriptLen);
|
|
2646
2707
|
checkResult(result);
|
|
2647
2708
|
} finally {
|
|
2648
2709
|
wasm._hd_dealloc(scriptPtr);
|
|
@@ -2662,7 +2723,7 @@ function createModule(wasm) {
|
|
|
2662
2723
|
sign(privateKey) {
|
|
2663
2724
|
const signFn = requireWasmFunction(wasm, '_hd_btc_tx_sign');
|
|
2664
2725
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
2665
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2726
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2666
2727
|
try {
|
|
2667
2728
|
// Sign all inputs
|
|
2668
2729
|
for (let i = 0; i < this._inputCount; i++) {
|
|
@@ -2750,9 +2811,9 @@ function createModule(wasm) {
|
|
|
2750
2811
|
parse(data) {
|
|
2751
2812
|
const parseFn = requireWasmFunction(wasm, '_hd_btc_tx_parse');
|
|
2752
2813
|
V.bytes(data, 'data');
|
|
2753
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
2814
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
2754
2815
|
try {
|
|
2755
|
-
const handle = parseFn(dataPtr,
|
|
2816
|
+
const handle = parseFn(dataPtr, dataLen);
|
|
2756
2817
|
if (!handle) throw new HDWalletError(ErrorCode.INVALID_TRANSACTION);
|
|
2757
2818
|
return this._makeTxObj(handle);
|
|
2758
2819
|
} finally {
|
|
@@ -2785,7 +2846,7 @@ function createModule(wasm) {
|
|
|
2785
2846
|
getAddress(publicKey) {
|
|
2786
2847
|
const getAddressFn = requireWasmFunction(wasm, '_hd_eth_address');
|
|
2787
2848
|
V.bytesOfLength(publicKey, [33, 64, 65], 'publicKey', ErrorCode.INVALID_PUBLIC_KEY);
|
|
2788
|
-
if (publicKey
|
|
2849
|
+
if (V.byteLength(publicKey) === 64) {
|
|
2789
2850
|
// Raw x || y: valid when 04 || x || y is a point.
|
|
2790
2851
|
const sec1 = new Uint8Array(65);
|
|
2791
2852
|
sec1[0] = 0x04;
|
|
@@ -2794,10 +2855,10 @@ function createModule(wasm) {
|
|
|
2794
2855
|
} else {
|
|
2795
2856
|
V.publicKey(wasm, publicKey, Curve.SECP256K1);
|
|
2796
2857
|
}
|
|
2797
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
2858
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
2798
2859
|
const outPtr = wasm._hd_alloc(64);
|
|
2799
2860
|
try {
|
|
2800
|
-
const result = getAddressFn(pubPtr,
|
|
2861
|
+
const result = getAddressFn(pubPtr, pubLen, outPtr, 64);
|
|
2801
2862
|
checkResult(result);
|
|
2802
2863
|
return readString(wasm, outPtr);
|
|
2803
2864
|
} finally {
|
|
@@ -2852,11 +2913,11 @@ function createModule(wasm) {
|
|
|
2852
2913
|
const signFn = requireWasmFunction(wasm, '_hd_eth_sign_message');
|
|
2853
2914
|
const msgBytes = ethereumMessageBytes(message);
|
|
2854
2915
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
2855
|
-
const msgPtr = allocAndCopy(wasm, msgBytes);
|
|
2856
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
2916
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, msgBytes);
|
|
2917
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2857
2918
|
const sigPtr = wasm._hd_alloc(65);
|
|
2858
2919
|
try {
|
|
2859
|
-
const result = signFn(msgPtr,
|
|
2920
|
+
const result = signFn(msgPtr, msgLen, keyPtr, sigPtr, 65);
|
|
2860
2921
|
checkResult(result);
|
|
2861
2922
|
const sigBytes = readBytes(wasm, sigPtr, 65);
|
|
2862
2923
|
return '0x' + encodeHexFallback(sigBytes);
|
|
@@ -2888,10 +2949,10 @@ function createModule(wasm) {
|
|
|
2888
2949
|
// keccak256 via WASM
|
|
2889
2950
|
function k256(data) {
|
|
2890
2951
|
const d = data instanceof Uint8Array ? data : new TextEncoder().encode(data);
|
|
2891
|
-
const dPtr = allocAndCopy(wasm, d);
|
|
2952
|
+
const { ptr: dPtr, len: dLen } = allocAndCopy(wasm, d);
|
|
2892
2953
|
const hPtr = wasm._hd_alloc(32);
|
|
2893
2954
|
try {
|
|
2894
|
-
checkLength(wasm._hd_hash_keccak256(dPtr,
|
|
2955
|
+
checkLength(wasm._hd_hash_keccak256(dPtr, dLen, hPtr, 32), 32);
|
|
2895
2956
|
return readBytes(wasm, hPtr, 32);
|
|
2896
2957
|
} finally {
|
|
2897
2958
|
wasm._hd_dealloc(dPtr);
|
|
@@ -2983,8 +3044,8 @@ function createModule(wasm) {
|
|
|
2983
3044
|
const namePtr = allocString(wasm, domain.name || '');
|
|
2984
3045
|
const versionPtr = allocString(wasm, domain.version || '');
|
|
2985
3046
|
const contractPtr = allocString(wasm, domain.verifyingContract || '');
|
|
2986
|
-
const structHashPtr = allocAndCopy(wasm, structHash);
|
|
2987
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3047
|
+
const { ptr: structHashPtr, len: structHashLen } = allocAndCopy(wasm, structHash);
|
|
3048
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
2988
3049
|
const sigPtr = wasm._hd_alloc(65);
|
|
2989
3050
|
try {
|
|
2990
3051
|
const result = signTypedDataFn(namePtr, versionPtr, BigInt(domain.chainId || 0), contractPtr, structHashPtr, keyPtr, sigPtr, 65);
|
|
@@ -3017,14 +3078,14 @@ function createModule(wasm) {
|
|
|
3017
3078
|
const msgBytes = ethereumMessageBytes(message);
|
|
3018
3079
|
V.string(signature, 'signature');
|
|
3019
3080
|
const sigBytes = hexOrNull(signature);
|
|
3020
|
-
if (sigBytes === null || sigBytes
|
|
3081
|
+
if (sigBytes === null || V.byteLength(sigBytes) !== 65 || ![0, 1, 27, 28].includes(sigBytes[64])) {
|
|
3021
3082
|
throw new HDWalletError(ErrorCode.INVALID_SIGNATURE, 'signature must be 65 bytes r || s || v with v 0, 1, 27 or 28');
|
|
3022
3083
|
}
|
|
3023
|
-
const msgPtr = allocAndCopy(wasm, msgBytes);
|
|
3024
|
-
const sigPtr = allocAndCopy(wasm, sigBytes);
|
|
3084
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, msgBytes);
|
|
3085
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, sigBytes);
|
|
3025
3086
|
const addrPtr = wasm._hd_alloc(64);
|
|
3026
3087
|
try {
|
|
3027
|
-
const result = recoverFn(msgPtr,
|
|
3088
|
+
const result = recoverFn(msgPtr, msgLen, sigPtr, sigLen, addrPtr, 64);
|
|
3028
3089
|
checkResult(result);
|
|
3029
3090
|
return readString(wasm, addrPtr);
|
|
3030
3091
|
} finally {
|
|
@@ -3047,10 +3108,10 @@ function createModule(wasm) {
|
|
|
3047
3108
|
hashMessage(message) {
|
|
3048
3109
|
const hashFn = requireWasmFunction(wasm, '_hd_eth_hash_message');
|
|
3049
3110
|
const msgBytes = ethereumMessageBytes(message);
|
|
3050
|
-
const msgPtr = allocAndCopy(wasm, msgBytes);
|
|
3111
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, msgBytes);
|
|
3051
3112
|
const hashPtr = wasm._hd_alloc(32);
|
|
3052
3113
|
try {
|
|
3053
|
-
const result = hashFn(msgPtr,
|
|
3114
|
+
const result = hashFn(msgPtr, msgLen, hashPtr);
|
|
3054
3115
|
checkResult(result);
|
|
3055
3116
|
return readBytes(wasm, hashPtr, 32);
|
|
3056
3117
|
} finally {
|
|
@@ -3067,7 +3128,7 @@ function createModule(wasm) {
|
|
|
3067
3128
|
sign(privateKey) {
|
|
3068
3129
|
const signFn = requireWasmFunction(wasm, '_hd_eth_tx_sign');
|
|
3069
3130
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
3070
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3131
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3071
3132
|
try {
|
|
3072
3133
|
const result = signFn(this._handle, keyPtr);
|
|
3073
3134
|
checkResult(result);
|
|
@@ -3116,31 +3177,54 @@ function createModule(wasm) {
|
|
|
3116
3177
|
};
|
|
3117
3178
|
},
|
|
3118
3179
|
|
|
3119
|
-
//
|
|
3120
|
-
//
|
|
3121
|
-
//
|
|
3122
|
-
|
|
3180
|
+
// Read each field of `params` once (a getter or a Uint8Array subclass
|
|
3181
|
+
// could answer differently on a second read: a longer `length` put heap
|
|
3182
|
+
// bytes into the signed data) and check it. The nonce and the chain ID
|
|
3183
|
+
// have no defaults: a missing nonce signed nonce 0, a missing chain ID
|
|
3184
|
+
// chain 1. The native setters take uint64 (a 256-bit value as 32 bytes);
|
|
3185
|
+
// a larger or negative number would wrap modulo 2^64, so it is refused.
|
|
3186
|
+
_readParams(params) {
|
|
3123
3187
|
if (params === null || typeof params !== 'object') {
|
|
3124
3188
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'params must be an object');
|
|
3125
3189
|
}
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3190
|
+
const {
|
|
3191
|
+
nonce, chainId, gasLimit, gasPrice, maxFeePerGas, maxPriorityFeePerGas, to, value, data,
|
|
3192
|
+
} = params;
|
|
3193
|
+
if (nonce === undefined || nonce === null) {
|
|
3194
|
+
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'nonce is required');
|
|
3195
|
+
}
|
|
3196
|
+
if (chainId === undefined || chainId === null) {
|
|
3197
|
+
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'chainId is required');
|
|
3198
|
+
}
|
|
3199
|
+
const fields = {
|
|
3200
|
+
nonce: V.unsignedBigInt(nonce, 'nonce', 64),
|
|
3201
|
+
chainId: V.unsignedBigInt(chainId, 'chainId', 64),
|
|
3202
|
+
gasLimit: gasLimit === undefined ? undefined : V.unsignedBigInt(gasLimit, 'gasLimit', 64),
|
|
3203
|
+
gasPrice: gasPrice === undefined ? undefined : V.unsignedBigInt(gasPrice, 'gasPrice', 64),
|
|
3204
|
+
maxFeePerGas,
|
|
3205
|
+
maxPriorityFeePerGas,
|
|
3206
|
+
to: to === undefined || to === null || to === '' ? undefined : V.string(to, 'to'),
|
|
3207
|
+
value: value === undefined ? undefined : V.unsignedBigInt(value, 'value', 256),
|
|
3208
|
+
// A copy made from the array's own bytes and length.
|
|
3209
|
+
data: data === undefined || data === null ? undefined : new Uint8Array(V.bytes(data, 'data')),
|
|
3132
3210
|
};
|
|
3211
|
+
// EIP-2294: 1 <= chainId <= floor(MAX_UINT64 / 2) - 36, so a legacy
|
|
3212
|
+
// v = 2 * chainId + 35 + recovery id fits 64 bits.
|
|
3213
|
+
if (fields.chainId === 0n || fields.chainId > ETH_MAX_CHAIN_ID) {
|
|
3214
|
+
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, `chainId must be from 1 to ${ETH_MAX_CHAIN_ID}`);
|
|
3215
|
+
}
|
|
3216
|
+
return fields;
|
|
3133
3217
|
},
|
|
3134
3218
|
|
|
3135
|
-
_setCommonFields(handle,
|
|
3219
|
+
_setCommonFields(handle, fields) {
|
|
3136
3220
|
requireWasmFunction(wasm, '_hd_eth_tx_set_nonce')(handle, fields.nonce);
|
|
3137
3221
|
if (fields.gasLimit !== undefined) {
|
|
3138
3222
|
requireWasmFunction(wasm, '_hd_eth_tx_set_gas_limit')(handle, fields.gasLimit);
|
|
3139
3223
|
}
|
|
3140
3224
|
|
|
3141
|
-
if (
|
|
3225
|
+
if (fields.to !== undefined) {
|
|
3142
3226
|
const setToFn = requireWasmFunction(wasm, '_hd_eth_tx_set_to_hex');
|
|
3143
|
-
const toPtr = allocString(wasm,
|
|
3227
|
+
const toPtr = allocString(wasm, fields.to);
|
|
3144
3228
|
try {
|
|
3145
3229
|
// An address that does not parse fails here. Without a recipient
|
|
3146
3230
|
// the transaction does not serialize or sign (it would otherwise
|
|
@@ -3156,7 +3240,7 @@ function createModule(wasm) {
|
|
|
3156
3240
|
const setValueFn = requireWasmFunction(wasm, '_hd_eth_tx_set_value_256');
|
|
3157
3241
|
const valueBytes = new Uint8Array(32);
|
|
3158
3242
|
for (let i = 31, v = fields.value; i >= 0 && v > 0n; i--, v >>= 8n) valueBytes[i] = Number(v & 0xffn);
|
|
3159
|
-
const valuePtr = allocAndCopy(wasm, valueBytes);
|
|
3243
|
+
const { ptr: valuePtr, len: valueLen } = allocAndCopy(wasm, valueBytes);
|
|
3160
3244
|
try {
|
|
3161
3245
|
setValueFn(handle, valuePtr);
|
|
3162
3246
|
} finally {
|
|
@@ -3164,31 +3248,32 @@ function createModule(wasm) {
|
|
|
3164
3248
|
}
|
|
3165
3249
|
}
|
|
3166
3250
|
|
|
3167
|
-
if (
|
|
3251
|
+
if (fields.data !== undefined) {
|
|
3168
3252
|
const setDataFn = requireWasmFunction(wasm, '_hd_eth_tx_set_data');
|
|
3169
|
-
const dataPtr = allocAndCopy(wasm,
|
|
3253
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, fields.data);
|
|
3170
3254
|
try {
|
|
3171
|
-
setDataFn(handle, dataPtr,
|
|
3255
|
+
setDataFn(handle, dataPtr, dataLen);
|
|
3172
3256
|
} finally {
|
|
3173
3257
|
wasm._hd_dealloc(dataPtr);
|
|
3174
3258
|
}
|
|
3175
3259
|
}
|
|
3176
3260
|
},
|
|
3177
3261
|
|
|
3262
|
+
// EIP-1559 transaction. nonce, chainId (>= 1), gasLimit, maxFeePerGas
|
|
3263
|
+
// and maxPriorityFeePerGas are required.
|
|
3178
3264
|
createEIP1559(params) {
|
|
3179
3265
|
const createFn = requireWasmFunction(wasm, '_hd_eth_tx_create_eip1559');
|
|
3180
|
-
const fields = this.
|
|
3266
|
+
const fields = this._readParams(params);
|
|
3181
3267
|
if (fields.gasLimit === undefined) {
|
|
3182
3268
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'gasLimit is required');
|
|
3183
3269
|
}
|
|
3184
|
-
const
|
|
3185
|
-
const
|
|
3186
|
-
const
|
|
3187
|
-
const handle = createFn(chainId, maxPriorityFeePerGas, maxFeePerGas);
|
|
3270
|
+
const maxPriorityFeePerGas = V.unsignedBigInt(fields.maxPriorityFeePerGas, 'maxPriorityFeePerGas', 64);
|
|
3271
|
+
const maxFeePerGas = V.unsignedBigInt(fields.maxFeePerGas, 'maxFeePerGas', 64);
|
|
3272
|
+
const handle = createFn(fields.chainId, maxPriorityFeePerGas, maxFeePerGas);
|
|
3188
3273
|
if (!handle) throw new HDWalletError(ErrorCode.NOT_SUPPORTED);
|
|
3189
3274
|
|
|
3190
3275
|
try {
|
|
3191
|
-
this._setCommonFields(handle,
|
|
3276
|
+
this._setCommonFields(handle, fields);
|
|
3192
3277
|
} catch (error) {
|
|
3193
3278
|
requireWasmFunction(wasm, '_hd_eth_tx_destroy')(handle);
|
|
3194
3279
|
throw error;
|
|
@@ -3197,19 +3282,18 @@ function createModule(wasm) {
|
|
|
3197
3282
|
return this._makeTxObj(handle);
|
|
3198
3283
|
},
|
|
3199
3284
|
|
|
3200
|
-
// Legacy (EIP-155) transaction.
|
|
3201
|
-
//
|
|
3285
|
+
// Legacy (EIP-155) transaction. nonce and chainId (>= 1) are required.
|
|
3286
|
+
// Before 2.1.1 every field but chainId was ignored, so the declared
|
|
3287
|
+
// to/value/gasPrice never reached the signed bytes.
|
|
3202
3288
|
create(params = {}) {
|
|
3203
3289
|
const createFn = requireWasmFunction(wasm, '_hd_eth_tx_create');
|
|
3204
|
-
const fields = this.
|
|
3205
|
-
const
|
|
3206
|
-
const gasPrice = params.gasPrice === undefined ? undefined : V.unsignedBigInt(params.gasPrice, 'gasPrice', 64);
|
|
3207
|
-
const handle = createFn(chainId);
|
|
3290
|
+
const fields = this._readParams(params);
|
|
3291
|
+
const handle = createFn(fields.chainId);
|
|
3208
3292
|
if (!handle) throw new HDWalletError(ErrorCode.NOT_SUPPORTED);
|
|
3209
3293
|
|
|
3210
3294
|
try {
|
|
3211
|
-
if (gasPrice !== undefined) requireWasmFunction(wasm, '_hd_eth_tx_set_gas_price')(handle, gasPrice);
|
|
3212
|
-
this._setCommonFields(handle,
|
|
3295
|
+
if (fields.gasPrice !== undefined) requireWasmFunction(wasm, '_hd_eth_tx_set_gas_price')(handle, fields.gasPrice);
|
|
3296
|
+
this._setCommonFields(handle, fields);
|
|
3213
3297
|
} catch (error) {
|
|
3214
3298
|
requireWasmFunction(wasm, '_hd_eth_tx_destroy')(handle);
|
|
3215
3299
|
throw error;
|
|
@@ -3221,9 +3305,9 @@ function createModule(wasm) {
|
|
|
3221
3305
|
parse(data) {
|
|
3222
3306
|
const parseFn = requireWasmFunction(wasm, '_hd_eth_tx_parse');
|
|
3223
3307
|
V.bytes(data, 'data');
|
|
3224
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
3308
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3225
3309
|
try {
|
|
3226
|
-
const handle = parseFn(dataPtr,
|
|
3310
|
+
const handle = parseFn(dataPtr, dataLen);
|
|
3227
3311
|
if (!handle) throw new HDWalletError(ErrorCode.INVALID_TRANSACTION);
|
|
3228
3312
|
return this._makeTxObj(handle);
|
|
3229
3313
|
} finally {
|
|
@@ -3246,11 +3330,11 @@ function createModule(wasm) {
|
|
|
3246
3330
|
const getAddressFn = requireWasmFunction(wasm, '_hd_cosmos_address');
|
|
3247
3331
|
V.publicKey(wasm, publicKey, Curve.SECP256K1, 'publicKey', [33]);
|
|
3248
3332
|
V.string(prefix, 'prefix');
|
|
3249
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3333
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3250
3334
|
const prefixPtr = allocString(wasm, prefix);
|
|
3251
3335
|
const outPtr = wasm._hd_alloc(128);
|
|
3252
3336
|
try {
|
|
3253
|
-
const result = getAddressFn(pubPtr,
|
|
3337
|
+
const result = getAddressFn(pubPtr, pubLen, prefixPtr, outPtr, 128);
|
|
3254
3338
|
checkResult(result);
|
|
3255
3339
|
return readString(wasm, outPtr);
|
|
3256
3340
|
} finally {
|
|
@@ -3301,11 +3385,11 @@ function createModule(wasm) {
|
|
|
3301
3385
|
const jsonStr = JSON.stringify(doc);
|
|
3302
3386
|
const enc = new TextEncoder();
|
|
3303
3387
|
const docBytes = enc.encode(jsonStr);
|
|
3304
|
-
const docPtr = allocAndCopy(wasm, docBytes);
|
|
3305
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3388
|
+
const { ptr: docPtr, len: docLen } = allocAndCopy(wasm, docBytes);
|
|
3389
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3306
3390
|
const sigPtr = wasm._hd_alloc(64);
|
|
3307
3391
|
try {
|
|
3308
|
-
const result = signAminoFn(docPtr,
|
|
3392
|
+
const result = signAminoFn(docPtr, docLen, keyPtr, sigPtr, 64);
|
|
3309
3393
|
checkResult(result);
|
|
3310
3394
|
return readBytes(wasm, sigPtr, 64);
|
|
3311
3395
|
} finally {
|
|
@@ -3324,11 +3408,11 @@ function createModule(wasm) {
|
|
|
3324
3408
|
const [signDocBytes, privateKey] = args;
|
|
3325
3409
|
V.bytes(signDocBytes, 'signDocBytes');
|
|
3326
3410
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
3327
|
-
const docPtr = allocAndCopy(wasm, signDocBytes);
|
|
3328
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3411
|
+
const { ptr: docPtr, len: docLen } = allocAndCopy(wasm, signDocBytes);
|
|
3412
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3329
3413
|
const sigPtr = wasm._hd_alloc(64);
|
|
3330
3414
|
try {
|
|
3331
|
-
const result = signDirectFn(docPtr,
|
|
3415
|
+
const result = signDirectFn(docPtr, docLen, keyPtr, sigPtr, 64);
|
|
3332
3416
|
checkResult(result);
|
|
3333
3417
|
return readBytes(wasm, sigPtr, 64);
|
|
3334
3418
|
} finally {
|
|
@@ -3342,9 +3426,10 @@ function createModule(wasm) {
|
|
|
3342
3426
|
if (args.length !== 5) {
|
|
3343
3427
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'signDirect takes (signDocBytes, privateKey) or (bodyBytes, authInfoBytes, chainId, accountNumber, privateKey)');
|
|
3344
3428
|
}
|
|
3345
|
-
const [
|
|
3346
|
-
|
|
3347
|
-
V.
|
|
3429
|
+
const [bodyArg, authInfoArg, chainId, accountNumber, privateKey] = args;
|
|
3430
|
+
// Copies read once: the lengths below size the SignDoc.
|
|
3431
|
+
const bodyBytes = V.snapshot(bodyArg, 'bodyBytes');
|
|
3432
|
+
const authInfoBytes = V.snapshot(authInfoArg, 'authInfoBytes');
|
|
3348
3433
|
V.string(chainId, 'chainId');
|
|
3349
3434
|
V.unsignedBigInt(accountNumber, 'accountNumber', 64);
|
|
3350
3435
|
V.privateKey(wasm, privateKey, Curve.SECP256K1);
|
|
@@ -3366,11 +3451,11 @@ function createModule(wasm) {
|
|
|
3366
3451
|
for (let i = 0; i < 8; i++) {
|
|
3367
3452
|
signDoc[off + i] = Number((accNum >> BigInt(i * 8)) & 0xFFn);
|
|
3368
3453
|
}
|
|
3369
|
-
const docPtr = allocAndCopy(wasm, signDoc);
|
|
3370
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3454
|
+
const { ptr: docPtr, len: docLen } = allocAndCopy(wasm, signDoc);
|
|
3455
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3371
3456
|
const sigPtr = wasm._hd_alloc(64);
|
|
3372
3457
|
try {
|
|
3373
|
-
const result = signDirectFn(docPtr,
|
|
3458
|
+
const result = signDirectFn(docPtr, docLen, keyPtr, sigPtr, 64);
|
|
3374
3459
|
checkResult(result);
|
|
3375
3460
|
return readBytes(wasm, sigPtr, 64);
|
|
3376
3461
|
} finally {
|
|
@@ -3387,12 +3472,12 @@ function createModule(wasm) {
|
|
|
3387
3472
|
V.bytes(message, 'message');
|
|
3388
3473
|
V.bytes(signature, 'signature');
|
|
3389
3474
|
V.bytes(publicKey, 'publicKey');
|
|
3390
|
-
if (signature
|
|
3391
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3392
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
3393
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3475
|
+
if (V.byteLength(signature) !== 64 || V.byteLength(publicKey) !== 33) return false;
|
|
3476
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3477
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
3478
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3394
3479
|
try {
|
|
3395
|
-
return verifyFn(msgPtr,
|
|
3480
|
+
return verifyFn(msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen) === 1;
|
|
3396
3481
|
} finally {
|
|
3397
3482
|
wasm._hd_dealloc(msgPtr);
|
|
3398
3483
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -3418,10 +3503,10 @@ function createModule(wasm) {
|
|
|
3418
3503
|
const getAddressFn = requireWasmFunction(wasm, '_hd_sol_address');
|
|
3419
3504
|
// Any 32 bytes: Solana addresses include off-curve program addresses.
|
|
3420
3505
|
V.bytesOfLength(publicKey, 32, 'publicKey', ErrorCode.INVALID_PUBLIC_KEY);
|
|
3421
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3506
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3422
3507
|
const outPtr = wasm._hd_alloc(64);
|
|
3423
3508
|
try {
|
|
3424
|
-
const result = getAddressFn(pubPtr,
|
|
3509
|
+
const result = getAddressFn(pubPtr, pubLen, outPtr, 64);
|
|
3425
3510
|
checkResult(result);
|
|
3426
3511
|
return readString(wasm, outPtr);
|
|
3427
3512
|
} finally {
|
|
@@ -3445,11 +3530,11 @@ function createModule(wasm) {
|
|
|
3445
3530
|
const signFn = requireWasmFunction(wasm, '_hd_sol_sign_message');
|
|
3446
3531
|
V.bytes(message, 'message');
|
|
3447
3532
|
V.privateKey(wasm, privateKey, Curve.ED25519);
|
|
3448
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3449
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3533
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3534
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3450
3535
|
const sigPtr = wasm._hd_alloc(64);
|
|
3451
3536
|
try {
|
|
3452
|
-
const result = signFn(msgPtr,
|
|
3537
|
+
const result = signFn(msgPtr, msgLen, keyPtr, sigPtr, 64);
|
|
3453
3538
|
checkResult(result);
|
|
3454
3539
|
return readBytes(wasm, sigPtr, 64);
|
|
3455
3540
|
} finally {
|
|
@@ -3465,12 +3550,12 @@ function createModule(wasm) {
|
|
|
3465
3550
|
V.bytes(message, 'message');
|
|
3466
3551
|
V.bytes(signature, 'signature');
|
|
3467
3552
|
V.bytes(publicKey, 'publicKey');
|
|
3468
|
-
if (signature
|
|
3469
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3470
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
3471
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3553
|
+
if (V.byteLength(signature) !== 64 || V.byteLength(publicKey) !== 32) return false;
|
|
3554
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3555
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
3556
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3472
3557
|
try {
|
|
3473
|
-
return verifyFn(msgPtr,
|
|
3558
|
+
return verifyFn(msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen) === 1;
|
|
3474
3559
|
} finally {
|
|
3475
3560
|
wasm._hd_dealloc(msgPtr);
|
|
3476
3561
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -3495,7 +3580,7 @@ function createModule(wasm) {
|
|
|
3495
3580
|
derivePubkey(privateKey) {
|
|
3496
3581
|
const fn = requireWasmFunction(wasm, '_hd_sol_derive_pubkey');
|
|
3497
3582
|
V.privateKey(wasm, privateKey, Curve.ED25519);
|
|
3498
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3583
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3499
3584
|
const outPtr = wasm._hd_alloc(32);
|
|
3500
3585
|
try {
|
|
3501
3586
|
const result = fn(keyPtr, outPtr, 32);
|
|
@@ -3513,25 +3598,31 @@ function createModule(wasm) {
|
|
|
3513
3598
|
// The export reads a 32-byte program id; Solana allows up to 16 seeds
|
|
3514
3599
|
// of up to 32 bytes.
|
|
3515
3600
|
V.bytesOfLength(programId, 32, 'programId', ErrorCode.INVALID_PUBLIC_KEY);
|
|
3516
|
-
|
|
3601
|
+
// The array and each seed are read once (an array or a Proxy could
|
|
3602
|
+
// answer a second read differently): the copies' lengths go to the heap.
|
|
3603
|
+
const count = Array.isArray(seeds) ? seeds.length : -1;
|
|
3604
|
+
if (!Number.isInteger(count) || count < 0 || count > 16) {
|
|
3517
3605
|
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'seeds must be an array of at most 16 seeds');
|
|
3518
3606
|
}
|
|
3519
|
-
|
|
3520
|
-
|
|
3607
|
+
const seedCopies = [];
|
|
3608
|
+
for (let i = 0; i < count; i++) {
|
|
3609
|
+
seedCopies.push(V.snapshot(V.bytesInRange(seeds[i], 0, 32, 'seed'), 'seed'));
|
|
3610
|
+
}
|
|
3611
|
+
const { ptr: progPtr } = allocAndCopy(wasm, programId);
|
|
3521
3612
|
let totalLen = 0;
|
|
3522
|
-
for (const s of
|
|
3613
|
+
for (const s of seedCopies) totalLen += s.length;
|
|
3523
3614
|
const flatSeeds = new Uint8Array(totalLen);
|
|
3524
3615
|
let off = 0;
|
|
3525
|
-
for (const s of
|
|
3526
|
-
const seedsPtr = totalLen > 0 ? allocAndCopy(wasm, flatSeeds) : 0;
|
|
3527
|
-
const seedLensPtr = wasm._hd_alloc(
|
|
3528
|
-
for (let i = 0; i <
|
|
3529
|
-
wasm.setValue(seedLensPtr + i * 4,
|
|
3616
|
+
for (const s of seedCopies) { flatSeeds.set(s, off); off += s.length; }
|
|
3617
|
+
const { ptr: seedsPtr } = totalLen > 0 ? allocAndCopy(wasm, flatSeeds) : { ptr: 0 };
|
|
3618
|
+
const seedLensPtr = wasm._hd_alloc(seedCopies.length * 4);
|
|
3619
|
+
for (let i = 0; i < seedCopies.length; i++) {
|
|
3620
|
+
wasm.setValue(seedLensPtr + i * 4, seedCopies[i].length, 'i32');
|
|
3530
3621
|
}
|
|
3531
3622
|
const addrPtr = wasm._hd_alloc(64);
|
|
3532
3623
|
const bumpPtr = wasm._hd_alloc(1);
|
|
3533
3624
|
try {
|
|
3534
|
-
const result = fn(progPtr, seedsPtr || 0, totalLen, seedLensPtr,
|
|
3625
|
+
const result = fn(progPtr, seedsPtr || 0, totalLen, seedLensPtr, seedCopies.length, addrPtr, 64, bumpPtr);
|
|
3535
3626
|
checkResult(result);
|
|
3536
3627
|
return {
|
|
3537
3628
|
address: readString(wasm, addrPtr),
|
|
@@ -3576,10 +3667,10 @@ function createModule(wasm) {
|
|
|
3576
3667
|
const getAddressFn = requireWasmFunction(wasm, '_hd_dot_address');
|
|
3577
3668
|
V.bytesOfLength(publicKey, 32, 'publicKey', ErrorCode.INVALID_PUBLIC_KEY);
|
|
3578
3669
|
V.integer(ss58Prefix, 'ss58Prefix', 0, 16383);
|
|
3579
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3670
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3580
3671
|
const outPtr = wasm._hd_alloc(64);
|
|
3581
3672
|
try {
|
|
3582
|
-
const result = getAddressFn(pubPtr,
|
|
3673
|
+
const result = getAddressFn(pubPtr, pubLen, ss58Prefix, outPtr, 64);
|
|
3583
3674
|
checkResult(result);
|
|
3584
3675
|
return readString(wasm, outPtr);
|
|
3585
3676
|
} finally {
|
|
@@ -3637,7 +3728,7 @@ function createModule(wasm) {
|
|
|
3637
3728
|
derivePubkey(privateKey) {
|
|
3638
3729
|
const fn = requireWasmFunction(wasm, '_hd_dot_derive_pubkey');
|
|
3639
3730
|
V.privateKey(wasm, privateKey, Curve.ED25519);
|
|
3640
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3731
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3641
3732
|
const outPtr = wasm._hd_alloc(32);
|
|
3642
3733
|
try {
|
|
3643
3734
|
const result = fn(keyPtr, outPtr, 32);
|
|
@@ -3654,11 +3745,11 @@ function createModule(wasm) {
|
|
|
3654
3745
|
const signFn = requireWasmFunction(wasm, '_hd_dot_sign_message');
|
|
3655
3746
|
V.bytes(message, 'message');
|
|
3656
3747
|
V.privateKey(wasm, privateKey, Curve.ED25519);
|
|
3657
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3658
|
-
const keyPtr = allocAndCopy(wasm, privateKey);
|
|
3748
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3749
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, privateKey);
|
|
3659
3750
|
const sigPtr = wasm._hd_alloc(64);
|
|
3660
3751
|
try {
|
|
3661
|
-
const result = signFn(msgPtr,
|
|
3752
|
+
const result = signFn(msgPtr, msgLen, keyPtr, sigPtr, 64);
|
|
3662
3753
|
checkResult(result);
|
|
3663
3754
|
return readBytes(wasm, sigPtr, 64);
|
|
3664
3755
|
} finally {
|
|
@@ -3674,12 +3765,12 @@ function createModule(wasm) {
|
|
|
3674
3765
|
V.bytes(message, 'message');
|
|
3675
3766
|
V.bytes(signature, 'signature');
|
|
3676
3767
|
V.bytes(publicKey, 'publicKey');
|
|
3677
|
-
if (signature
|
|
3678
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3679
|
-
const sigPtr = allocAndCopy(wasm, signature);
|
|
3680
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
3768
|
+
if (V.byteLength(signature) !== 64 || V.byteLength(publicKey) !== 32) return false;
|
|
3769
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3770
|
+
const { ptr: sigPtr, len: sigLen } = allocAndCopy(wasm, signature);
|
|
3771
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
3681
3772
|
try {
|
|
3682
|
-
return verifyFn(msgPtr,
|
|
3773
|
+
return verifyFn(msgPtr, msgLen, sigPtr, sigLen, pubPtr, pubLen) === 1;
|
|
3683
3774
|
} finally {
|
|
3684
3775
|
wasm._hd_dealloc(msgPtr);
|
|
3685
3776
|
wasm._hd_dealloc(sigPtr);
|
|
@@ -3775,10 +3866,10 @@ function createModule(wasm) {
|
|
|
3775
3866
|
|
|
3776
3867
|
async signTransaction(path, transaction) {
|
|
3777
3868
|
const pathPtr = allocString(wasm, path);
|
|
3778
|
-
const txPtr = allocAndCopy(wasm, transaction);
|
|
3869
|
+
const { ptr: txPtr, len: txLen } = allocAndCopy(wasm, transaction);
|
|
3779
3870
|
const sigPtr = wasm._hd_alloc(128);
|
|
3780
3871
|
try {
|
|
3781
|
-
const result = wasm._hd_hw_sign_transaction(this._handle, pathPtr, txPtr,
|
|
3872
|
+
const result = wasm._hd_hw_sign_transaction(this._handle, pathPtr, txPtr, txLen, sigPtr, 128);
|
|
3782
3873
|
checkResult(result);
|
|
3783
3874
|
return readBytes(wasm, sigPtr, 64);
|
|
3784
3875
|
} finally {
|
|
@@ -3843,13 +3934,13 @@ function createModule(wasm) {
|
|
|
3843
3934
|
addWallet(seed, name) {
|
|
3844
3935
|
const addWalletFn = getWasmFunction(wasm, '_hd_keyring_add_wallet');
|
|
3845
3936
|
if (!addWalletFn) return '';
|
|
3846
|
-
const seedPtr = allocAndCopy(wasm, seed);
|
|
3937
|
+
const { ptr: seedPtr, len: seedLen } = allocAndCopy(wasm, seed);
|
|
3847
3938
|
const namePtr = name ? allocString(wasm, name) : 0;
|
|
3848
3939
|
try {
|
|
3849
|
-
const ptr = addWalletFn(this._handle, seedPtr,
|
|
3940
|
+
const ptr = addWalletFn(this._handle, seedPtr, seedLen, namePtr);
|
|
3850
3941
|
return readString(wasm, ptr);
|
|
3851
3942
|
} finally {
|
|
3852
|
-
wasm._hd_secure_wipe(seedPtr,
|
|
3943
|
+
wasm._hd_secure_wipe(seedPtr, seedLen);
|
|
3853
3944
|
wasm._hd_dealloc(seedPtr);
|
|
3854
3945
|
if (namePtr) wasm._hd_dealloc(namePtr);
|
|
3855
3946
|
}
|
|
@@ -3887,10 +3978,10 @@ function createModule(wasm) {
|
|
|
3887
3978
|
const signTransactionFn = requireWasmFunction(wasm, '_hd_keyring_sign_transaction', ErrorCode.NOT_SUPPORTED, 'Keyring is not available in the WASM build');
|
|
3888
3979
|
const idPtr = allocString(wasm, walletId);
|
|
3889
3980
|
const pathPtr = allocString(wasm, path);
|
|
3890
|
-
const txPtr = allocAndCopy(wasm, transaction);
|
|
3981
|
+
const { ptr: txPtr, len: txLen } = allocAndCopy(wasm, transaction);
|
|
3891
3982
|
const sigPtr = wasm._hd_alloc(128);
|
|
3892
3983
|
try {
|
|
3893
|
-
const result = signTransactionFn(this._handle, idPtr, pathPtr, txPtr,
|
|
3984
|
+
const result = signTransactionFn(this._handle, idPtr, pathPtr, txPtr, txLen, sigPtr, 128);
|
|
3894
3985
|
checkResult(result);
|
|
3895
3986
|
return readBytes(wasm, sigPtr, 64);
|
|
3896
3987
|
} finally {
|
|
@@ -3905,10 +3996,10 @@ function createModule(wasm) {
|
|
|
3905
3996
|
const signMessageFn = requireWasmFunction(wasm, '_hd_keyring_sign_message', ErrorCode.NOT_SUPPORTED, 'Keyring is not available in the WASM build');
|
|
3906
3997
|
const idPtr = allocString(wasm, walletId);
|
|
3907
3998
|
const pathPtr = allocString(wasm, path);
|
|
3908
|
-
const msgPtr = allocAndCopy(wasm, message);
|
|
3999
|
+
const { ptr: msgPtr, len: msgLen } = allocAndCopy(wasm, message);
|
|
3909
4000
|
const sigPtr = wasm._hd_alloc(128);
|
|
3910
4001
|
try {
|
|
3911
|
-
const result = signMessageFn(this._handle, idPtr, pathPtr, msgPtr,
|
|
4002
|
+
const result = signMessageFn(this._handle, idPtr, pathPtr, msgPtr, msgLen, sigPtr, 128);
|
|
3912
4003
|
checkResult(result);
|
|
3913
4004
|
return readBytes(wasm, sigPtr, 64);
|
|
3914
4005
|
} finally {
|
|
@@ -3943,10 +4034,10 @@ function createModule(wasm) {
|
|
|
3943
4034
|
const utils = {
|
|
3944
4035
|
// Hashing
|
|
3945
4036
|
sha256(data) {
|
|
3946
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4037
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3947
4038
|
const hashPtr = wasm._hd_alloc(32);
|
|
3948
4039
|
try {
|
|
3949
|
-
checkLength(wasm._hd_hash_sha256(dataPtr,
|
|
4040
|
+
checkLength(wasm._hd_hash_sha256(dataPtr, dataLen, hashPtr, 32), 32);
|
|
3950
4041
|
return readBytes(wasm, hashPtr, 32);
|
|
3951
4042
|
} finally {
|
|
3952
4043
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -3955,10 +4046,10 @@ function createModule(wasm) {
|
|
|
3955
4046
|
},
|
|
3956
4047
|
|
|
3957
4048
|
sha512(data) {
|
|
3958
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4049
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3959
4050
|
const hashPtr = wasm._hd_alloc(64);
|
|
3960
4051
|
try {
|
|
3961
|
-
checkLength(wasm._hd_hash_sha512(dataPtr,
|
|
4052
|
+
checkLength(wasm._hd_hash_sha512(dataPtr, dataLen, hashPtr, 64), 64);
|
|
3962
4053
|
return readBytes(wasm, hashPtr, 64);
|
|
3963
4054
|
} finally {
|
|
3964
4055
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -3967,10 +4058,10 @@ function createModule(wasm) {
|
|
|
3967
4058
|
},
|
|
3968
4059
|
|
|
3969
4060
|
keccak256(data) {
|
|
3970
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4061
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3971
4062
|
const hashPtr = wasm._hd_alloc(32);
|
|
3972
4063
|
try {
|
|
3973
|
-
checkLength(wasm._hd_hash_keccak256(dataPtr,
|
|
4064
|
+
checkLength(wasm._hd_hash_keccak256(dataPtr, dataLen, hashPtr, 32), 32);
|
|
3974
4065
|
return readBytes(wasm, hashPtr, 32);
|
|
3975
4066
|
} finally {
|
|
3976
4067
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -3979,10 +4070,10 @@ function createModule(wasm) {
|
|
|
3979
4070
|
},
|
|
3980
4071
|
|
|
3981
4072
|
ripemd160(data) {
|
|
3982
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4073
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3983
4074
|
const hashPtr = wasm._hd_alloc(20);
|
|
3984
4075
|
try {
|
|
3985
|
-
checkLength(wasm._hd_hash_ripemd160(dataPtr,
|
|
4076
|
+
checkLength(wasm._hd_hash_ripemd160(dataPtr, dataLen, hashPtr, 20), 20);
|
|
3986
4077
|
return readBytes(wasm, hashPtr, 20);
|
|
3987
4078
|
} finally {
|
|
3988
4079
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -3991,10 +4082,10 @@ function createModule(wasm) {
|
|
|
3991
4082
|
},
|
|
3992
4083
|
|
|
3993
4084
|
hash160(data) {
|
|
3994
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4085
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
3995
4086
|
const hashPtr = wasm._hd_alloc(20);
|
|
3996
4087
|
try {
|
|
3997
|
-
checkLength(wasm._hd_hash_hash160(dataPtr,
|
|
4088
|
+
checkLength(wasm._hd_hash_hash160(dataPtr, dataLen, hashPtr, 20), 20);
|
|
3998
4089
|
return readBytes(wasm, hashPtr, 20);
|
|
3999
4090
|
} finally {
|
|
4000
4091
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -4005,10 +4096,10 @@ function createModule(wasm) {
|
|
|
4005
4096
|
blake2b(data, outputLength = 32) {
|
|
4006
4097
|
// The export checks the size against its 64-byte buffer.
|
|
4007
4098
|
V.integer(outputLength, 'outputLength', 0, 0x7fffffff);
|
|
4008
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4099
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
4009
4100
|
const hashPtr = wasm._hd_alloc(64);
|
|
4010
4101
|
try {
|
|
4011
|
-
checkLength(wasm._hd_hash_blake2b(dataPtr,
|
|
4102
|
+
checkLength(wasm._hd_hash_blake2b(dataPtr, dataLen, hashPtr, 64, outputLength), outputLength);
|
|
4012
4103
|
return readBytes(wasm, hashPtr, outputLength);
|
|
4013
4104
|
} finally {
|
|
4014
4105
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -4019,10 +4110,10 @@ function createModule(wasm) {
|
|
|
4019
4110
|
blake2s(data, outputLength = 32) {
|
|
4020
4111
|
// The export checks the size against its 32-byte buffer.
|
|
4021
4112
|
V.integer(outputLength, 'outputLength', 0, 0x7fffffff);
|
|
4022
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4113
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
4023
4114
|
const hashPtr = wasm._hd_alloc(32);
|
|
4024
4115
|
try {
|
|
4025
|
-
checkLength(wasm._hd_hash_blake2s(dataPtr,
|
|
4116
|
+
checkLength(wasm._hd_hash_blake2s(dataPtr, dataLen, hashPtr, 32, outputLength), outputLength);
|
|
4026
4117
|
return readBytes(wasm, hashPtr, outputLength);
|
|
4027
4118
|
} finally {
|
|
4028
4119
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -4037,15 +4128,15 @@ function createModule(wasm) {
|
|
|
4037
4128
|
V.bytes(info, 'info');
|
|
4038
4129
|
// The export refuses more than 255 blocks of output.
|
|
4039
4130
|
V.integer(length, 'length', 1, 0x3fffffff);
|
|
4040
|
-
const ikmPtr = allocAndCopy(wasm, ikm);
|
|
4041
|
-
const saltPtr = allocAndCopy(wasm, salt);
|
|
4042
|
-
const infoPtr = allocAndCopy(wasm, info);
|
|
4131
|
+
const { ptr: ikmPtr, len: ikmLen } = allocAndCopy(wasm, ikm);
|
|
4132
|
+
const { ptr: saltPtr, len: saltLen } = allocAndCopy(wasm, salt);
|
|
4133
|
+
const { ptr: infoPtr, len: infoLen } = allocAndCopy(wasm, info);
|
|
4043
4134
|
const outPtr = wasm._hd_alloc(length);
|
|
4044
4135
|
try {
|
|
4045
|
-
checkLength(wasm._hd_kdf_hkdf(ikmPtr,
|
|
4136
|
+
checkLength(wasm._hd_kdf_hkdf(ikmPtr, ikmLen, saltPtr, saltLen, infoPtr, infoLen, outPtr, length), length);
|
|
4046
4137
|
return readBytes(wasm, outPtr, length);
|
|
4047
4138
|
} finally {
|
|
4048
|
-
wasm._hd_secure_wipe(ikmPtr,
|
|
4139
|
+
wasm._hd_secure_wipe(ikmPtr, ikmLen);
|
|
4049
4140
|
wasm._hd_dealloc(ikmPtr);
|
|
4050
4141
|
wasm._hd_dealloc(saltPtr);
|
|
4051
4142
|
wasm._hd_dealloc(infoPtr);
|
|
@@ -4069,30 +4160,30 @@ function createModule(wasm) {
|
|
|
4069
4160
|
V.bytesOfLength(iv, 12, 'IV');
|
|
4070
4161
|
V.bytes(aad, 'aad');
|
|
4071
4162
|
|
|
4072
|
-
const keyPtr = allocAndCopy(wasm, key);
|
|
4073
|
-
const ptPtr = allocAndCopy(wasm, plaintext);
|
|
4074
|
-
const ivPtr = allocAndCopy(wasm, iv);
|
|
4075
|
-
const aadPtr = aad
|
|
4076
|
-
const ctPtr = wasm._hd_alloc(
|
|
4163
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, key);
|
|
4164
|
+
const { ptr: ptPtr, len: ptLen } = allocAndCopy(wasm, plaintext);
|
|
4165
|
+
const { ptr: ivPtr, len: ivLen } = allocAndCopy(wasm, iv);
|
|
4166
|
+
const { ptr: aadPtr, len: aadLen } = V.byteLength(aad) > 0 ? allocAndCopy(wasm, aad) : { ptr: 0, len: 0 };
|
|
4167
|
+
const ctPtr = wasm._hd_alloc(ptLen);
|
|
4077
4168
|
const tagPtr = wasm._hd_alloc(16);
|
|
4078
4169
|
|
|
4079
4170
|
try {
|
|
4080
4171
|
const result = wasm._hd_aes_gcm_encrypt(
|
|
4081
|
-
keyPtr,
|
|
4082
|
-
ptPtr,
|
|
4083
|
-
ivPtr,
|
|
4084
|
-
aadPtr,
|
|
4172
|
+
keyPtr, keyLen,
|
|
4173
|
+
ptPtr, ptLen,
|
|
4174
|
+
ivPtr, ivLen,
|
|
4175
|
+
aadPtr, aadLen,
|
|
4085
4176
|
ctPtr, tagPtr
|
|
4086
4177
|
);
|
|
4087
|
-
checkLength(result,
|
|
4178
|
+
checkLength(result, ptLen);
|
|
4088
4179
|
|
|
4089
4180
|
return {
|
|
4090
|
-
ciphertext: readBytes(wasm, ctPtr,
|
|
4181
|
+
ciphertext: readBytes(wasm, ctPtr, ptLen),
|
|
4091
4182
|
tag: readBytes(wasm, tagPtr, 16)
|
|
4092
4183
|
};
|
|
4093
4184
|
} finally {
|
|
4094
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4095
|
-
wasm._hd_secure_wipe(ptPtr,
|
|
4185
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4186
|
+
wasm._hd_secure_wipe(ptPtr, ptLen);
|
|
4096
4187
|
wasm._hd_dealloc(keyPtr);
|
|
4097
4188
|
wasm._hd_dealloc(ptPtr);
|
|
4098
4189
|
wasm._hd_dealloc(ivPtr);
|
|
@@ -4119,22 +4210,22 @@ function createModule(wasm) {
|
|
|
4119
4210
|
V.bytesOfLength(iv, 12, 'IV');
|
|
4120
4211
|
V.bytes(aad, 'aad');
|
|
4121
4212
|
|
|
4122
|
-
const keyPtr = allocAndCopy(wasm, key);
|
|
4123
|
-
const ctPtr = allocAndCopy(wasm, ciphertext);
|
|
4124
|
-
const ivPtr = allocAndCopy(wasm, iv);
|
|
4125
|
-
const tagPtr = allocAndCopy(wasm, tag);
|
|
4126
|
-
const aadPtr = aad
|
|
4127
|
-
const ptPtr = wasm._hd_alloc(
|
|
4213
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, key);
|
|
4214
|
+
const { ptr: ctPtr, len: ctLen } = allocAndCopy(wasm, ciphertext);
|
|
4215
|
+
const { ptr: ivPtr, len: ivLen } = allocAndCopy(wasm, iv);
|
|
4216
|
+
const { ptr: tagPtr, len: tagLen } = allocAndCopy(wasm, tag);
|
|
4217
|
+
const { ptr: aadPtr, len: aadLen } = V.byteLength(aad) > 0 ? allocAndCopy(wasm, aad) : { ptr: 0, len: 0 };
|
|
4218
|
+
const ptPtr = wasm._hd_alloc(ctLen);
|
|
4128
4219
|
|
|
4129
4220
|
try {
|
|
4130
4221
|
const result = wasm._hd_aes_gcm_decrypt(
|
|
4131
|
-
keyPtr,
|
|
4132
|
-
ctPtr,
|
|
4133
|
-
ivPtr,
|
|
4134
|
-
aadPtr,
|
|
4222
|
+
keyPtr, keyLen,
|
|
4223
|
+
ctPtr, ctLen,
|
|
4224
|
+
ivPtr, ivLen,
|
|
4225
|
+
aadPtr, aadLen,
|
|
4135
4226
|
tagPtr, ptPtr
|
|
4136
4227
|
);
|
|
4137
|
-
if (result !==
|
|
4228
|
+
if (result !== ctLen) {
|
|
4138
4229
|
const code = nativeErrorCode(result);
|
|
4139
4230
|
throw new HDWalletError(
|
|
4140
4231
|
code,
|
|
@@ -4142,15 +4233,15 @@ function createModule(wasm) {
|
|
|
4142
4233
|
);
|
|
4143
4234
|
}
|
|
4144
4235
|
|
|
4145
|
-
return readBytes(wasm, ptPtr,
|
|
4236
|
+
return readBytes(wasm, ptPtr, ctLen);
|
|
4146
4237
|
} finally {
|
|
4147
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4238
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4148
4239
|
wasm._hd_dealloc(keyPtr);
|
|
4149
4240
|
wasm._hd_dealloc(ctPtr);
|
|
4150
4241
|
wasm._hd_dealloc(ivPtr);
|
|
4151
4242
|
wasm._hd_dealloc(tagPtr);
|
|
4152
4243
|
if (aadPtr) wasm._hd_dealloc(aadPtr);
|
|
4153
|
-
wasm._hd_secure_wipe(ptPtr,
|
|
4244
|
+
wasm._hd_secure_wipe(ptPtr, ctLen);
|
|
4154
4245
|
wasm._hd_dealloc(ptPtr);
|
|
4155
4246
|
}
|
|
4156
4247
|
}
|
|
@@ -4186,14 +4277,14 @@ function createModule(wasm) {
|
|
|
4186
4277
|
V.bytes(salt, 'salt');
|
|
4187
4278
|
V.integer(iterations, 'iterations', 1, 0x7fffffff);
|
|
4188
4279
|
V.integer(length, 'length', 1, 0x3fffffff);
|
|
4189
|
-
const pwdPtr = allocAndCopy(wasm, password);
|
|
4190
|
-
const saltPtr = allocAndCopy(wasm, salt);
|
|
4280
|
+
const { ptr: pwdPtr, len: pwdLen } = allocAndCopy(wasm, password);
|
|
4281
|
+
const { ptr: saltPtr, len: saltLen } = allocAndCopy(wasm, salt);
|
|
4191
4282
|
const outPtr = wasm._hd_alloc(length);
|
|
4192
4283
|
try {
|
|
4193
|
-
checkLength(wasm._hd_kdf_pbkdf2(pwdPtr,
|
|
4284
|
+
checkLength(wasm._hd_kdf_pbkdf2(pwdPtr, pwdLen, saltPtr, saltLen, iterations, outPtr, length), length);
|
|
4194
4285
|
return readBytes(wasm, outPtr, length);
|
|
4195
4286
|
} finally {
|
|
4196
|
-
wasm._hd_secure_wipe(pwdPtr,
|
|
4287
|
+
wasm._hd_secure_wipe(pwdPtr, pwdLen);
|
|
4197
4288
|
wasm._hd_dealloc(pwdPtr);
|
|
4198
4289
|
wasm._hd_dealloc(saltPtr);
|
|
4199
4290
|
wasm._hd_dealloc(outPtr);
|
|
@@ -4207,14 +4298,14 @@ function createModule(wasm) {
|
|
|
4207
4298
|
V.integer(r, 'r', 1, 0x7fffffff);
|
|
4208
4299
|
V.integer(p, 'p', 1, 0x7fffffff);
|
|
4209
4300
|
V.integer(length, 'length', 1, 0x3fffffff);
|
|
4210
|
-
const pwdPtr = allocAndCopy(wasm, password);
|
|
4211
|
-
const saltPtr = allocAndCopy(wasm, salt);
|
|
4301
|
+
const { ptr: pwdPtr, len: pwdLen } = allocAndCopy(wasm, password);
|
|
4302
|
+
const { ptr: saltPtr, len: saltLen } = allocAndCopy(wasm, salt);
|
|
4212
4303
|
const outPtr = wasm._hd_alloc(length);
|
|
4213
4304
|
try {
|
|
4214
|
-
checkLength(wasm._hd_kdf_scrypt(pwdPtr,
|
|
4305
|
+
checkLength(wasm._hd_kdf_scrypt(pwdPtr, pwdLen, saltPtr, saltLen, BigInt(n), r, p, outPtr, length), length);
|
|
4215
4306
|
return readBytes(wasm, outPtr, length);
|
|
4216
4307
|
} finally {
|
|
4217
|
-
wasm._hd_secure_wipe(pwdPtr,
|
|
4308
|
+
wasm._hd_secure_wipe(pwdPtr, pwdLen);
|
|
4218
4309
|
wasm._hd_dealloc(pwdPtr);
|
|
4219
4310
|
wasm._hd_dealloc(saltPtr);
|
|
4220
4311
|
wasm._hd_dealloc(outPtr);
|
|
@@ -4228,9 +4319,9 @@ function createModule(wasm) {
|
|
|
4228
4319
|
if (!encodeBase58Fn) {
|
|
4229
4320
|
return encodeBase58Fallback(data);
|
|
4230
4321
|
}
|
|
4231
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4322
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
4232
4323
|
try {
|
|
4233
|
-
const ptr = encodeBase58Fn(dataPtr,
|
|
4324
|
+
const ptr = encodeBase58Fn(dataPtr, dataLen);
|
|
4234
4325
|
return readString(wasm, ptr);
|
|
4235
4326
|
} finally {
|
|
4236
4327
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -4264,14 +4355,14 @@ function createModule(wasm) {
|
|
|
4264
4355
|
const encodeBase58CheckFn = getWasmFunction(wasm, '_hd_encode_base58check');
|
|
4265
4356
|
if (!encodeBase58CheckFn) {
|
|
4266
4357
|
const checksum = this.sha256(this.sha256(data)).slice(0, 4);
|
|
4267
|
-
const payload = new Uint8Array(data
|
|
4358
|
+
const payload = new Uint8Array(V.byteLength(data) + checksum.length);
|
|
4268
4359
|
payload.set(data, 0);
|
|
4269
|
-
payload.set(checksum, data
|
|
4360
|
+
payload.set(checksum, V.byteLength(data));
|
|
4270
4361
|
return encodeBase58Fallback(payload);
|
|
4271
4362
|
}
|
|
4272
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4363
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
4273
4364
|
try {
|
|
4274
|
-
const ptr = encodeBase58CheckFn(dataPtr,
|
|
4365
|
+
const ptr = encodeBase58CheckFn(dataPtr, dataLen);
|
|
4275
4366
|
return readString(wasm, ptr);
|
|
4276
4367
|
} finally {
|
|
4277
4368
|
wasm._hd_dealloc(dataPtr);
|
|
@@ -4320,9 +4411,9 @@ function createModule(wasm) {
|
|
|
4320
4411
|
return encodeBech32Fallback(hrp, data);
|
|
4321
4412
|
}
|
|
4322
4413
|
const hrpPtr = allocString(wasm, hrp);
|
|
4323
|
-
const dataPtr = allocAndCopy(wasm, data);
|
|
4414
|
+
const { ptr: dataPtr, len: dataLen } = allocAndCopy(wasm, data);
|
|
4324
4415
|
try {
|
|
4325
|
-
const ptr = encodeBech32Fn(hrpPtr, dataPtr,
|
|
4416
|
+
const ptr = encodeBech32Fn(hrpPtr, dataPtr, dataLen);
|
|
4326
4417
|
return readString(wasm, ptr);
|
|
4327
4418
|
} finally {
|
|
4328
4419
|
wasm._hd_dealloc(hrpPtr);
|
|
@@ -4374,13 +4465,22 @@ function createModule(wasm) {
|
|
|
4374
4465
|
},
|
|
4375
4466
|
|
|
4376
4467
|
// Memory
|
|
4468
|
+
/**
|
|
4469
|
+
* Zero, in place, the bytes under any typed array, DataView, ArrayBuffer
|
|
4470
|
+
* or SharedArrayBuffer (any realm), read from its internal slots, never
|
|
4471
|
+
* from overridable properties. Throws INVALID_ARGUMENT for anything else
|
|
4472
|
+
* and for a detached buffer (its bytes are no longer here to wipe).
|
|
4473
|
+
*/
|
|
4377
4474
|
secureWipe(data) {
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4475
|
+
const region = binaryRegion(data);
|
|
4476
|
+
if (region === null) {
|
|
4477
|
+
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT,
|
|
4478
|
+
'secureWipe takes a typed array, DataView, ArrayBuffer or SharedArrayBuffer');
|
|
4479
|
+
}
|
|
4480
|
+
if (region.detached) {
|
|
4481
|
+
throw new HDWalletError(ErrorCode.INVALID_ARGUMENT, 'secureWipe: the buffer is detached');
|
|
4383
4482
|
}
|
|
4483
|
+
TYPED_ARRAY_FILL.call(new Uint8Array(region.buffer, region.offset, region.length), 0);
|
|
4384
4484
|
}
|
|
4385
4485
|
};
|
|
4386
4486
|
|
|
@@ -4411,15 +4511,15 @@ function createModule(wasm) {
|
|
|
4411
4511
|
exportPrivateKeyPem(curve, privateKey) {
|
|
4412
4512
|
const fn = requireWasmFunction(wasm, '_hd_x509_export_private_key_pem');
|
|
4413
4513
|
const keyBytes = V.privateKey(wasm, toUint8Array(privateKey, 'privateKey'), curve);
|
|
4414
|
-
const keyPtr = allocAndCopy(wasm, keyBytes);
|
|
4514
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, keyBytes);
|
|
4415
4515
|
try {
|
|
4416
4516
|
return callDynamicStringResult(
|
|
4417
4517
|
wasm,
|
|
4418
|
-
(outPtr, outLenPtr) => fn(curve, keyPtr,
|
|
4518
|
+
(outPtr, outLenPtr) => fn(curve, keyPtr, keyLen, outPtr, outLenPtr),
|
|
4419
4519
|
{ wipeOutput: true }
|
|
4420
4520
|
);
|
|
4421
4521
|
} finally {
|
|
4422
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4522
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4423
4523
|
wasm._hd_dealloc(keyPtr);
|
|
4424
4524
|
}
|
|
4425
4525
|
},
|
|
@@ -4448,7 +4548,7 @@ function createModule(wasm) {
|
|
|
4448
4548
|
const optionsLen = wasm.lengthBytesUTF8(optionsSpec) + 1;
|
|
4449
4549
|
const keyBytes = V.privateKey(wasm, toUint8Array(certificatePrivateKey, 'certificatePrivateKey'),
|
|
4450
4550
|
certificateCurve, 'certificatePrivateKey');
|
|
4451
|
-
const keyPtr = allocAndCopy(wasm, keyBytes);
|
|
4551
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, keyBytes);
|
|
4452
4552
|
|
|
4453
4553
|
try {
|
|
4454
4554
|
const bytes = callDynamicBytesResult(
|
|
@@ -4457,7 +4557,7 @@ function createModule(wasm) {
|
|
|
4457
4557
|
optionsPtr,
|
|
4458
4558
|
certificateCurve,
|
|
4459
4559
|
keyPtr,
|
|
4460
|
-
|
|
4560
|
+
keyLen,
|
|
4461
4561
|
outputEncoding,
|
|
4462
4562
|
outPtr,
|
|
4463
4563
|
outLenPtr
|
|
@@ -4466,7 +4566,7 @@ function createModule(wasm) {
|
|
|
4466
4566
|
return decodeX509CertificateOutput(bytes, outputEncoding);
|
|
4467
4567
|
} finally {
|
|
4468
4568
|
wasm._hd_secure_wipe(optionsPtr, optionsLen);
|
|
4469
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4569
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4470
4570
|
wasm._hd_dealloc(optionsPtr);
|
|
4471
4571
|
wasm._hd_dealloc(keyPtr);
|
|
4472
4572
|
}
|
|
@@ -4489,16 +4589,16 @@ function createModule(wasm) {
|
|
|
4489
4589
|
const optionsLen = wasm.lengthBytesUTF8(optionsSpec) + 1;
|
|
4490
4590
|
const issuerKeyBytes = V.privateKey(wasm, toUint8Array(issuerPrivateKey, 'issuerPrivateKey'),
|
|
4491
4591
|
issuerCurve, 'issuerPrivateKey');
|
|
4492
|
-
const issuerKeyPtr = allocAndCopy(wasm, issuerKeyBytes);
|
|
4592
|
+
const { ptr: issuerKeyPtr, len: issuerKeyLen } = allocAndCopy(wasm, issuerKeyBytes);
|
|
4493
4593
|
const issuerCertBytes = normalizeX509CertificateInput(
|
|
4494
4594
|
issuerCertificate,
|
|
4495
4595
|
issuerCertificateEncoding,
|
|
4496
4596
|
'issuerCertificate'
|
|
4497
4597
|
);
|
|
4498
|
-
const issuerCertPtr = allocAndCopy(wasm, issuerCertBytes);
|
|
4598
|
+
const { ptr: issuerCertPtr, len: issuerCertLen } = allocAndCopy(wasm, issuerCertBytes);
|
|
4499
4599
|
const subjectKeyBytes = V.privateKey(wasm, toUint8Array(subjectPrivateKey, 'subjectPrivateKey'),
|
|
4500
4600
|
subjectCurve, 'subjectPrivateKey');
|
|
4501
|
-
const subjectKeyPtr = allocAndCopy(wasm, subjectKeyBytes);
|
|
4601
|
+
const { ptr: subjectKeyPtr, len: subjectKeyLen } = allocAndCopy(wasm, subjectKeyBytes);
|
|
4502
4602
|
|
|
4503
4603
|
try {
|
|
4504
4604
|
const bytes = callDynamicBytesResult(
|
|
@@ -4507,13 +4607,13 @@ function createModule(wasm) {
|
|
|
4507
4607
|
optionsPtr,
|
|
4508
4608
|
issuerCurve,
|
|
4509
4609
|
issuerKeyPtr,
|
|
4510
|
-
|
|
4610
|
+
issuerKeyLen,
|
|
4511
4611
|
issuerCertPtr,
|
|
4512
|
-
|
|
4612
|
+
issuerCertLen,
|
|
4513
4613
|
issuerCertificateEncoding,
|
|
4514
4614
|
subjectCurve,
|
|
4515
4615
|
subjectKeyPtr,
|
|
4516
|
-
|
|
4616
|
+
subjectKeyLen,
|
|
4517
4617
|
outputEncoding,
|
|
4518
4618
|
outPtr,
|
|
4519
4619
|
outLenPtr
|
|
@@ -4522,8 +4622,8 @@ function createModule(wasm) {
|
|
|
4522
4622
|
return decodeX509CertificateOutput(bytes, outputEncoding);
|
|
4523
4623
|
} finally {
|
|
4524
4624
|
wasm._hd_secure_wipe(optionsPtr, optionsLen);
|
|
4525
|
-
wasm._hd_secure_wipe(issuerKeyPtr,
|
|
4526
|
-
wasm._hd_secure_wipe(subjectKeyPtr,
|
|
4625
|
+
wasm._hd_secure_wipe(issuerKeyPtr, issuerKeyLen);
|
|
4626
|
+
wasm._hd_secure_wipe(subjectKeyPtr, subjectKeyLen);
|
|
4527
4627
|
wasm._hd_dealloc(optionsPtr);
|
|
4528
4628
|
wasm._hd_dealloc(issuerKeyPtr);
|
|
4529
4629
|
wasm._hd_dealloc(issuerCertPtr);
|
|
@@ -4536,14 +4636,14 @@ function createModule(wasm) {
|
|
|
4536
4636
|
assertX509CertificateEncoding(outputEncoding, 'outputEncoding');
|
|
4537
4637
|
const fn = requireWasmFunction(wasm, '_hd_x509_convert_certificate');
|
|
4538
4638
|
const certBytes = normalizeX509CertificateInput(certificate, inputEncoding);
|
|
4539
|
-
const certPtr = allocAndCopy(wasm, certBytes);
|
|
4639
|
+
const { ptr: certPtr, len: certLen } = allocAndCopy(wasm, certBytes);
|
|
4540
4640
|
|
|
4541
4641
|
try {
|
|
4542
4642
|
const bytes = callDynamicBytesResult(
|
|
4543
4643
|
wasm,
|
|
4544
4644
|
(outPtr, outLenPtr) => fn(
|
|
4545
4645
|
certPtr,
|
|
4546
|
-
|
|
4646
|
+
certLen,
|
|
4547
4647
|
inputEncoding,
|
|
4548
4648
|
outputEncoding,
|
|
4549
4649
|
outPtr,
|
|
@@ -4560,13 +4660,13 @@ function createModule(wasm) {
|
|
|
4560
4660
|
assertX509CertificateEncoding(inputEncoding, 'inputEncoding');
|
|
4561
4661
|
const fn = requireWasmFunction(wasm, '_hd_x509_parse_certificate_json');
|
|
4562
4662
|
const certBytes = normalizeX509CertificateInput(certificate, inputEncoding);
|
|
4563
|
-
const certPtr = allocAndCopy(wasm, certBytes);
|
|
4663
|
+
const { ptr: certPtr, len: certLen } = allocAndCopy(wasm, certBytes);
|
|
4564
4664
|
|
|
4565
4665
|
try {
|
|
4566
4666
|
return normalizeParsedCertificateJson(JSON.parse(
|
|
4567
4667
|
callDynamicStringResult(
|
|
4568
4668
|
wasm,
|
|
4569
|
-
(outPtr, outLenPtr) => fn(certPtr,
|
|
4669
|
+
(outPtr, outLenPtr) => fn(certPtr, certLen, inputEncoding, outPtr, outLenPtr)
|
|
4570
4670
|
)
|
|
4571
4671
|
));
|
|
4572
4672
|
} finally {
|
|
@@ -4578,10 +4678,10 @@ function createModule(wasm) {
|
|
|
4578
4678
|
assertX509CertificateEncoding(inputEncoding, 'inputEncoding');
|
|
4579
4679
|
const fn = requireWasmFunction(wasm, '_hd_x509_verify_wallet_attestation');
|
|
4580
4680
|
const certBytes = normalizeX509CertificateInput(certificate, inputEncoding);
|
|
4581
|
-
const certPtr = allocAndCopy(wasm, certBytes);
|
|
4681
|
+
const { ptr: certPtr, len: certLen } = allocAndCopy(wasm, certBytes);
|
|
4582
4682
|
|
|
4583
4683
|
try {
|
|
4584
|
-
const result = fn(certPtr,
|
|
4684
|
+
const result = fn(certPtr, certLen, inputEncoding);
|
|
4585
4685
|
if (result < 0) {
|
|
4586
4686
|
throw new HDWalletError(result);
|
|
4587
4687
|
}
|
|
@@ -4603,38 +4703,38 @@ function createModule(wasm) {
|
|
|
4603
4703
|
assertX509CertificateEncoding(certificateEncoding, 'certificateEncoding');
|
|
4604
4704
|
const fn = requireWasmFunction(wasm, '_hd_x509_export_pkcs12');
|
|
4605
4705
|
const certBytes = normalizeX509CertificateInput(certificate, certificateEncoding);
|
|
4606
|
-
const certPtr = allocAndCopy(wasm, certBytes);
|
|
4706
|
+
const { ptr: certPtr, len: certLen } = allocAndCopy(wasm, certBytes);
|
|
4607
4707
|
const keyBytes = V.privateKey(wasm, toUint8Array(privateKey, 'privateKey'), privateKeyCurve);
|
|
4608
4708
|
V.string(password, 'password');
|
|
4609
4709
|
V.string(friendlyName, 'friendlyName');
|
|
4610
|
-
const keyPtr = allocAndCopy(wasm, keyBytes);
|
|
4710
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, keyBytes);
|
|
4611
4711
|
const passwordPtr = allocString(wasm, password);
|
|
4612
4712
|
const passwordLen = wasm.lengthBytesUTF8(password) + 1;
|
|
4613
4713
|
const friendlyNamePtr = allocString(wasm, friendlyName);
|
|
4614
4714
|
const chainBytes = normalizePemInput(chainPem, 'chainPem');
|
|
4615
|
-
const chainPtr = chainBytes
|
|
4715
|
+
const { ptr: chainPtr, len: chainLen } = V.byteLength(chainBytes) > 0 ? allocAndCopy(wasm, chainBytes) : { ptr: 0, len: 0 };
|
|
4616
4716
|
|
|
4617
4717
|
try {
|
|
4618
4718
|
return callDynamicBytesResult(
|
|
4619
4719
|
wasm,
|
|
4620
4720
|
(outPtr, outLenPtr) => fn(
|
|
4621
4721
|
certPtr,
|
|
4622
|
-
|
|
4722
|
+
certLen,
|
|
4623
4723
|
certificateEncoding,
|
|
4624
4724
|
privateKeyCurve,
|
|
4625
4725
|
keyPtr,
|
|
4626
|
-
|
|
4726
|
+
keyLen,
|
|
4627
4727
|
passwordPtr,
|
|
4628
4728
|
friendlyNamePtr,
|
|
4629
4729
|
chainPtr,
|
|
4630
|
-
|
|
4730
|
+
chainLen,
|
|
4631
4731
|
outPtr,
|
|
4632
4732
|
outLenPtr
|
|
4633
4733
|
),
|
|
4634
4734
|
{ wipeOutput: true }
|
|
4635
4735
|
);
|
|
4636
4736
|
} finally {
|
|
4637
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4737
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4638
4738
|
wasm._hd_secure_wipe(passwordPtr, passwordLen);
|
|
4639
4739
|
wasm._hd_dealloc(certPtr);
|
|
4640
4740
|
wasm._hd_dealloc(keyPtr);
|
|
@@ -4650,7 +4750,7 @@ function createModule(wasm) {
|
|
|
4650
4750
|
const fn = requireWasmFunction(wasm, '_hd_x509_import_pkcs12_json');
|
|
4651
4751
|
const bundleBytes = toUint8Array(pkcs12Bundle, 'pkcs12Bundle');
|
|
4652
4752
|
V.string(password, 'password');
|
|
4653
|
-
const bundlePtr = allocAndCopy(wasm, bundleBytes);
|
|
4753
|
+
const { ptr: bundlePtr, len: bundleLen } = allocAndCopy(wasm, bundleBytes);
|
|
4654
4754
|
const passwordPtr = allocString(wasm, password);
|
|
4655
4755
|
const passwordLen = wasm.lengthBytesUTF8(password) + 1;
|
|
4656
4756
|
|
|
@@ -4658,12 +4758,12 @@ function createModule(wasm) {
|
|
|
4658
4758
|
return normalizePkcs12ImportJson(JSON.parse(
|
|
4659
4759
|
callDynamicStringResult(
|
|
4660
4760
|
wasm,
|
|
4661
|
-
(outPtr, outLenPtr) => fn(bundlePtr,
|
|
4761
|
+
(outPtr, outLenPtr) => fn(bundlePtr, bundleLen, passwordPtr, outPtr, outLenPtr),
|
|
4662
4762
|
{ wipeOutput: true }
|
|
4663
4763
|
)
|
|
4664
4764
|
));
|
|
4665
4765
|
} finally {
|
|
4666
|
-
wasm._hd_secure_wipe(bundlePtr,
|
|
4766
|
+
wasm._hd_secure_wipe(bundlePtr, bundleLen);
|
|
4667
4767
|
wasm._hd_secure_wipe(passwordPtr, passwordLen);
|
|
4668
4768
|
wasm._hd_dealloc(bundlePtr);
|
|
4669
4769
|
wasm._hd_dealloc(passwordPtr);
|
|
@@ -4698,18 +4798,18 @@ function createModule(wasm) {
|
|
|
4698
4798
|
if (!Number.isInteger(overhead) || overhead <= 0) {
|
|
4699
4799
|
throw new HDWalletError(ErrorCode.NOT_SUPPORTED, 'ECIES is not supported on this curve');
|
|
4700
4800
|
}
|
|
4701
|
-
const outSize = plaintext
|
|
4702
|
-
const pubPtr = allocAndCopy(wasm, recipientPublicKey);
|
|
4703
|
-
const ptPtr = allocAndCopy(wasm, plaintext);
|
|
4704
|
-
const aadPtr = aad
|
|
4801
|
+
const outSize = V.byteLength(plaintext) + overhead;
|
|
4802
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, recipientPublicKey);
|
|
4803
|
+
const { ptr: ptPtr, len: ptLen } = allocAndCopy(wasm, plaintext);
|
|
4804
|
+
const { ptr: aadPtr, len: aadLen } = V.byteLength(aad) > 0 ? allocAndCopy(wasm, aad) : { ptr: 0, len: 0 };
|
|
4705
4805
|
const outPtr = wasm._hd_alloc(outSize);
|
|
4706
4806
|
try {
|
|
4707
|
-
const result = checkLength(encryptFn(curveId, pubPtr,
|
|
4708
|
-
ptPtr,
|
|
4807
|
+
const result = checkLength(encryptFn(curveId, pubPtr, pubLen,
|
|
4808
|
+
ptPtr, ptLen, aadPtr, aadLen, outPtr, outSize), outSize);
|
|
4709
4809
|
return readBytes(wasm, outPtr, result);
|
|
4710
4810
|
} finally {
|
|
4711
4811
|
wasm._hd_dealloc(pubPtr);
|
|
4712
|
-
wasm._hd_secure_wipe(ptPtr,
|
|
4812
|
+
wasm._hd_secure_wipe(ptPtr, ptLen);
|
|
4713
4813
|
wasm._hd_dealloc(ptPtr);
|
|
4714
4814
|
if (aadPtr) wasm._hd_dealloc(aadPtr);
|
|
4715
4815
|
wasm._hd_dealloc(outPtr);
|
|
@@ -4722,20 +4822,20 @@ function createModule(wasm) {
|
|
|
4722
4822
|
V.bytes(ciphertext, 'ciphertext');
|
|
4723
4823
|
V.bytes(aad, 'aad');
|
|
4724
4824
|
const decryptFn = requireWasmFunction(wasm, '_hd_ecies_decrypt');
|
|
4725
|
-
const privPtr = allocAndCopy(wasm, recipientPrivateKey);
|
|
4726
|
-
const ctPtr = allocAndCopy(wasm, ciphertext);
|
|
4727
|
-
const aadPtr = aad
|
|
4728
|
-
const outPtr = wasm._hd_alloc(
|
|
4825
|
+
const { ptr: privPtr, len: privLen } = allocAndCopy(wasm, recipientPrivateKey);
|
|
4826
|
+
const { ptr: ctPtr, len: ctLen } = allocAndCopy(wasm, ciphertext);
|
|
4827
|
+
const { ptr: aadPtr, len: aadLen } = V.byteLength(aad) > 0 ? allocAndCopy(wasm, aad) : { ptr: 0, len: 0 };
|
|
4828
|
+
const outPtr = wasm._hd_alloc(ctLen);
|
|
4729
4829
|
try {
|
|
4730
|
-
const result = checkLengthWithin(decryptFn(curveId, privPtr,
|
|
4731
|
-
ctPtr,
|
|
4830
|
+
const result = checkLengthWithin(decryptFn(curveId, privPtr, privLen,
|
|
4831
|
+
ctPtr, ctLen, aadPtr, aadLen, outPtr, ctLen), 0, ctLen);
|
|
4732
4832
|
return readBytes(wasm, outPtr, result);
|
|
4733
4833
|
} finally {
|
|
4734
|
-
wasm._hd_secure_wipe(privPtr,
|
|
4834
|
+
wasm._hd_secure_wipe(privPtr, privLen);
|
|
4735
4835
|
wasm._hd_dealloc(privPtr);
|
|
4736
4836
|
wasm._hd_dealloc(ctPtr);
|
|
4737
4837
|
if (aadPtr) wasm._hd_dealloc(aadPtr);
|
|
4738
|
-
wasm._hd_secure_wipe(outPtr,
|
|
4838
|
+
wasm._hd_secure_wipe(outPtr, ctLen);
|
|
4739
4839
|
wasm._hd_dealloc(outPtr);
|
|
4740
4840
|
}
|
|
4741
4841
|
}
|
|
@@ -4751,16 +4851,16 @@ function createModule(wasm) {
|
|
|
4751
4851
|
V.bytesOfLength(key, [16, 24, 32], 'key');
|
|
4752
4852
|
V.bytes(plaintext, 'plaintext');
|
|
4753
4853
|
V.bytesOfLength(iv, 16, 'iv');
|
|
4754
|
-
const keyPtr = allocAndCopy(wasm, key);
|
|
4755
|
-
const ptPtr = allocAndCopy(wasm, plaintext);
|
|
4756
|
-
const ivPtr = allocAndCopy(wasm, iv);
|
|
4757
|
-
const outPtr = wasm._hd_alloc(
|
|
4854
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, key);
|
|
4855
|
+
const { ptr: ptPtr, len: ptLen } = allocAndCopy(wasm, plaintext);
|
|
4856
|
+
const { ptr: ivPtr, len: ivLen } = allocAndCopy(wasm, iv);
|
|
4857
|
+
const outPtr = wasm._hd_alloc(ptLen);
|
|
4758
4858
|
try {
|
|
4759
|
-
checkLength(encryptFn(keyPtr,
|
|
4760
|
-
return readBytes(wasm, outPtr,
|
|
4859
|
+
checkLength(encryptFn(keyPtr, keyLen, ptPtr, ptLen, ivPtr, ivLen, outPtr, ptLen), ptLen);
|
|
4860
|
+
return readBytes(wasm, outPtr, ptLen);
|
|
4761
4861
|
} finally {
|
|
4762
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4763
|
-
wasm._hd_secure_wipe(ptPtr,
|
|
4862
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4863
|
+
wasm._hd_secure_wipe(ptPtr, ptLen);
|
|
4764
4864
|
wasm._hd_dealloc(keyPtr);
|
|
4765
4865
|
wasm._hd_dealloc(ptPtr);
|
|
4766
4866
|
wasm._hd_dealloc(ivPtr);
|
|
@@ -4773,19 +4873,19 @@ function createModule(wasm) {
|
|
|
4773
4873
|
V.bytesOfLength(key, [16, 24, 32], 'key');
|
|
4774
4874
|
V.bytes(ciphertext, 'ciphertext');
|
|
4775
4875
|
V.bytesOfLength(iv, 16, 'iv');
|
|
4776
|
-
const keyPtr = allocAndCopy(wasm, key);
|
|
4777
|
-
const ctPtr = allocAndCopy(wasm, ciphertext);
|
|
4778
|
-
const ivPtr = allocAndCopy(wasm, iv);
|
|
4779
|
-
const outPtr = wasm._hd_alloc(
|
|
4876
|
+
const { ptr: keyPtr, len: keyLen } = allocAndCopy(wasm, key);
|
|
4877
|
+
const { ptr: ctPtr, len: ctLen } = allocAndCopy(wasm, ciphertext);
|
|
4878
|
+
const { ptr: ivPtr, len: ivLen } = allocAndCopy(wasm, iv);
|
|
4879
|
+
const outPtr = wasm._hd_alloc(ctLen);
|
|
4780
4880
|
try {
|
|
4781
|
-
checkLength(decryptFn(keyPtr,
|
|
4782
|
-
return readBytes(wasm, outPtr,
|
|
4881
|
+
checkLength(decryptFn(keyPtr, keyLen, ctPtr, ctLen, ivPtr, ivLen, outPtr, ctLen), ctLen);
|
|
4882
|
+
return readBytes(wasm, outPtr, ctLen);
|
|
4783
4883
|
} finally {
|
|
4784
|
-
wasm._hd_secure_wipe(keyPtr,
|
|
4884
|
+
wasm._hd_secure_wipe(keyPtr, keyLen);
|
|
4785
4885
|
wasm._hd_dealloc(keyPtr);
|
|
4786
4886
|
wasm._hd_dealloc(ctPtr);
|
|
4787
4887
|
wasm._hd_dealloc(ivPtr);
|
|
4788
|
-
wasm._hd_secure_wipe(outPtr,
|
|
4888
|
+
wasm._hd_secure_wipe(outPtr, ctLen);
|
|
4789
4889
|
wasm._hd_dealloc(outPtr);
|
|
4790
4890
|
}
|
|
4791
4891
|
}
|
|
@@ -4800,19 +4900,19 @@ function createModule(wasm) {
|
|
|
4800
4900
|
const deriveFn = requireWasmFunction(wasm, '_hd_slip10_ed25519_derive_path');
|
|
4801
4901
|
V.bytesOfLength(seed, 64, 'seed', ErrorCode.INVALID_SEED);
|
|
4802
4902
|
V.string(path, 'path');
|
|
4803
|
-
const seedPtr = allocAndCopy(wasm, seed);
|
|
4903
|
+
const { ptr: seedPtr, len: seedLen } = allocAndCopy(wasm, seed);
|
|
4804
4904
|
const pathPtr = allocString(wasm, path);
|
|
4805
4905
|
const keyPtr = wasm._hd_alloc(32);
|
|
4806
4906
|
const chainCodePtr = wasm._hd_alloc(32);
|
|
4807
4907
|
try {
|
|
4808
|
-
const result = deriveFn(seedPtr,
|
|
4908
|
+
const result = deriveFn(seedPtr, seedLen, pathPtr, keyPtr, chainCodePtr);
|
|
4809
4909
|
checkResult(result);
|
|
4810
4910
|
return {
|
|
4811
4911
|
privateKey: readBytes(wasm, keyPtr, 32),
|
|
4812
4912
|
chainCode: readBytes(wasm, chainCodePtr, 32)
|
|
4813
4913
|
};
|
|
4814
4914
|
} finally {
|
|
4815
|
-
wasm._hd_secure_wipe(seedPtr,
|
|
4915
|
+
wasm._hd_secure_wipe(seedPtr, seedLen);
|
|
4816
4916
|
wasm._hd_secure_wipe(keyPtr, 32);
|
|
4817
4917
|
wasm._hd_dealloc(seedPtr);
|
|
4818
4918
|
wasm._hd_dealloc(pathPtr);
|
|
@@ -4838,11 +4938,11 @@ function createModule(wasm) {
|
|
|
4838
4938
|
V.curve(curve, [Curve.SECP256K1, Curve.ED25519, Curve.P256]);
|
|
4839
4939
|
V.publicKey(wasm, publicKey, curve, 'publicKey',
|
|
4840
4940
|
curve === Curve.SECP256K1 ? [33] : V.publicKeyLengths(curve));
|
|
4841
|
-
const pubPtr = allocAndCopy(wasm, publicKey);
|
|
4941
|
+
const { ptr: pubPtr, len: pubLen } = allocAndCopy(wasm, publicKey);
|
|
4842
4942
|
const outPtr = wasm._hd_alloc(64);
|
|
4843
4943
|
try {
|
|
4844
4944
|
const result = checkLengthWithin(
|
|
4845
|
-
wasm._hd_libp2p_peer_id(pubPtr,
|
|
4945
|
+
wasm._hd_libp2p_peer_id(pubPtr, pubLen, curve, outPtr, 64), 1, 64);
|
|
4846
4946
|
return readBytes(wasm, outPtr, result);
|
|
4847
4947
|
} finally {
|
|
4848
4948
|
wasm._hd_dealloc(pubPtr);
|
|
@@ -4872,16 +4972,16 @@ function createModule(wasm) {
|
|
|
4872
4972
|
// pre-computed peerID bytes and just do the CID wrapping + encoding here.
|
|
4873
4973
|
// We still use WASM for base36 encoding.
|
|
4874
4974
|
// A peer ID multihash: identity or SHA-256, at most 64 bytes.
|
|
4875
|
-
V.bytesInRange(peerIdBytes, 2, 64, 'peerIdBytes');
|
|
4975
|
+
const peerId = V.snapshot(V.bytesInRange(peerIdBytes, 2, 64, 'peerIdBytes'), 'peerIdBytes');
|
|
4876
4976
|
const outPtr = wasm._hd_alloc(128);
|
|
4877
4977
|
// Build CID in JS (trivial: 2-byte prefix + multihash)
|
|
4878
|
-
const cid = new Uint8Array(2 +
|
|
4978
|
+
const cid = new Uint8Array(2 + peerId.length);
|
|
4879
4979
|
cid[0] = 0x01; // CIDv1
|
|
4880
4980
|
cid[1] = 0x72; // libp2p-key codec
|
|
4881
|
-
cid.set(
|
|
4882
|
-
const cidPtr = allocAndCopy(wasm, cid);
|
|
4981
|
+
cid.set(peerId, 2);
|
|
4982
|
+
const { ptr: cidPtr, len: cidLen } = allocAndCopy(wasm, cid);
|
|
4883
4983
|
try {
|
|
4884
|
-
const result = wasm._hd_encode_base36lower(cidPtr,
|
|
4984
|
+
const result = wasm._hd_encode_base36lower(cidPtr, cidLen, outPtr, 128);
|
|
4885
4985
|
checkResult(result);
|
|
4886
4986
|
return 'k' + readString(wasm, outPtr);
|
|
4887
4987
|
} finally {
|
|
@@ -4896,15 +4996,15 @@ function createModule(wasm) {
|
|
|
4896
4996
|
* @returns {string}
|
|
4897
4997
|
*/
|
|
4898
4998
|
ipnsHashBase32(peerIdBytes) {
|
|
4899
|
-
V.bytesInRange(peerIdBytes, 2, 64, 'peerIdBytes');
|
|
4900
|
-
const cid = new Uint8Array(2 +
|
|
4999
|
+
const peerId = V.snapshot(V.bytesInRange(peerIdBytes, 2, 64, 'peerIdBytes'), 'peerIdBytes');
|
|
5000
|
+
const cid = new Uint8Array(2 + peerId.length);
|
|
4901
5001
|
cid[0] = 0x01; // CIDv1
|
|
4902
5002
|
cid[1] = 0x72; // libp2p-key codec
|
|
4903
|
-
cid.set(
|
|
4904
|
-
const cidPtr = allocAndCopy(wasm, cid);
|
|
5003
|
+
cid.set(peerId, 2);
|
|
5004
|
+
const { ptr: cidPtr, len: cidLen } = allocAndCopy(wasm, cid);
|
|
4905
5005
|
const outPtr = wasm._hd_alloc(128);
|
|
4906
5006
|
try {
|
|
4907
|
-
const result = wasm._hd_encode_base32lower(cidPtr,
|
|
5007
|
+
const result = wasm._hd_encode_base32lower(cidPtr, cidLen, outPtr, 128);
|
|
4908
5008
|
checkResult(result);
|
|
4909
5009
|
return 'b' + readString(wasm, outPtr);
|
|
4910
5010
|
} finally {
|
|
@@ -4995,11 +5095,11 @@ function createModule(wasm) {
|
|
|
4995
5095
|
// Entropy
|
|
4996
5096
|
injectEntropy(entropy) {
|
|
4997
5097
|
V.bytesInRange(entropy, 1, 0x100000, 'entropy');
|
|
4998
|
-
const entropyPtr = allocAndCopy(wasm, entropy);
|
|
5098
|
+
const { ptr: entropyPtr, len: entropyLen } = allocAndCopy(wasm, entropy);
|
|
4999
5099
|
try {
|
|
5000
|
-
wasm._hd_inject_entropy(entropyPtr,
|
|
5100
|
+
wasm._hd_inject_entropy(entropyPtr, entropyLen);
|
|
5001
5101
|
} finally {
|
|
5002
|
-
wasm._hd_secure_wipe(entropyPtr,
|
|
5102
|
+
wasm._hd_secure_wipe(entropyPtr, entropyLen);
|
|
5003
5103
|
wasm._hd_dealloc(entropyPtr);
|
|
5004
5104
|
}
|
|
5005
5105
|
},
|