quantumcoin 7.0.3 → 7.0.5
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/.github/workflows/publish-npmjs.yaml +22 -22
- package/.gitignore +15 -15
- package/LICENSE +21 -21
- package/README-SDK.md +758 -754
- package/README.md +165 -150
- package/SPEC.md +3845 -3843
- package/config.d.ts +50 -50
- package/config.js +115 -115
- package/examples/AllSolidityTypes.sol +184 -184
- package/examples/SimpleIERC20.sol +74 -74
- package/examples/events.js +41 -35
- package/examples/events.ts +35 -0
- package/examples/example-generator-sdk-js.js +100 -95
- package/examples/example-generator-sdk-js.ts +77 -0
- package/examples/example-generator-sdk-ts.js +100 -95
- package/examples/example-generator-sdk-ts.ts +77 -0
- package/examples/example.js +72 -61
- package/examples/example.ts +61 -0
- package/examples/offline-signing.js +79 -73
- package/examples/offline-signing.ts +66 -0
- package/examples/package-lock.json +596 -57
- package/examples/package.json +32 -16
- package/examples/read-operations.js +32 -27
- package/examples/read-operations.ts +31 -0
- package/examples/sdk-generator-erc20.inline.json +251 -251
- package/examples/solidity-types.ts +43 -43
- package/examples/wallet-offline.js +35 -29
- package/examples/wallet-offline.ts +34 -0
- package/generate-sdk.js +1824 -1490
- package/index.js +12 -12
- package/package.json +95 -75
- package/scripts/copy-declarations.js +31 -0
- package/scripts/run-all-one-by-one.js +151 -0
- package/src/abi/fragments.d.ts +42 -42
- package/src/abi/fragments.js +63 -63
- package/src/abi/index.d.ts +13 -13
- package/src/abi/index.js +9 -9
- package/src/abi/interface.d.ts +128 -132
- package/src/abi/interface.js +590 -590
- package/src/abi/js-abi-coder.d.ts +8 -0
- package/src/abi/js-abi-coder.js +474 -474
- package/src/constants.d.ts +66 -61
- package/src/constants.js +101 -94
- package/src/contract/contract-factory.d.ts +28 -28
- package/src/contract/contract-factory.js +105 -105
- package/src/contract/contract.d.ts +113 -114
- package/src/contract/contract.js +354 -354
- package/src/contract/index.d.ts +9 -9
- package/src/contract/index.js +9 -9
- package/src/errors/index.d.ts +92 -92
- package/src/errors/index.js +188 -188
- package/src/generator/index.d.ts +74 -0
- package/src/generator/index.js +1404 -1404
- package/src/index.d.ts +125 -127
- package/src/index.js +41 -41
- package/src/internal/hex.d.ts +61 -61
- package/src/internal/hex.js +144 -144
- package/src/providers/extra-providers.d.ts +139 -128
- package/src/providers/extra-providers.js +600 -575
- package/src/providers/index.d.ts +17 -16
- package/src/providers/index.js +10 -10
- package/src/providers/json-rpc-provider.d.ts +12 -12
- package/src/providers/json-rpc-provider.js +79 -79
- package/src/providers/provider.d.ts +208 -203
- package/src/providers/provider.js +393 -371
- package/src/types/index.d.ts +214 -462
- package/src/types/index.js +9 -9
- package/src/utils/address.d.ts +72 -72
- package/src/utils/address.js +181 -182
- package/src/utils/encoding.d.ts +120 -120
- package/src/utils/encoding.js +306 -306
- package/src/utils/hashing.d.ts +82 -76
- package/src/utils/hashing.js +313 -298
- package/src/utils/index.d.ts +65 -55
- package/src/utils/index.js +13 -13
- package/src/utils/result.d.ts +57 -57
- package/src/utils/result.js +128 -128
- package/src/utils/rlp.d.ts +12 -12
- package/src/utils/rlp.js +200 -200
- package/src/utils/units.d.ts +29 -29
- package/src/utils/units.js +107 -107
- package/src/wallet/index.d.ts +10 -10
- package/src/wallet/index.js +8 -8
- package/src/wallet/wallet.d.ts +168 -160
- package/src/wallet/wallet.js +500 -489
- package/test/e2e/all-solidity-types.dynamic.test.js +207 -200
- package/test/e2e/all-solidity-types.dynamic.test.ts +191 -0
- package/test/e2e/all-solidity-types.fixtures.js +231 -231
- package/test/e2e/all-solidity-types.generated-sdks.e2e.test.js +387 -368
- package/test/e2e/all-solidity-types.generated-sdks.e2e.test.ts +350 -0
- package/test/e2e/helpers.js +59 -47
- package/test/e2e/signing-context-and-fee.e2e.test.js +141 -0
- package/test/e2e/signing-context-and-fee.e2e.test.ts +128 -0
- package/test/e2e/simple-erc20.generated-sdks.e2e.test.js +168 -151
- package/test/e2e/simple-erc20.generated-sdks.e2e.test.ts +141 -0
- package/test/e2e/transactional.test.js +245 -191
- package/test/e2e/transactional.test.ts +208 -0
- package/test/e2e/typed-generator.e2e.test.js +407 -404
- package/test/e2e/typed-generator.e2e.test.ts +337 -0
- package/test/fixtures/ConstructorParam.sol +23 -23
- package/test/fixtures/MultiContracts.sol +37 -37
- package/test/fixtures/SimpleStorage.sol +18 -18
- package/test/fixtures/StakingContract.abi.json +1 -1
- package/test/integration/ipc-provider.test.js +49 -44
- package/test/integration/ipc-provider.test.ts +44 -0
- package/test/integration/provider.test.js +88 -72
- package/test/integration/provider.test.ts +85 -0
- package/test/integration/ws-provider.test.js +41 -33
- package/test/integration/ws-provider.test.ts +38 -0
- package/test/security/malformed-input.test.js +37 -31
- package/test/security/malformed-input.test.ts +35 -0
- package/test/unit/_encrypted-output.txt +6 -0
- package/test/unit/_log-encrypted-jsons.js +45 -0
- package/test/unit/_write-keystore-fixture.js +16 -0
- package/test/unit/abi-interface.test.js +103 -98
- package/test/unit/abi-interface.test.ts +102 -0
- package/test/unit/address-wallet.test.js +392 -257
- package/test/unit/address-wallet.test.ts +379 -0
- package/test/unit/browser-provider.test.js +85 -82
- package/test/unit/browser-provider.test.ts +79 -0
- package/test/unit/contract.test.js +85 -82
- package/test/unit/contract.test.ts +83 -0
- package/test/unit/encoding-units-rlp.test.js +92 -89
- package/test/unit/encoding-units-rlp.test.ts +91 -0
- package/test/unit/errors.test.js +77 -74
- package/test/unit/errors.test.ts +76 -0
- package/test/unit/filter-by-blockhash.test.js +55 -52
- package/test/unit/filter-by-blockhash.test.ts +54 -0
- package/test/unit/fixtures/encrypted-keystores-48-32-36.js +9 -0
- package/test/unit/generate-contract-cli.test.js +42 -39
- package/test/unit/generate-contract-cli.test.ts +41 -0
- package/test/unit/generate-sdk-artifacts-json.test.js +113 -110
- package/test/unit/generate-sdk-artifacts-json.test.ts +110 -0
- package/test/unit/generator.test.js +102 -99
- package/test/unit/generator.test.ts +101 -0
- package/test/unit/hashing.test.js +68 -54
- package/test/unit/hashing.test.ts +67 -0
- package/test/unit/init.test.js +39 -36
- package/test/unit/init.test.ts +38 -0
- package/test/unit/interface.test.js +56 -53
- package/test/unit/interface.test.ts +54 -0
- package/test/unit/internal-hex.test.js +50 -47
- package/test/unit/internal-hex.test.ts +49 -0
- package/test/unit/populate-transaction.test.js +65 -62
- package/test/unit/populate-transaction.test.ts +64 -0
- package/test/unit/providers.test.js +200 -144
- package/test/unit/providers.test.ts +196 -0
- package/test/unit/result.test.js +80 -77
- package/test/unit/result.test.ts +79 -0
- package/test/unit/solidity-types.test.js +49 -46
- package/test/unit/solidity-types.test.ts +39 -0
- package/test/unit/utils.test.js +57 -54
- package/test/unit/utils.test.ts +56 -0
- package/test/verbose-logger.js +74 -0
- package/tsconfig.build.json +14 -0
package/src/utils/encoding.js
CHANGED
|
@@ -1,306 +1,306 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview Encoding/decoding helpers (ethers.js v6 compatible names).
|
|
3
|
-
*
|
|
4
|
-
* Notes:
|
|
5
|
-
* - QuantumCoin addresses are 32 bytes (not 20).
|
|
6
|
-
* - This module intentionally uses only built-in Node.js APIs.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const {
|
|
10
|
-
isUint8Array,
|
|
11
|
-
normalizeHex,
|
|
12
|
-
isHexString,
|
|
13
|
-
strip0x,
|
|
14
|
-
add0x,
|
|
15
|
-
hexToBytes,
|
|
16
|
-
bytesToHex,
|
|
17
|
-
utf8ToBytes,
|
|
18
|
-
bytesToUtf8,
|
|
19
|
-
arrayify: _arrayify,
|
|
20
|
-
} = require("../internal/hex");
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @typedef {string | Uint8Array} BytesLike
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Converts bytes to UTF-8 string.
|
|
28
|
-
* @param {BytesLike} data
|
|
29
|
-
* @returns {string}
|
|
30
|
-
*/
|
|
31
|
-
function toUtf8String(data) {
|
|
32
|
-
return bytesToUtf8(arrayify(data));
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Converts string to UTF-8 bytes.
|
|
37
|
-
* @param {string} str
|
|
38
|
-
* @returns {Uint8Array}
|
|
39
|
-
*/
|
|
40
|
-
function toUtf8Bytes(str) {
|
|
41
|
-
return utf8ToBytes(str);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Converts data to hex string.
|
|
46
|
-
* @param {BytesLike} data
|
|
47
|
-
* @returns {string}
|
|
48
|
-
*/
|
|
49
|
-
function toHex(data) {
|
|
50
|
-
if (typeof data === "string") return normalizeHex(data);
|
|
51
|
-
return bytesToHex(arrayify(data));
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Alias for toHex.
|
|
56
|
-
* @param {BytesLike} data
|
|
57
|
-
* @returns {string}
|
|
58
|
-
*/
|
|
59
|
-
function hexlify(data) {
|
|
60
|
-
return toHex(data);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Converts data to byte array.
|
|
65
|
-
* @param {BytesLike} data
|
|
66
|
-
* @returns {Uint8Array}
|
|
67
|
-
*/
|
|
68
|
-
function arrayify(data) {
|
|
69
|
-
return _arrayify(data);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Returns true if value is BytesLike.
|
|
74
|
-
* @param {any} value
|
|
75
|
-
* @returns {boolean}
|
|
76
|
-
*/
|
|
77
|
-
function isBytesLike(value) {
|
|
78
|
-
return (typeof value === "string" && isHexString(value)) || isUint8Array(value);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Concatenates byte arrays and returns a hex string.
|
|
83
|
-
* @param {BytesLike[]} items
|
|
84
|
-
* @returns {string}
|
|
85
|
-
*/
|
|
86
|
-
function concat(items) {
|
|
87
|
-
if (!Array.isArray(items)) throw new TypeError("items must be an array");
|
|
88
|
-
const parts = items.map((i) => arrayify(i));
|
|
89
|
-
const len = parts.reduce((a, b) => a + b.length, 0);
|
|
90
|
-
const out = new Uint8Array(len);
|
|
91
|
-
let offset = 0;
|
|
92
|
-
for (const p of parts) {
|
|
93
|
-
out.set(p, offset);
|
|
94
|
-
offset += p.length;
|
|
95
|
-
}
|
|
96
|
-
return bytesToHex(out);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Strips leading zeros from a hex string.
|
|
101
|
-
* @param {BytesLike} data
|
|
102
|
-
* @returns {string}
|
|
103
|
-
*/
|
|
104
|
-
function stripZerosLeft(data) {
|
|
105
|
-
const hex = toHex(data);
|
|
106
|
-
let h = strip0x(hex);
|
|
107
|
-
h = h.replace(/^0+/, "");
|
|
108
|
-
if (h.length === 0) return "0x";
|
|
109
|
-
if (h.length % 2 !== 0) h = "0" + h;
|
|
110
|
-
return add0x(h);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Pads a BytesLike value to the left with zeros (byte length).
|
|
115
|
-
* @param {BytesLike} value
|
|
116
|
-
* @param {number} length
|
|
117
|
-
* @returns {string}
|
|
118
|
-
*/
|
|
119
|
-
function zeroPad(value, length) {
|
|
120
|
-
const bytes = arrayify(value);
|
|
121
|
-
if (bytes.length > length) throw new RangeError("value exceeds length");
|
|
122
|
-
const out = new Uint8Array(length);
|
|
123
|
-
out.set(bytes, length - bytes.length);
|
|
124
|
-
return bytesToHex(out);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* Pads a hex value (interpreted as bytes) to the left with zeros (byte length).
|
|
129
|
-
* @param {BytesLike} value
|
|
130
|
-
* @param {number} length
|
|
131
|
-
* @returns {string}
|
|
132
|
-
*/
|
|
133
|
-
function zeroPadValue(value, length) {
|
|
134
|
-
return zeroPad(value, length);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/**
|
|
138
|
-
* Encodes a short UTF-8 string into a bytes32 hex string.
|
|
139
|
-
* @param {string} text
|
|
140
|
-
* @returns {string}
|
|
141
|
-
*/
|
|
142
|
-
function encodeBytes32String(text) {
|
|
143
|
-
const bytes = toUtf8Bytes(text);
|
|
144
|
-
if (bytes.length > 32) throw new RangeError("string too long (max 32 bytes)");
|
|
145
|
-
const out = new Uint8Array(32);
|
|
146
|
-
out.set(bytes, 0);
|
|
147
|
-
return bytesToHex(out);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Decodes a bytes32 hex string into a UTF-8 string (trailing zeros stripped).
|
|
152
|
-
* @param {BytesLike} bytes
|
|
153
|
-
* @returns {string}
|
|
154
|
-
*/
|
|
155
|
-
function decodeBytes32String(bytes) {
|
|
156
|
-
const b = arrayify(bytes);
|
|
157
|
-
if (b.length !== 32) throw new RangeError("invalid bytes32 length");
|
|
158
|
-
let end = b.length;
|
|
159
|
-
while (end > 0 && b[end - 1] === 0) end--;
|
|
160
|
-
return bytesToUtf8(b.slice(0, end));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Base64 decode to bytes.
|
|
165
|
-
* @param {string} data
|
|
166
|
-
* @returns {Uint8Array}
|
|
167
|
-
*/
|
|
168
|
-
function decodeBase64(data) {
|
|
169
|
-
const buf = Buffer.from(data, "base64");
|
|
170
|
-
return new Uint8Array(buf);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
/**
|
|
174
|
-
* Base64 encode BytesLike.
|
|
175
|
-
* @param {BytesLike} data
|
|
176
|
-
* @returns {string}
|
|
177
|
-
*/
|
|
178
|
-
function encodeBase64(data) {
|
|
179
|
-
return Buffer.from(arrayify(data)).toString("base64");
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Minimal base58 implementation (Bitcoin alphabet) for compatibility with ethers helpers.
|
|
183
|
-
const _B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
184
|
-
const _B58_INDEX = new Map(_B58_ALPHABET.split("").map((c, i) => [c, i]));
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Decode Base58 string to bytes.
|
|
188
|
-
* @param {string} data
|
|
189
|
-
* @returns {Uint8Array}
|
|
190
|
-
*/
|
|
191
|
-
function decodeBase58(data) {
|
|
192
|
-
if (typeof data !== "string" || data.length === 0) throw new TypeError("invalid base58 string");
|
|
193
|
-
|
|
194
|
-
let bytes = [0];
|
|
195
|
-
for (const ch of data) {
|
|
196
|
-
const val = _B58_INDEX.get(ch);
|
|
197
|
-
if (val == null) throw new TypeError("invalid base58 character");
|
|
198
|
-
|
|
199
|
-
let carry = val;
|
|
200
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
201
|
-
const x = bytes[i] * 58 + carry;
|
|
202
|
-
bytes[i] = x & 0xff;
|
|
203
|
-
carry = x >> 8;
|
|
204
|
-
}
|
|
205
|
-
while (carry > 0) {
|
|
206
|
-
bytes.push(carry & 0xff);
|
|
207
|
-
carry >>= 8;
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Deal with leading zeros
|
|
212
|
-
let leading = 0;
|
|
213
|
-
for (const ch of data) {
|
|
214
|
-
if (ch === "1") leading++;
|
|
215
|
-
else break;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
const out = new Uint8Array(leading + bytes.length);
|
|
219
|
-
for (let i = 0; i < bytes.length; i++) out[out.length - 1 - i] = bytes[i];
|
|
220
|
-
return out;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/**
|
|
224
|
-
* Encode BytesLike as Base58.
|
|
225
|
-
* @param {BytesLike} data
|
|
226
|
-
* @returns {string}
|
|
227
|
-
*/
|
|
228
|
-
function encodeBase58(data) {
|
|
229
|
-
const bytes = arrayify(data);
|
|
230
|
-
let digits = [0];
|
|
231
|
-
|
|
232
|
-
for (const b of bytes) {
|
|
233
|
-
let carry = b;
|
|
234
|
-
for (let i = 0; i < digits.length; i++) {
|
|
235
|
-
const x = digits[i] * 256 + carry;
|
|
236
|
-
digits[i] = x % 58;
|
|
237
|
-
carry = (x / 58) | 0;
|
|
238
|
-
}
|
|
239
|
-
while (carry > 0) {
|
|
240
|
-
digits.push(carry % 58);
|
|
241
|
-
carry = (carry / 58) | 0;
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
// Leading zeros
|
|
246
|
-
let leading = 0;
|
|
247
|
-
for (const b of bytes) {
|
|
248
|
-
if (b === 0) leading++;
|
|
249
|
-
else break;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
let out = "1".repeat(leading);
|
|
253
|
-
for (let i = digits.length - 1; i >= 0; i--) out += _B58_ALPHABET[digits[i]];
|
|
254
|
-
return out;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
/**
|
|
258
|
-
* Returns UTF-8 code points for a string.
|
|
259
|
-
* @param {string} str
|
|
260
|
-
* @returns {number[]}
|
|
261
|
-
*/
|
|
262
|
-
function toUtf8CodePoints(str) {
|
|
263
|
-
return Array.from(str).map((c) => c.codePointAt(0) || 0);
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
/**
|
|
267
|
-
* Solidity packed encoding.
|
|
268
|
-
* This is a complex helper in ethers.js; in QuantumCoin.js it is currently not implemented.
|
|
269
|
-
* @throws
|
|
270
|
-
*/
|
|
271
|
-
function solidityPacked() {
|
|
272
|
-
throw new Error("solidityPacked is not implemented in QuantumCoin.js yet");
|
|
273
|
-
}
|
|
274
|
-
function solidityPackedKeccak256() {
|
|
275
|
-
throw new Error("solidityPackedKeccak256 is not implemented in QuantumCoin.js yet");
|
|
276
|
-
}
|
|
277
|
-
function solidityPackedSha256() {
|
|
278
|
-
throw new Error("solidityPackedSha256 is not implemented in QuantumCoin.js yet");
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
module.exports = {
|
|
282
|
-
toUtf8String,
|
|
283
|
-
toUtf8Bytes,
|
|
284
|
-
toHex,
|
|
285
|
-
hexlify,
|
|
286
|
-
arrayify,
|
|
287
|
-
concat,
|
|
288
|
-
stripZerosLeft,
|
|
289
|
-
encodeBytes32String,
|
|
290
|
-
decodeBytes32String,
|
|
291
|
-
decodeBase58,
|
|
292
|
-
decodeBase64,
|
|
293
|
-
encodeBase58,
|
|
294
|
-
encodeBase64,
|
|
295
|
-
toUtf8CodePoints,
|
|
296
|
-
isHexString,
|
|
297
|
-
isBytesLike,
|
|
298
|
-
zeroPad,
|
|
299
|
-
zeroPadValue,
|
|
300
|
-
solidityPacked,
|
|
301
|
-
solidityPackedKeccak256,
|
|
302
|
-
solidityPackedSha256,
|
|
303
|
-
bytesToHex,
|
|
304
|
-
hexToBytes,
|
|
305
|
-
};
|
|
306
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Encoding/decoding helpers (ethers.js v6 compatible names).
|
|
3
|
+
*
|
|
4
|
+
* Notes:
|
|
5
|
+
* - QuantumCoin addresses are 32 bytes (not 20).
|
|
6
|
+
* - This module intentionally uses only built-in Node.js APIs.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const {
|
|
10
|
+
isUint8Array,
|
|
11
|
+
normalizeHex,
|
|
12
|
+
isHexString,
|
|
13
|
+
strip0x,
|
|
14
|
+
add0x,
|
|
15
|
+
hexToBytes,
|
|
16
|
+
bytesToHex,
|
|
17
|
+
utf8ToBytes,
|
|
18
|
+
bytesToUtf8,
|
|
19
|
+
arrayify: _arrayify,
|
|
20
|
+
} = require("../internal/hex");
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {string | Uint8Array} BytesLike
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Converts bytes to UTF-8 string.
|
|
28
|
+
* @param {BytesLike} data
|
|
29
|
+
* @returns {string}
|
|
30
|
+
*/
|
|
31
|
+
function toUtf8String(data) {
|
|
32
|
+
return bytesToUtf8(arrayify(data));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Converts string to UTF-8 bytes.
|
|
37
|
+
* @param {string} str
|
|
38
|
+
* @returns {Uint8Array}
|
|
39
|
+
*/
|
|
40
|
+
function toUtf8Bytes(str) {
|
|
41
|
+
return utf8ToBytes(str);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Converts data to hex string.
|
|
46
|
+
* @param {BytesLike} data
|
|
47
|
+
* @returns {string}
|
|
48
|
+
*/
|
|
49
|
+
function toHex(data) {
|
|
50
|
+
if (typeof data === "string") return normalizeHex(data);
|
|
51
|
+
return bytesToHex(arrayify(data));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Alias for toHex.
|
|
56
|
+
* @param {BytesLike} data
|
|
57
|
+
* @returns {string}
|
|
58
|
+
*/
|
|
59
|
+
function hexlify(data) {
|
|
60
|
+
return toHex(data);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Converts data to byte array.
|
|
65
|
+
* @param {BytesLike} data
|
|
66
|
+
* @returns {Uint8Array}
|
|
67
|
+
*/
|
|
68
|
+
function arrayify(data) {
|
|
69
|
+
return _arrayify(data);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Returns true if value is BytesLike.
|
|
74
|
+
* @param {any} value
|
|
75
|
+
* @returns {boolean}
|
|
76
|
+
*/
|
|
77
|
+
function isBytesLike(value) {
|
|
78
|
+
return (typeof value === "string" && isHexString(value)) || isUint8Array(value);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Concatenates byte arrays and returns a hex string.
|
|
83
|
+
* @param {BytesLike[]} items
|
|
84
|
+
* @returns {string}
|
|
85
|
+
*/
|
|
86
|
+
function concat(items) {
|
|
87
|
+
if (!Array.isArray(items)) throw new TypeError("items must be an array");
|
|
88
|
+
const parts = items.map((i) => arrayify(i));
|
|
89
|
+
const len = parts.reduce((a, b) => a + b.length, 0);
|
|
90
|
+
const out = new Uint8Array(len);
|
|
91
|
+
let offset = 0;
|
|
92
|
+
for (const p of parts) {
|
|
93
|
+
out.set(p, offset);
|
|
94
|
+
offset += p.length;
|
|
95
|
+
}
|
|
96
|
+
return bytesToHex(out);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Strips leading zeros from a hex string.
|
|
101
|
+
* @param {BytesLike} data
|
|
102
|
+
* @returns {string}
|
|
103
|
+
*/
|
|
104
|
+
function stripZerosLeft(data) {
|
|
105
|
+
const hex = toHex(data);
|
|
106
|
+
let h = strip0x(hex);
|
|
107
|
+
h = h.replace(/^0+/, "");
|
|
108
|
+
if (h.length === 0) return "0x";
|
|
109
|
+
if (h.length % 2 !== 0) h = "0" + h;
|
|
110
|
+
return add0x(h);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Pads a BytesLike value to the left with zeros (byte length).
|
|
115
|
+
* @param {BytesLike} value
|
|
116
|
+
* @param {number} length
|
|
117
|
+
* @returns {string}
|
|
118
|
+
*/
|
|
119
|
+
function zeroPad(value, length) {
|
|
120
|
+
const bytes = arrayify(value);
|
|
121
|
+
if (bytes.length > length) throw new RangeError("value exceeds length");
|
|
122
|
+
const out = new Uint8Array(length);
|
|
123
|
+
out.set(bytes, length - bytes.length);
|
|
124
|
+
return bytesToHex(out);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Pads a hex value (interpreted as bytes) to the left with zeros (byte length).
|
|
129
|
+
* @param {BytesLike} value
|
|
130
|
+
* @param {number} length
|
|
131
|
+
* @returns {string}
|
|
132
|
+
*/
|
|
133
|
+
function zeroPadValue(value, length) {
|
|
134
|
+
return zeroPad(value, length);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Encodes a short UTF-8 string into a bytes32 hex string.
|
|
139
|
+
* @param {string} text
|
|
140
|
+
* @returns {string}
|
|
141
|
+
*/
|
|
142
|
+
function encodeBytes32String(text) {
|
|
143
|
+
const bytes = toUtf8Bytes(text);
|
|
144
|
+
if (bytes.length > 32) throw new RangeError("string too long (max 32 bytes)");
|
|
145
|
+
const out = new Uint8Array(32);
|
|
146
|
+
out.set(bytes, 0);
|
|
147
|
+
return bytesToHex(out);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Decodes a bytes32 hex string into a UTF-8 string (trailing zeros stripped).
|
|
152
|
+
* @param {BytesLike} bytes
|
|
153
|
+
* @returns {string}
|
|
154
|
+
*/
|
|
155
|
+
function decodeBytes32String(bytes) {
|
|
156
|
+
const b = arrayify(bytes);
|
|
157
|
+
if (b.length !== 32) throw new RangeError("invalid bytes32 length");
|
|
158
|
+
let end = b.length;
|
|
159
|
+
while (end > 0 && b[end - 1] === 0) end--;
|
|
160
|
+
return bytesToUtf8(b.slice(0, end));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Base64 decode to bytes.
|
|
165
|
+
* @param {string} data
|
|
166
|
+
* @returns {Uint8Array}
|
|
167
|
+
*/
|
|
168
|
+
function decodeBase64(data) {
|
|
169
|
+
const buf = Buffer.from(data, "base64");
|
|
170
|
+
return new Uint8Array(buf);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Base64 encode BytesLike.
|
|
175
|
+
* @param {BytesLike} data
|
|
176
|
+
* @returns {string}
|
|
177
|
+
*/
|
|
178
|
+
function encodeBase64(data) {
|
|
179
|
+
return Buffer.from(arrayify(data)).toString("base64");
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Minimal base58 implementation (Bitcoin alphabet) for compatibility with ethers helpers.
|
|
183
|
+
const _B58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
184
|
+
const _B58_INDEX = new Map(_B58_ALPHABET.split("").map((c, i) => [c, i]));
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Decode Base58 string to bytes.
|
|
188
|
+
* @param {string} data
|
|
189
|
+
* @returns {Uint8Array}
|
|
190
|
+
*/
|
|
191
|
+
function decodeBase58(data) {
|
|
192
|
+
if (typeof data !== "string" || data.length === 0) throw new TypeError("invalid base58 string");
|
|
193
|
+
|
|
194
|
+
let bytes = [0];
|
|
195
|
+
for (const ch of data) {
|
|
196
|
+
const val = _B58_INDEX.get(ch);
|
|
197
|
+
if (val == null) throw new TypeError("invalid base58 character");
|
|
198
|
+
|
|
199
|
+
let carry = val;
|
|
200
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
201
|
+
const x = bytes[i] * 58 + carry;
|
|
202
|
+
bytes[i] = x & 0xff;
|
|
203
|
+
carry = x >> 8;
|
|
204
|
+
}
|
|
205
|
+
while (carry > 0) {
|
|
206
|
+
bytes.push(carry & 0xff);
|
|
207
|
+
carry >>= 8;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Deal with leading zeros
|
|
212
|
+
let leading = 0;
|
|
213
|
+
for (const ch of data) {
|
|
214
|
+
if (ch === "1") leading++;
|
|
215
|
+
else break;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const out = new Uint8Array(leading + bytes.length);
|
|
219
|
+
for (let i = 0; i < bytes.length; i++) out[out.length - 1 - i] = bytes[i];
|
|
220
|
+
return out;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Encode BytesLike as Base58.
|
|
225
|
+
* @param {BytesLike} data
|
|
226
|
+
* @returns {string}
|
|
227
|
+
*/
|
|
228
|
+
function encodeBase58(data) {
|
|
229
|
+
const bytes = arrayify(data);
|
|
230
|
+
let digits = [0];
|
|
231
|
+
|
|
232
|
+
for (const b of bytes) {
|
|
233
|
+
let carry = b;
|
|
234
|
+
for (let i = 0; i < digits.length; i++) {
|
|
235
|
+
const x = digits[i] * 256 + carry;
|
|
236
|
+
digits[i] = x % 58;
|
|
237
|
+
carry = (x / 58) | 0;
|
|
238
|
+
}
|
|
239
|
+
while (carry > 0) {
|
|
240
|
+
digits.push(carry % 58);
|
|
241
|
+
carry = (carry / 58) | 0;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Leading zeros
|
|
246
|
+
let leading = 0;
|
|
247
|
+
for (const b of bytes) {
|
|
248
|
+
if (b === 0) leading++;
|
|
249
|
+
else break;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
let out = "1".repeat(leading);
|
|
253
|
+
for (let i = digits.length - 1; i >= 0; i--) out += _B58_ALPHABET[digits[i]];
|
|
254
|
+
return out;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Returns UTF-8 code points for a string.
|
|
259
|
+
* @param {string} str
|
|
260
|
+
* @returns {number[]}
|
|
261
|
+
*/
|
|
262
|
+
function toUtf8CodePoints(str) {
|
|
263
|
+
return Array.from(str).map((c) => c.codePointAt(0) || 0);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Solidity packed encoding.
|
|
268
|
+
* This is a complex helper in ethers.js; in QuantumCoin.js it is currently not implemented.
|
|
269
|
+
* @throws
|
|
270
|
+
*/
|
|
271
|
+
function solidityPacked() {
|
|
272
|
+
throw new Error("solidityPacked is not implemented in QuantumCoin.js yet");
|
|
273
|
+
}
|
|
274
|
+
function solidityPackedKeccak256() {
|
|
275
|
+
throw new Error("solidityPackedKeccak256 is not implemented in QuantumCoin.js yet");
|
|
276
|
+
}
|
|
277
|
+
function solidityPackedSha256() {
|
|
278
|
+
throw new Error("solidityPackedSha256 is not implemented in QuantumCoin.js yet");
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
module.exports = {
|
|
282
|
+
toUtf8String,
|
|
283
|
+
toUtf8Bytes,
|
|
284
|
+
toHex,
|
|
285
|
+
hexlify,
|
|
286
|
+
arrayify,
|
|
287
|
+
concat,
|
|
288
|
+
stripZerosLeft,
|
|
289
|
+
encodeBytes32String,
|
|
290
|
+
decodeBytes32String,
|
|
291
|
+
decodeBase58,
|
|
292
|
+
decodeBase64,
|
|
293
|
+
encodeBase58,
|
|
294
|
+
encodeBase64,
|
|
295
|
+
toUtf8CodePoints,
|
|
296
|
+
isHexString,
|
|
297
|
+
isBytesLike,
|
|
298
|
+
zeroPad,
|
|
299
|
+
zeroPadValue,
|
|
300
|
+
solidityPacked,
|
|
301
|
+
solidityPackedKeccak256,
|
|
302
|
+
solidityPackedSha256,
|
|
303
|
+
bytesToHex,
|
|
304
|
+
hexToBytes,
|
|
305
|
+
};
|
|
306
|
+
|