quantumcoin 7.0.6 → 7.0.8
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-SDK.md +53 -1
- package/SPEC.md +1 -1
- package/examples/package-lock.json +103 -454
- package/examples/package.json +1 -1
- package/generate-sdk.js +1 -0
- package/package.json +2 -2
- package/src/utils/fixednumber.d.ts +57 -0
- package/src/utils/fixednumber.js +366 -0
- package/src/utils/hashing.js +1 -1
- package/src/utils/index.d.ts +1 -0
- package/src/utils/index.js +1 -0
- package/src/wallet/wallet.d.ts +15 -1
- package/src/wallet/wallet.js +45 -3
- package/test/unit/address-wallet.test.js +172 -0
- package/test/unit/address-wallet.test.ts +170 -0
- package/test/unit/fixednumber.test.js +656 -0
- package/test/unit/fixednumber.test.ts +660 -0
- package/test/unit/hashing.test.js +7 -0
- package/test/unit/hashing.test.ts +7 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "quantumcoin",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.8",
|
|
4
4
|
"description": "QuantumCoin SDK - a complete SDK for dapps",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"types": "src/index.d.ts",
|
|
@@ -90,6 +90,6 @@
|
|
|
90
90
|
},
|
|
91
91
|
"dependencies": {
|
|
92
92
|
"seed-words": "^1.0.2",
|
|
93
|
-
"quantum-coin-js-sdk": "1.0.
|
|
93
|
+
"quantum-coin-js-sdk": "1.0.32"
|
|
94
94
|
}
|
|
95
95
|
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { BytesLike } from "./encoding";
|
|
2
|
+
|
|
3
|
+
export type BigNumberish = string | number | bigint;
|
|
4
|
+
|
|
5
|
+
export type FixedFormat = number | string | {
|
|
6
|
+
signed?: boolean;
|
|
7
|
+
width?: number;
|
|
8
|
+
decimals?: number;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export class FixedNumber {
|
|
12
|
+
private constructor(guard: any, value: bigint, format: any);
|
|
13
|
+
|
|
14
|
+
readonly format: string;
|
|
15
|
+
readonly _value: string;
|
|
16
|
+
|
|
17
|
+
get signed(): boolean;
|
|
18
|
+
get width(): number;
|
|
19
|
+
get decimals(): number;
|
|
20
|
+
get value(): bigint;
|
|
21
|
+
|
|
22
|
+
add(other: FixedNumber): FixedNumber;
|
|
23
|
+
addUnsafe(other: FixedNumber): FixedNumber;
|
|
24
|
+
sub(other: FixedNumber): FixedNumber;
|
|
25
|
+
subUnsafe(other: FixedNumber): FixedNumber;
|
|
26
|
+
mul(other: FixedNumber): FixedNumber;
|
|
27
|
+
mulUnsafe(other: FixedNumber): FixedNumber;
|
|
28
|
+
mulSignal(other: FixedNumber): FixedNumber;
|
|
29
|
+
div(other: FixedNumber): FixedNumber;
|
|
30
|
+
divUnsafe(other: FixedNumber): FixedNumber;
|
|
31
|
+
divSignal(other: FixedNumber): FixedNumber;
|
|
32
|
+
|
|
33
|
+
cmp(other: FixedNumber): number;
|
|
34
|
+
eq(other: FixedNumber): boolean;
|
|
35
|
+
lt(other: FixedNumber): boolean;
|
|
36
|
+
lte(other: FixedNumber): boolean;
|
|
37
|
+
gt(other: FixedNumber): boolean;
|
|
38
|
+
gte(other: FixedNumber): boolean;
|
|
39
|
+
|
|
40
|
+
floor(): FixedNumber;
|
|
41
|
+
ceiling(): FixedNumber;
|
|
42
|
+
round(decimals?: number): FixedNumber;
|
|
43
|
+
|
|
44
|
+
isZero(): boolean;
|
|
45
|
+
isNegative(): boolean;
|
|
46
|
+
|
|
47
|
+
toString(): string;
|
|
48
|
+
toUnsafeFloat(): number;
|
|
49
|
+
toFormat(format: FixedFormat): FixedNumber;
|
|
50
|
+
toHexString(width?: number): string;
|
|
51
|
+
|
|
52
|
+
static fromValue(value: BigNumberish, decimals?: number, format?: FixedFormat): FixedNumber;
|
|
53
|
+
static fromString(value: string, format?: FixedFormat): FixedNumber;
|
|
54
|
+
static fromBytes(value: BytesLike, format?: FixedFormat): FixedNumber;
|
|
55
|
+
static from(value: any, format?: FixedFormat): FixedNumber;
|
|
56
|
+
static isFixedNumber(value: any): value is FixedNumber;
|
|
57
|
+
}
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Fixed-point arithmetic (ethers.js v5/v6 compatible).
|
|
3
|
+
*
|
|
4
|
+
* FixedNumber stores values as a bigint multiplied by 10**decimals,
|
|
5
|
+
* inside a fixed bit-width field. All instances are immutable.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { makeError, assertArgument, assert } = require("../errors");
|
|
9
|
+
const { arrayify, hexlify, isBytesLike, zeroPad } = require("./encoding");
|
|
10
|
+
|
|
11
|
+
const BN_N1 = -1n;
|
|
12
|
+
const BN_0 = 0n;
|
|
13
|
+
const BN_1 = 1n;
|
|
14
|
+
const BN_5 = 5n;
|
|
15
|
+
|
|
16
|
+
const _guard = {};
|
|
17
|
+
|
|
18
|
+
let _zeros = "0000";
|
|
19
|
+
while (_zeros.length < 80) { _zeros += _zeros; }
|
|
20
|
+
|
|
21
|
+
function _getTens(decimals) {
|
|
22
|
+
let z = _zeros;
|
|
23
|
+
while (z.length < decimals) { z += z; }
|
|
24
|
+
return BigInt("1" + z.substring(0, decimals));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function _fromTwos(value, width) {
|
|
28
|
+
const limit = BN_1 << BigInt(width);
|
|
29
|
+
if (value & (limit >> BN_1)) {
|
|
30
|
+
return value - limit;
|
|
31
|
+
}
|
|
32
|
+
return value;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function _mask(value, width) {
|
|
36
|
+
return value & ((BN_1 << BigInt(width)) - BN_1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function _checkValue(val, format, safeOp) {
|
|
40
|
+
const width = BigInt(format.width);
|
|
41
|
+
if (format.signed) {
|
|
42
|
+
const limit = BN_1 << (width - BN_1);
|
|
43
|
+
assert(safeOp == null || (val >= -limit && val < limit), "overflow", "NUMERIC_FAULT", {
|
|
44
|
+
operation: safeOp, fault: "overflow", value: val,
|
|
45
|
+
});
|
|
46
|
+
if (val > BN_0) {
|
|
47
|
+
val = _fromTwos(_mask(val, width), format.width);
|
|
48
|
+
} else if (val < BN_0) {
|
|
49
|
+
val = -_fromTwos(_mask(-val, width), format.width);
|
|
50
|
+
}
|
|
51
|
+
} else {
|
|
52
|
+
const limit = BN_1 << width;
|
|
53
|
+
assert(safeOp == null || (val >= BN_0 && val < limit), "overflow", "NUMERIC_FAULT", {
|
|
54
|
+
operation: safeOp, fault: "overflow", value: val,
|
|
55
|
+
});
|
|
56
|
+
val = ((val % limit) + limit) % limit & (limit - BN_1);
|
|
57
|
+
}
|
|
58
|
+
return val;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* @param {import("./units").BigNumberish} value
|
|
63
|
+
* @returns {bigint}
|
|
64
|
+
*/
|
|
65
|
+
function _getBigInt(value) {
|
|
66
|
+
if (typeof value === "bigint") return value;
|
|
67
|
+
if (typeof value === "number") {
|
|
68
|
+
assertArgument(Number.isInteger(value), "invalid numeric value", "value", value);
|
|
69
|
+
return BigInt(value);
|
|
70
|
+
}
|
|
71
|
+
if (typeof value === "string") {
|
|
72
|
+
const v = value.trim();
|
|
73
|
+
assertArgument(v.length > 0 && /^-?(?:0x[0-9a-fA-F]+|[0-9]+)$/.test(v), "invalid BigNumberish string", "value", value);
|
|
74
|
+
return BigInt(v);
|
|
75
|
+
}
|
|
76
|
+
assertArgument(false, "invalid BigNumberish", "value", value);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function _getFormat(value) {
|
|
80
|
+
if (typeof value === "number") { value = `fixed128x${value}`; }
|
|
81
|
+
|
|
82
|
+
let signed = true;
|
|
83
|
+
let width = 128;
|
|
84
|
+
let decimals = 18;
|
|
85
|
+
|
|
86
|
+
if (typeof value === "string") {
|
|
87
|
+
if (value === "fixed") {
|
|
88
|
+
// defaults
|
|
89
|
+
} else if (value === "ufixed") {
|
|
90
|
+
signed = false;
|
|
91
|
+
} else {
|
|
92
|
+
const match = value.match(/^(u?)fixed([0-9]+)x([0-9]+)$/);
|
|
93
|
+
assertArgument(match, "invalid fixed format", "format", value);
|
|
94
|
+
signed = match[1] !== "u";
|
|
95
|
+
width = parseInt(match[2]);
|
|
96
|
+
decimals = parseInt(match[3]);
|
|
97
|
+
}
|
|
98
|
+
} else if (value != null && typeof value === "object") {
|
|
99
|
+
const check = (key, type, defaultValue) => {
|
|
100
|
+
if (value[key] == null) return defaultValue;
|
|
101
|
+
assertArgument(typeof value[key] === type,
|
|
102
|
+
`invalid fixed format (${key} not ${type})`, `format.${key}`, value[key]);
|
|
103
|
+
return value[key];
|
|
104
|
+
};
|
|
105
|
+
signed = check("signed", "boolean", signed);
|
|
106
|
+
width = check("width", "number", width);
|
|
107
|
+
decimals = check("decimals", "number", decimals);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
assertArgument(width % 8 === 0, "invalid FixedNumber width (not byte aligned)", "format.width", width);
|
|
111
|
+
assertArgument(decimals <= 80, "invalid FixedNumber decimals (too large)", "format.decimals", decimals);
|
|
112
|
+
|
|
113
|
+
const name = (signed ? "" : "u") + "fixed" + String(width) + "x" + String(decimals);
|
|
114
|
+
return { signed, width, decimals, name };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function _toString(val, decimals) {
|
|
118
|
+
let negative = "";
|
|
119
|
+
if (val < BN_0) {
|
|
120
|
+
negative = "-";
|
|
121
|
+
val *= BN_N1;
|
|
122
|
+
}
|
|
123
|
+
let str = val.toString();
|
|
124
|
+
if (decimals === 0) return negative + str;
|
|
125
|
+
|
|
126
|
+
while (str.length <= decimals) { str = _zeros + str; }
|
|
127
|
+
const index = str.length - decimals;
|
|
128
|
+
str = str.substring(0, index) + "." + str.substring(index);
|
|
129
|
+
|
|
130
|
+
while (str[0] === "0" && str[1] !== ".") { str = str.substring(1); }
|
|
131
|
+
while (str[str.length - 1] === "0" && str[str.length - 2] !== ".") { str = str.substring(0, str.length - 1); }
|
|
132
|
+
|
|
133
|
+
return negative + str;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
class FixedNumber {
|
|
137
|
+
/**
|
|
138
|
+
* @param {any} guard
|
|
139
|
+
* @param {bigint} value
|
|
140
|
+
* @param {any} format
|
|
141
|
+
*/
|
|
142
|
+
constructor(guard, value, format) {
|
|
143
|
+
assertArgument(guard === _guard, "cannot use FixedNumber constructor; use FixedNumber.from", "guard", "INVALID");
|
|
144
|
+
|
|
145
|
+
/** @type {bigint} */
|
|
146
|
+
this._val = value;
|
|
147
|
+
/** @type {{ signed: boolean, width: number, decimals: number, name: string }} */
|
|
148
|
+
this._format = format;
|
|
149
|
+
/** @type {string} */
|
|
150
|
+
this.format = format.name;
|
|
151
|
+
/** @type {string} */
|
|
152
|
+
this._value = _toString(value, format.decimals);
|
|
153
|
+
/** @type {bigint} */
|
|
154
|
+
this._tens = _getTens(format.decimals);
|
|
155
|
+
|
|
156
|
+
Object.freeze(this);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
get signed() { return this._format.signed; }
|
|
160
|
+
get width() { return this._format.width; }
|
|
161
|
+
get decimals() { return this._format.decimals; }
|
|
162
|
+
get value() { return this._val; }
|
|
163
|
+
|
|
164
|
+
_checkFormat(other) {
|
|
165
|
+
assertArgument(this.format === other.format,
|
|
166
|
+
"incompatible format; use fixedNumber.toFormat", "other", other);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
_checkValue(val, safeOp) {
|
|
170
|
+
val = _checkValue(val, this._format, safeOp);
|
|
171
|
+
return new FixedNumber(_guard, val, this._format);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// --- Arithmetic -----------------------------------------------------------
|
|
175
|
+
|
|
176
|
+
_add(o, safeOp) {
|
|
177
|
+
this._checkFormat(o);
|
|
178
|
+
return this._checkValue(this._val + o._val, safeOp);
|
|
179
|
+
}
|
|
180
|
+
addUnsafe(other) { return this._add(other); }
|
|
181
|
+
add(other) { return this._add(other, "add"); }
|
|
182
|
+
|
|
183
|
+
_sub(o, safeOp) {
|
|
184
|
+
this._checkFormat(o);
|
|
185
|
+
return this._checkValue(this._val - o._val, safeOp);
|
|
186
|
+
}
|
|
187
|
+
subUnsafe(other) { return this._sub(other); }
|
|
188
|
+
sub(other) { return this._sub(other, "sub"); }
|
|
189
|
+
|
|
190
|
+
_mul(o, safeOp) {
|
|
191
|
+
this._checkFormat(o);
|
|
192
|
+
return this._checkValue((this._val * o._val) / this._tens, safeOp);
|
|
193
|
+
}
|
|
194
|
+
mulUnsafe(other) { return this._mul(other); }
|
|
195
|
+
mul(other) { return this._mul(other, "mul"); }
|
|
196
|
+
|
|
197
|
+
mulSignal(other) {
|
|
198
|
+
this._checkFormat(other);
|
|
199
|
+
const value = this._val * other._val;
|
|
200
|
+
assert(value % this._tens === BN_0, "precision lost during signalling mul", "NUMERIC_FAULT", {
|
|
201
|
+
operation: "mulSignal", fault: "underflow", value: this,
|
|
202
|
+
});
|
|
203
|
+
return this._checkValue(value / this._tens, "mulSignal");
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
_div(o, safeOp) {
|
|
207
|
+
assert(o._val !== BN_0, "division by zero", "NUMERIC_FAULT", {
|
|
208
|
+
operation: "div", fault: "divide-by-zero", value: this,
|
|
209
|
+
});
|
|
210
|
+
this._checkFormat(o);
|
|
211
|
+
return this._checkValue((this._val * this._tens) / o._val, safeOp);
|
|
212
|
+
}
|
|
213
|
+
divUnsafe(other) { return this._div(other); }
|
|
214
|
+
div(other) { return this._div(other, "div"); }
|
|
215
|
+
|
|
216
|
+
divSignal(other) {
|
|
217
|
+
assert(other._val !== BN_0, "division by zero", "NUMERIC_FAULT", {
|
|
218
|
+
operation: "div", fault: "divide-by-zero", value: this,
|
|
219
|
+
});
|
|
220
|
+
this._checkFormat(other);
|
|
221
|
+
const value = this._val * this._tens;
|
|
222
|
+
assert(value % other._val === BN_0, "precision lost during signalling div", "NUMERIC_FAULT", {
|
|
223
|
+
operation: "divSignal", fault: "underflow", value: this,
|
|
224
|
+
});
|
|
225
|
+
return this._checkValue(value / other._val, "divSignal");
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// --- Comparison -----------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
cmp(other) {
|
|
231
|
+
let a = this._val, b = other._val;
|
|
232
|
+
const delta = this.decimals - other.decimals;
|
|
233
|
+
if (delta > 0) { b *= _getTens(delta); }
|
|
234
|
+
else if (delta < 0) { a *= _getTens(-delta); }
|
|
235
|
+
if (a < b) return -1;
|
|
236
|
+
if (a > b) return 1;
|
|
237
|
+
return 0;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
eq(other) { return this.cmp(other) === 0; }
|
|
241
|
+
lt(other) { return this.cmp(other) < 0; }
|
|
242
|
+
lte(other) { return this.cmp(other) <= 0; }
|
|
243
|
+
gt(other) { return this.cmp(other) > 0; }
|
|
244
|
+
gte(other) { return this.cmp(other) >= 0; }
|
|
245
|
+
|
|
246
|
+
// --- Rounding -------------------------------------------------------------
|
|
247
|
+
|
|
248
|
+
floor() {
|
|
249
|
+
let val = this._val;
|
|
250
|
+
if (val < BN_0) { val -= this._tens - BN_1; }
|
|
251
|
+
val = (val / this._tens) * this._tens;
|
|
252
|
+
return this._checkValue(val, "floor");
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
ceiling() {
|
|
256
|
+
let val = this._val;
|
|
257
|
+
if (val > BN_0) { val += this._tens - BN_1; }
|
|
258
|
+
val = (val / this._tens) * this._tens;
|
|
259
|
+
return this._checkValue(val, "ceiling");
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
round(decimals) {
|
|
263
|
+
if (decimals == null) { decimals = 0; }
|
|
264
|
+
if (decimals >= this.decimals) return this;
|
|
265
|
+
const delta = this.decimals - decimals;
|
|
266
|
+
const bump = BN_5 * _getTens(delta - 1);
|
|
267
|
+
let value = this._val;
|
|
268
|
+
if (value < BN_0) { value -= bump; } else { value += bump; }
|
|
269
|
+
const tens = _getTens(delta);
|
|
270
|
+
value = (value / tens) * tens;
|
|
271
|
+
_checkValue(value, this._format, "round");
|
|
272
|
+
return new FixedNumber(_guard, value, this._format);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// --- Inspection -----------------------------------------------------------
|
|
276
|
+
|
|
277
|
+
isZero() { return this._val === BN_0; }
|
|
278
|
+
isNegative() { return this._val < BN_0; }
|
|
279
|
+
|
|
280
|
+
// --- Conversion -----------------------------------------------------------
|
|
281
|
+
|
|
282
|
+
toString() { return this._value; }
|
|
283
|
+
toUnsafeFloat() { return parseFloat(this.toString()); }
|
|
284
|
+
|
|
285
|
+
toFormat(format) {
|
|
286
|
+
return FixedNumber.fromString(this._value, format);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
toHexString(width) {
|
|
290
|
+
let val = this._val;
|
|
291
|
+
const w = width || this.width;
|
|
292
|
+
if (this._format.signed && val < BN_0) {
|
|
293
|
+
val = (BN_1 << BigInt(w)) + val;
|
|
294
|
+
}
|
|
295
|
+
let hex = val.toString(16);
|
|
296
|
+
const byteLen = w / 8;
|
|
297
|
+
while (hex.length < byteLen * 2) { hex = "0" + hex; }
|
|
298
|
+
return "0x" + hex;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// --- Static factories -----------------------------------------------------
|
|
302
|
+
|
|
303
|
+
static fromValue(_value, decimals, _format) {
|
|
304
|
+
if (decimals == null) { decimals = 0; }
|
|
305
|
+
const format = _getFormat(_format);
|
|
306
|
+
let value = _getBigInt(_value);
|
|
307
|
+
const delta = decimals - format.decimals;
|
|
308
|
+
if (delta > 0) {
|
|
309
|
+
const tens = _getTens(delta);
|
|
310
|
+
assert(value % tens === BN_0, "value loses precision for format", "NUMERIC_FAULT", {
|
|
311
|
+
operation: "fromValue", fault: "underflow", value: _value,
|
|
312
|
+
});
|
|
313
|
+
value /= tens;
|
|
314
|
+
} else if (delta < 0) {
|
|
315
|
+
value *= _getTens(-delta);
|
|
316
|
+
}
|
|
317
|
+
_checkValue(value, format, "fromValue");
|
|
318
|
+
return new FixedNumber(_guard, value, format);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
static fromString(_value, _format) {
|
|
322
|
+
const match = _value.match(/^(-?)([0-9]*)\.?([0-9]*)$/);
|
|
323
|
+
assertArgument(match && (match[2].length + match[3].length) > 0,
|
|
324
|
+
"invalid FixedNumber string value", "value", _value);
|
|
325
|
+
const format = _getFormat(_format);
|
|
326
|
+
let whole = match[2] || "0";
|
|
327
|
+
let decimal = match[3] || "";
|
|
328
|
+
|
|
329
|
+
while (decimal.length < format.decimals) { decimal += _zeros; }
|
|
330
|
+
|
|
331
|
+
assert(decimal.substring(format.decimals).match(/^0*$/),
|
|
332
|
+
"too many decimals for format", "NUMERIC_FAULT", {
|
|
333
|
+
operation: "fromString", fault: "underflow", value: _value,
|
|
334
|
+
});
|
|
335
|
+
decimal = decimal.substring(0, format.decimals);
|
|
336
|
+
|
|
337
|
+
const value = BigInt(match[1] + whole + decimal);
|
|
338
|
+
_checkValue(value, format, "fromString");
|
|
339
|
+
return new FixedNumber(_guard, value, format);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
static fromBytes(_value, _format) {
|
|
343
|
+
let value = BigInt("0x" + hexlify(arrayify(_value)).replace(/^0x/, ""));
|
|
344
|
+
const format = _getFormat(_format);
|
|
345
|
+
if (format.signed) { value = _fromTwos(value, format.width); }
|
|
346
|
+
_checkValue(value, format, "fromBytes");
|
|
347
|
+
return new FixedNumber(_guard, value, format);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
static from(value, format) {
|
|
351
|
+
if (typeof value === "string") return FixedNumber.fromString(value, format);
|
|
352
|
+
if (isBytesLike(value)) return FixedNumber.fromBytes(value, format);
|
|
353
|
+
try {
|
|
354
|
+
return FixedNumber.fromValue(value, 0, format);
|
|
355
|
+
} catch (error) {
|
|
356
|
+
if (error.code !== "INVALID_ARGUMENT") throw error;
|
|
357
|
+
}
|
|
358
|
+
return assertArgument(false, "invalid FixedNumber value", "value", value);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
static isFixedNumber(value) {
|
|
362
|
+
return !!(value && value instanceof FixedNumber);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
module.exports = { FixedNumber };
|
package/src/utils/hashing.js
CHANGED
|
@@ -293,7 +293,7 @@ function scrypt(password, salt, N, r, p, dkLen) {
|
|
|
293
293
|
function scryptSync(password, salt, N, r, p, dkLen) {
|
|
294
294
|
const pw = arrayify(password);
|
|
295
295
|
const sa = arrayify(salt);
|
|
296
|
-
const out = crypto.scryptSync(Buffer.from(pw), Buffer.from(sa), dkLen, { N, r, p, maxmem:
|
|
296
|
+
const out = crypto.scryptSync(Buffer.from(pw), Buffer.from(sa), dkLen, { N, r, p, maxmem: 257 * 1024 * 1024 }); //257 instead of 256 for buffer for compat for N=262144, r=8, p=1
|
|
297
297
|
return bytesToHex(new Uint8Array(out));
|
|
298
298
|
}
|
|
299
299
|
|
package/src/utils/index.d.ts
CHANGED
|
@@ -61,5 +61,6 @@ declare const _exports: {
|
|
|
61
61
|
computeAddress(key: string | Uint8Array): string;
|
|
62
62
|
verifyMessage(message: string | Uint8Array, signature: string): string;
|
|
63
63
|
recoverAddress(message: string | Uint8Array, signature: string): string;
|
|
64
|
+
FixedNumber: typeof import("./fixednumber").FixedNumber;
|
|
64
65
|
};
|
|
65
66
|
export = _exports;
|
package/src/utils/index.js
CHANGED
package/src/wallet/wallet.d.ts
CHANGED
|
@@ -66,9 +66,23 @@ export class Wallet extends BaseWallet {
|
|
|
66
66
|
/**
|
|
67
67
|
* Creates a new random wallet.
|
|
68
68
|
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
69
|
+
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
69
70
|
* @returns {Wallet}
|
|
70
71
|
*/
|
|
71
|
-
static createRandom(provider?: import("../providers/provider").AbstractProvider | undefined): Wallet;
|
|
72
|
+
static createRandom(provider?: import("../providers/provider").AbstractProvider | undefined, keyType?: number | null): Wallet;
|
|
73
|
+
/**
|
|
74
|
+
* Creates a new random seed word list (32 words for keyType 3, 36 for keyType 5).
|
|
75
|
+
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
76
|
+
* @returns {string[]}
|
|
77
|
+
*/
|
|
78
|
+
static createRandomSeed(keyType?: number | null): string[];
|
|
79
|
+
/**
|
|
80
|
+
* Creates a wallet from raw seed bytes.
|
|
81
|
+
* @param {number[]} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
82
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
83
|
+
* @returns {Wallet}
|
|
84
|
+
*/
|
|
85
|
+
static fromSeed(seed: number[], provider?: import("../providers/provider").AbstractProvider | undefined): Wallet;
|
|
72
86
|
/**
|
|
73
87
|
* Creates a wallet from an encrypted JSON string.
|
|
74
88
|
* @param {string} json
|
package/src/wallet/wallet.js
CHANGED
|
@@ -323,12 +323,54 @@ class Wallet extends BaseWallet {
|
|
|
323
323
|
/**
|
|
324
324
|
* Creates a new random wallet.
|
|
325
325
|
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
326
|
+
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
326
327
|
* @returns {Wallet}
|
|
327
328
|
*/
|
|
328
|
-
static createRandom(provider) {
|
|
329
|
+
static createRandom(provider, keyType) {
|
|
329
330
|
_requireInitialized();
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
if (keyType != null) {
|
|
332
|
+
assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
|
|
333
|
+
}
|
|
334
|
+
const qcWallet = qcsdk.newWallet(keyType ?? null);
|
|
335
|
+
if (!qcWallet || typeof qcWallet === "number") {
|
|
336
|
+
throw makeError("newWallet failed", "UNKNOWN_ERROR", { result: qcWallet });
|
|
337
|
+
}
|
|
338
|
+
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Creates a new random seed word list (32 words for keyType 3, 36 for keyType 5).
|
|
343
|
+
* Use the returned words with `Wallet.fromPhrase()` to create a wallet.
|
|
344
|
+
* @param {number|null=} keyType Optional key type: null (default=3), 3, or 5
|
|
345
|
+
* @returns {string[]}
|
|
346
|
+
*/
|
|
347
|
+
static createRandomSeed(keyType) {
|
|
348
|
+
_requireInitialized();
|
|
349
|
+
if (keyType != null) {
|
|
350
|
+
assertArgument(keyType === 3 || keyType === 5, "keyType must be null, 3, or 5", "keyType", keyType);
|
|
351
|
+
}
|
|
352
|
+
const words = qcsdk.newWalletSeed(keyType ?? null);
|
|
353
|
+
if (!words || !Array.isArray(words)) {
|
|
354
|
+
throw makeError("newWalletSeed failed", "UNKNOWN_ERROR", { result: words });
|
|
355
|
+
}
|
|
356
|
+
return words;
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Creates a wallet from raw seed bytes.
|
|
361
|
+
* @param {number[]} seed Raw seed bytes: 64 (keyType 3), 72 (keyType 5), or 96 (legacy)
|
|
362
|
+
* @param {import("../providers/provider").AbstractProvider=} provider
|
|
363
|
+
* @returns {Wallet}
|
|
364
|
+
*/
|
|
365
|
+
static fromSeed(seed, provider) {
|
|
366
|
+
_requireInitialized();
|
|
367
|
+
assertArgument(Array.isArray(seed), "seed must be an array of numbers", "seed", seed);
|
|
368
|
+
const allowedLengths = [64, 72, 96];
|
|
369
|
+
assertArgument(allowedLengths.includes(seed.length), "seed must be 64, 72, or 96 bytes", "seed", seed.length);
|
|
370
|
+
const qcWallet = qcsdk.openWalletFromSeed(seed);
|
|
371
|
+
if (!qcWallet || typeof qcWallet === "number") {
|
|
372
|
+
throw makeError("openWalletFromSeed failed", "UNKNOWN_ERROR", { result: qcWallet });
|
|
373
|
+
}
|
|
332
374
|
return Wallet._fromQcWallet(qcWallet, provider || null);
|
|
333
375
|
}
|
|
334
376
|
|