1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | import _BN from "bn.js";
|
10 | var BN = _BN.BN;
|
11 | import { hexlify, isBytes, isHexString } from "@ethersproject/bytes";
|
12 | import { Logger } from "@ethersproject/logger";
|
13 | import { version } from "./_version";
|
14 | const logger = new Logger(version);
|
15 | const _constructorGuard = {};
|
16 | const MAX_SAFE = 0x1fffffffffffff;
|
17 | export function isBigNumberish(value) {
|
18 | return (value != null) && (BigNumber.isBigNumber(value) ||
|
19 | (typeof (value) === "number" && (value % 1) === 0) ||
|
20 | (typeof (value) === "string" && !!value.match(/^-?[0-9]+$/)) ||
|
21 | isHexString(value) ||
|
22 | (typeof (value) === "bigint") ||
|
23 | isBytes(value));
|
24 | }
|
25 |
|
26 | let _warnedToStringRadix = false;
|
27 | export class BigNumber {
|
28 | constructor(constructorGuard, hex) {
|
29 | logger.checkNew(new.target, BigNumber);
|
30 | if (constructorGuard !== _constructorGuard) {
|
31 | logger.throwError("cannot call constructor directly; use BigNumber.from", Logger.errors.UNSUPPORTED_OPERATION, {
|
32 | operation: "new (BigNumber)"
|
33 | });
|
34 | }
|
35 | this._hex = hex;
|
36 | this._isBigNumber = true;
|
37 | Object.freeze(this);
|
38 | }
|
39 | fromTwos(value) {
|
40 | return toBigNumber(toBN(this).fromTwos(value));
|
41 | }
|
42 | toTwos(value) {
|
43 | return toBigNumber(toBN(this).toTwos(value));
|
44 | }
|
45 | abs() {
|
46 | if (this._hex[0] === "-") {
|
47 | return BigNumber.from(this._hex.substring(1));
|
48 | }
|
49 | return this;
|
50 | }
|
51 | add(other) {
|
52 | return toBigNumber(toBN(this).add(toBN(other)));
|
53 | }
|
54 | sub(other) {
|
55 | return toBigNumber(toBN(this).sub(toBN(other)));
|
56 | }
|
57 | div(other) {
|
58 | const o = BigNumber.from(other);
|
59 | if (o.isZero()) {
|
60 | throwFault("division-by-zero", "div");
|
61 | }
|
62 | return toBigNumber(toBN(this).div(toBN(other)));
|
63 | }
|
64 | mul(other) {
|
65 | return toBigNumber(toBN(this).mul(toBN(other)));
|
66 | }
|
67 | mod(other) {
|
68 | const value = toBN(other);
|
69 | if (value.isNeg()) {
|
70 | throwFault("division-by-zero", "mod");
|
71 | }
|
72 | return toBigNumber(toBN(this).umod(value));
|
73 | }
|
74 | pow(other) {
|
75 | const value = toBN(other);
|
76 | if (value.isNeg()) {
|
77 | throwFault("negative-power", "pow");
|
78 | }
|
79 | return toBigNumber(toBN(this).pow(value));
|
80 | }
|
81 | and(other) {
|
82 | const value = toBN(other);
|
83 | if (this.isNegative() || value.isNeg()) {
|
84 | throwFault("unbound-bitwise-result", "and");
|
85 | }
|
86 | return toBigNumber(toBN(this).and(value));
|
87 | }
|
88 | or(other) {
|
89 | const value = toBN(other);
|
90 | if (this.isNegative() || value.isNeg()) {
|
91 | throwFault("unbound-bitwise-result", "or");
|
92 | }
|
93 | return toBigNumber(toBN(this).or(value));
|
94 | }
|
95 | xor(other) {
|
96 | const value = toBN(other);
|
97 | if (this.isNegative() || value.isNeg()) {
|
98 | throwFault("unbound-bitwise-result", "xor");
|
99 | }
|
100 | return toBigNumber(toBN(this).xor(value));
|
101 | }
|
102 | mask(value) {
|
103 | if (this.isNegative() || value < 0) {
|
104 | throwFault("negative-width", "mask");
|
105 | }
|
106 | return toBigNumber(toBN(this).maskn(value));
|
107 | }
|
108 | shl(value) {
|
109 | if (this.isNegative() || value < 0) {
|
110 | throwFault("negative-width", "shl");
|
111 | }
|
112 | return toBigNumber(toBN(this).shln(value));
|
113 | }
|
114 | shr(value) {
|
115 | if (this.isNegative() || value < 0) {
|
116 | throwFault("negative-width", "shr");
|
117 | }
|
118 | return toBigNumber(toBN(this).shrn(value));
|
119 | }
|
120 | eq(other) {
|
121 | return toBN(this).eq(toBN(other));
|
122 | }
|
123 | lt(other) {
|
124 | return toBN(this).lt(toBN(other));
|
125 | }
|
126 | lte(other) {
|
127 | return toBN(this).lte(toBN(other));
|
128 | }
|
129 | gt(other) {
|
130 | return toBN(this).gt(toBN(other));
|
131 | }
|
132 | gte(other) {
|
133 | return toBN(this).gte(toBN(other));
|
134 | }
|
135 | isNegative() {
|
136 | return (this._hex[0] === "-");
|
137 | }
|
138 | isZero() {
|
139 | return toBN(this).isZero();
|
140 | }
|
141 | toNumber() {
|
142 | try {
|
143 | return toBN(this).toNumber();
|
144 | }
|
145 | catch (error) {
|
146 | throwFault("overflow", "toNumber", this.toString());
|
147 | }
|
148 | return null;
|
149 | }
|
150 | toBigInt() {
|
151 | try {
|
152 | return BigInt(this.toString());
|
153 | }
|
154 | catch (e) { }
|
155 | return logger.throwError("this platform does not support BigInt", Logger.errors.UNSUPPORTED_OPERATION, {
|
156 | value: this.toString()
|
157 | });
|
158 | }
|
159 | toString() {
|
160 |
|
161 | if (arguments.length > 0) {
|
162 | if (arguments[0] === 10) {
|
163 | if (!_warnedToStringRadix) {
|
164 | _warnedToStringRadix = true;
|
165 | logger.warn("BigNumber.toString does not accept any parameters; base-10 is assumed");
|
166 | }
|
167 | }
|
168 | else if (arguments[0] === 16) {
|
169 | logger.throwError("BigNumber.toString does not accept any parameters; use bigNumber.toHexString()", Logger.errors.UNEXPECTED_ARGUMENT, {});
|
170 | }
|
171 | else {
|
172 | logger.throwError("BigNumber.toString does not accept parameters", Logger.errors.UNEXPECTED_ARGUMENT, {});
|
173 | }
|
174 | }
|
175 | return toBN(this).toString(10);
|
176 | }
|
177 | toHexString() {
|
178 | return this._hex;
|
179 | }
|
180 | toJSON(key) {
|
181 | return { type: "BigNumber", hex: this.toHexString() };
|
182 | }
|
183 | static from(value) {
|
184 | if (value instanceof BigNumber) {
|
185 | return value;
|
186 | }
|
187 | if (typeof (value) === "string") {
|
188 | if (value.match(/^-?0x[0-9a-f]+$/i)) {
|
189 | return new BigNumber(_constructorGuard, toHex(value));
|
190 | }
|
191 | if (value.match(/^-?[0-9]+$/)) {
|
192 | return new BigNumber(_constructorGuard, toHex(new BN(value)));
|
193 | }
|
194 | return logger.throwArgumentError("invalid BigNumber string", "value", value);
|
195 | }
|
196 | if (typeof (value) === "number") {
|
197 | if (value % 1) {
|
198 | throwFault("underflow", "BigNumber.from", value);
|
199 | }
|
200 | if (value >= MAX_SAFE || value <= -MAX_SAFE) {
|
201 | throwFault("overflow", "BigNumber.from", value);
|
202 | }
|
203 | return BigNumber.from(String(value));
|
204 | }
|
205 | const anyValue = value;
|
206 | if (typeof (anyValue) === "bigint") {
|
207 | return BigNumber.from(anyValue.toString());
|
208 | }
|
209 | if (isBytes(anyValue)) {
|
210 | return BigNumber.from(hexlify(anyValue));
|
211 | }
|
212 | if (anyValue) {
|
213 |
|
214 | if (anyValue.toHexString) {
|
215 | const hex = anyValue.toHexString();
|
216 | if (typeof (hex) === "string") {
|
217 | return BigNumber.from(hex);
|
218 | }
|
219 | }
|
220 | else {
|
221 |
|
222 | let hex = anyValue._hex;
|
223 |
|
224 | if (hex == null && anyValue.type === "BigNumber") {
|
225 | hex = anyValue.hex;
|
226 | }
|
227 | if (typeof (hex) === "string") {
|
228 | if (isHexString(hex) || (hex[0] === "-" && isHexString(hex.substring(1)))) {
|
229 | return BigNumber.from(hex);
|
230 | }
|
231 | }
|
232 | }
|
233 | }
|
234 | return logger.throwArgumentError("invalid BigNumber value", "value", value);
|
235 | }
|
236 | static isBigNumber(value) {
|
237 | return !!(value && value._isBigNumber);
|
238 | }
|
239 | }
|
240 |
|
241 | function toHex(value) {
|
242 |
|
243 | if (typeof (value) !== "string") {
|
244 | return toHex(value.toString(16));
|
245 | }
|
246 |
|
247 | if (value[0] === "-") {
|
248 |
|
249 | value = value.substring(1);
|
250 |
|
251 | if (value[0] === "-") {
|
252 | logger.throwArgumentError("invalid hex", "value", value);
|
253 | }
|
254 |
|
255 | value = toHex(value);
|
256 |
|
257 | if (value === "0x00") {
|
258 | return value;
|
259 | }
|
260 |
|
261 | return "-" + value;
|
262 | }
|
263 |
|
264 | if (value.substring(0, 2) !== "0x") {
|
265 | value = "0x" + value;
|
266 | }
|
267 |
|
268 | if (value === "0x") {
|
269 | return "0x00";
|
270 | }
|
271 |
|
272 | if (value.length % 2) {
|
273 | value = "0x0" + value.substring(2);
|
274 | }
|
275 |
|
276 | while (value.length > 4 && value.substring(0, 4) === "0x00") {
|
277 | value = "0x" + value.substring(4);
|
278 | }
|
279 | return value;
|
280 | }
|
281 | function toBigNumber(value) {
|
282 | return BigNumber.from(toHex(value));
|
283 | }
|
284 | function toBN(value) {
|
285 | const hex = BigNumber.from(value).toHexString();
|
286 | if (hex[0] === "-") {
|
287 | return (new BN("-" + hex.substring(3), 16));
|
288 | }
|
289 | return new BN(hex.substring(2), 16);
|
290 | }
|
291 | function throwFault(fault, operation, value) {
|
292 | const params = { fault: fault, operation: operation };
|
293 | if (value != null) {
|
294 | params.value = value;
|
295 | }
|
296 | return logger.throwError(fault, Logger.errors.NUMERIC_FAULT, params);
|
297 | }
|
298 |
|
299 | export function _base36To16(value) {
|
300 | return (new BN(value, 36)).toString(16);
|
301 | }
|
302 |
|
303 | export function _base16To36(value) {
|
304 | return (new BN(value, 16)).toString(36);
|
305 | }
|
306 |
|
\ | No newline at end of file |