@caict/bop-typescript-sdk 1.0.0
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/CHANGELOG.md +34 -0
- package/LICENSE +202 -0
- package/NOTICE +5 -0
- package/README.md +112 -0
- package/package.json +90 -0
- package/src/bop/bop-base/README.md +5 -0
- package/src/bop/bop-base/base.ts +366 -0
- package/src/bop/bop-base/index.ts +83 -0
- package/src/bop/bop-base/permit.ts +116 -0
- package/src/bop/bop-base/test/base.test.ts +867 -0
- package/src/bop/bop-base/test/index.test.ts +69 -0
- package/src/bop/bop-base/test/permit.test.ts +125 -0
- package/src/bop/bop-base/tsconfig.json +8 -0
- package/src/bop/bop-proto/README.md +2 -0
- package/src/bop/bop-proto/bop-ws.proto +266 -0
- package/src/bop/bop-proto/bop-ws.ts +4447 -0
- package/src/bop/bop-proto/bop.proto +898 -0
- package/src/bop/bop-proto/bop.ts +12890 -0
- package/src/bop/bop-proto/tsconfig.json +8 -0
- package/src/bop/bop-ws/index.ts +315 -0
- package/src/bop/bop-ws/sample/sample.ts +107 -0
- package/src/bop/bop-ws/tsconfig.json +8 -0
- package/src/bop/index.ts +14 -0
- package/src/bop-sdk/index.ts +22 -0
- package/src/bop-sdk/interface/abstract-service/abstract-account.ts +23 -0
- package/src/bop-sdk/interface/abstract-service/abstract-chain.ts +9 -0
- package/src/bop-sdk/interface/abstract-service/abstract-contract.ts +16 -0
- package/src/bop-sdk/interface/abstract-service/abstract-ledger.ts +15 -0
- package/src/bop-sdk/interface/abstract-service/abstract-provider.ts +13 -0
- package/src/bop-sdk/interface/abstract-service/abstract-signer.ts +133 -0
- package/src/bop-sdk/interface/abstract-service/abstract-transaction.ts +86 -0
- package/src/bop-sdk/interface/provider-ws.ts +10 -0
- package/src/bop-sdk/interface/provider.ts +22 -0
- package/src/bop-sdk/interface/service/3rd.ts +54 -0
- package/src/bop-sdk/interface/service/account.ts +86 -0
- package/src/bop-sdk/interface/service/chain.ts +27 -0
- package/src/bop-sdk/interface/service/contract.ts +51 -0
- package/src/bop-sdk/interface/service/helper.ts +426 -0
- package/src/bop-sdk/interface/service/ledger.ts +75 -0
- package/src/bop-sdk/interface/service/offline/check/index.js +138 -0
- package/src/bop-sdk/interface/service/offline/common/constant.js +6 -0
- package/src/bop-sdk/interface/service/offline/common/snowFlakeUtils.js +192 -0
- package/src/bop-sdk/interface/service/offline/common/util.js +511 -0
- package/src/bop-sdk/interface/service/offline/exception/customErrors.js +29 -0
- package/src/bop-sdk/interface/service/offline/exception/errors.js +90 -0
- package/src/bop-sdk/interface/service/offline/exception/index.js +5 -0
- package/src/bop-sdk/interface/service/offline/operation/accountCreateOperation.js +28 -0
- package/src/bop-sdk/interface/service/offline/operation/accountSetMetadataOperation.js +44 -0
- package/src/bop-sdk/interface/service/offline/operation/accountSetPrivilegeOperation.js +49 -0
- package/src/bop-sdk/interface/service/offline/operation/contractCreateOperation.js +43 -0
- package/src/bop-sdk/interface/service/offline/operation/contractInvokeOperation.js +42 -0
- package/src/bop-sdk/interface/service/offline/operation/contractInvokeRequestOperation.js +69 -0
- package/src/bop-sdk/interface/service/offline/operation/gasSendOperation.js +29 -0
- package/src/bop-sdk/interface/service/offline/operation/gasSendRequestOperation.js +61 -0
- package/src/bop-sdk/interface/service/offline/operation/index.js +20 -0
- package/src/bop-sdk/interface/service/offline/proto/chain_pb.js +12079 -0
- package/src/bop-sdk/interface/service/offline/proto/common_pb.js +2867 -0
- package/src/bop-sdk/interface/service/offline/transaction/index.js +988 -0
- package/src/bop-sdk/interface/service/offline/transaction/operations.js +188 -0
- package/src/bop-sdk/interface/service/offline/validate/account.js +152 -0
- package/src/bop-sdk/interface/service/offline/validate/contract.js +101 -0
- package/src/bop-sdk/interface/service/offline/validate/index.js +10 -0
- package/src/bop-sdk/interface/service/offline/validate/transaction.js +51 -0
- package/src/bop-sdk/interface/service/transaction.ts +731 -0
- package/src/bop-sdk/interface/signer.ts +46 -0
- package/src/bop-sdk/interface/test/3rd.test.ts +1571 -0
- package/src/bop-sdk/interface/test/account.test.ts +284 -0
- package/src/bop-sdk/interface/test/chain.test.ts +45 -0
- package/src/bop-sdk/interface/test/contract.test.ts +283 -0
- package/src/bop-sdk/interface/test/ledger.test.ts +166 -0
- package/src/bop-sdk/interface/test/provider.test.ts +407 -0
- package/src/bop-sdk/interface/test/signer.test.ts +105 -0
- package/src/bop-sdk/interface/test/transaction.test.ts +713 -0
- package/src/bop-sdk/proto/bop-sdk-common.proto +159 -0
- package/src/bop-sdk/proto/bop-sdk-common.ts +829 -0
- package/src/bop-sdk/proto/bop-sdk-interface.proto +581 -0
- package/src/bop-sdk/proto/bop-sdk-interface.ts +10839 -0
- package/src/bop-sdk/proto/bop-sdk-utils.proto +86 -0
- package/src/bop-sdk/proto/bop-sdk-utils.ts +1495 -0
- package/src/bop-sdk/utils/abi/abi-coder.ts +147 -0
- package/src/bop-sdk/utils/abi/address.ts +109 -0
- package/src/bop-sdk/utils/abi/bignumber.ts +403 -0
- package/src/bop-sdk/utils/abi/bytes.ts +565 -0
- package/src/bop-sdk/utils/abi/coders/abstract-coder.ts +239 -0
- package/src/bop-sdk/utils/abi/coders/address.ts +58 -0
- package/src/bop-sdk/utils/abi/coders/anonymous.ts +25 -0
- package/src/bop-sdk/utils/abi/coders/array.ts +275 -0
- package/src/bop-sdk/utils/abi/coders/boolean.ts +21 -0
- package/src/bop-sdk/utils/abi/coders/bytes.ts +36 -0
- package/src/bop-sdk/utils/abi/coders/fixed-bytes.ts +35 -0
- package/src/bop-sdk/utils/abi/coders/null.ts +25 -0
- package/src/bop-sdk/utils/abi/coders/number.ts +56 -0
- package/src/bop-sdk/utils/abi/coders/string.ts +24 -0
- package/src/bop-sdk/utils/abi/coders/tuple.ts +73 -0
- package/src/bop-sdk/utils/abi/constants/addresses.ts +1 -0
- package/src/bop-sdk/utils/abi/constants/bignumbers.ts +30 -0
- package/src/bop-sdk/utils/abi/constants/hashes.ts +2 -0
- package/src/bop-sdk/utils/abi/constants/index.ts +15 -0
- package/src/bop-sdk/utils/abi/constants/strings.ts +2 -0
- package/src/bop-sdk/utils/abi/fragments.ts +1243 -0
- package/src/bop-sdk/utils/abi/id.ts +6 -0
- package/src/bop-sdk/utils/abi/index.ts +46 -0
- package/src/bop-sdk/utils/abi/interface.ts +921 -0
- package/src/bop-sdk/utils/abi/keccak256.ts +9 -0
- package/src/bop-sdk/utils/abi/properties.ts +172 -0
- package/src/bop-sdk/utils/abi/strings/bytes32.ts +40 -0
- package/src/bop-sdk/utils/abi/strings/idna.ts +258 -0
- package/src/bop-sdk/utils/abi/strings/index.ts +28 -0
- package/src/bop-sdk/utils/abi/strings/utf8.ts +373 -0
- package/src/bop-sdk/utils/encryption-address.ts +501 -0
- package/src/bop-sdk/utils/encryption-crypto.ts +427 -0
- package/src/bop-sdk/utils/encryption-mnemonics.ts +120 -0
- package/src/bop-sdk/utils/index.ts +27 -0
- package/src/bop-sdk/utils/logger.ts +480 -0
- package/src/index.ts +35 -0
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
// See: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI
|
|
4
|
+
|
|
5
|
+
import { arrayify, BytesLike } from "./bytes";
|
|
6
|
+
import { defineReadOnly } from "./properties";
|
|
7
|
+
|
|
8
|
+
import { Logger } from "../logger";
|
|
9
|
+
const version = "abi-coder/5.7.0";
|
|
10
|
+
const logger = new Logger(version);
|
|
11
|
+
|
|
12
|
+
import { Coder, Reader, Result, Writer } from "./coders/abstract-coder";
|
|
13
|
+
import { AddressCoder } from "./coders/address";
|
|
14
|
+
import { ArrayCoder } from "./coders/array";
|
|
15
|
+
import { BooleanCoder } from "./coders/boolean";
|
|
16
|
+
import { BytesCoder } from "./coders/bytes";
|
|
17
|
+
import { FixedBytesCoder } from "./coders/fixed-bytes";
|
|
18
|
+
import { NullCoder } from "./coders/null";
|
|
19
|
+
import { NumberCoder } from "./coders/number";
|
|
20
|
+
import { StringCoder } from "./coders/string";
|
|
21
|
+
import { TupleCoder } from "./coders/tuple";
|
|
22
|
+
|
|
23
|
+
import { ParamType } from "./fragments";
|
|
24
|
+
|
|
25
|
+
const paramTypeBytes = new RegExp(/^bytes([0-9]*)$/);
|
|
26
|
+
const paramTypeNumber = new RegExp(/^(u?int)([0-9]*)$/);
|
|
27
|
+
|
|
28
|
+
export type CoerceFunc = (type: string, value: any) => any;
|
|
29
|
+
|
|
30
|
+
export class AbiCoder {
|
|
31
|
+
readonly coerceFunc: CoerceFunc;
|
|
32
|
+
|
|
33
|
+
constructor(coerceFunc?: CoerceFunc) {
|
|
34
|
+
defineReadOnly(this, "coerceFunc", coerceFunc || null);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
_getCoder(param: ParamType): Coder {
|
|
38
|
+
switch (param.baseType) {
|
|
39
|
+
case "address":
|
|
40
|
+
return new AddressCoder(param.name);
|
|
41
|
+
case "bool":
|
|
42
|
+
return new BooleanCoder(param.name);
|
|
43
|
+
case "string":
|
|
44
|
+
return new StringCoder(param.name);
|
|
45
|
+
case "bytes":
|
|
46
|
+
return new BytesCoder(param.name);
|
|
47
|
+
case "array":
|
|
48
|
+
return new ArrayCoder(
|
|
49
|
+
this._getCoder(param.arrayChildren),
|
|
50
|
+
param.arrayLength,
|
|
51
|
+
param.name,
|
|
52
|
+
);
|
|
53
|
+
case "tuple":
|
|
54
|
+
return new TupleCoder(
|
|
55
|
+
(param.components || []).map((component) => {
|
|
56
|
+
return this._getCoder(component);
|
|
57
|
+
}),
|
|
58
|
+
param.name,
|
|
59
|
+
);
|
|
60
|
+
case "":
|
|
61
|
+
return new NullCoder(param.name);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// u?int[0-9]*
|
|
65
|
+
let match = param.type.match(paramTypeNumber);
|
|
66
|
+
if (match) {
|
|
67
|
+
let size = parseInt(match[2] || "256");
|
|
68
|
+
if (size === 0 || size > 256 || size % 8 !== 0) {
|
|
69
|
+
logger.throwArgumentError(
|
|
70
|
+
"invalid " + match[1] + " bit length",
|
|
71
|
+
"param",
|
|
72
|
+
param,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
return new NumberCoder(size / 8, match[1] === "int", param.name);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// bytes[0-9]+
|
|
79
|
+
match = param.type.match(paramTypeBytes);
|
|
80
|
+
if (match) {
|
|
81
|
+
let size = parseInt(match[1]);
|
|
82
|
+
if (size === 0 || size > 32) {
|
|
83
|
+
logger.throwArgumentError("invalid bytes length", "param", param);
|
|
84
|
+
}
|
|
85
|
+
return new FixedBytesCoder(size, param.name);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return logger.throwArgumentError("invalid type", "type", param.type);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
_getWordSize(): number {
|
|
92
|
+
return 32;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
_getReader(data: Uint8Array, allowLoose?: boolean): Reader {
|
|
96
|
+
return new Reader(data, this._getWordSize(), this.coerceFunc, allowLoose);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
_getWriter(): Writer {
|
|
100
|
+
return new Writer(this._getWordSize());
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
getDefaultValue(types: ReadonlyArray<string | ParamType>): Result {
|
|
104
|
+
const coders: Array<Coder> = types.map((type) =>
|
|
105
|
+
this._getCoder(ParamType.from(type)),
|
|
106
|
+
);
|
|
107
|
+
const coder = new TupleCoder(coders, "_");
|
|
108
|
+
return coder.defaultValue();
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
encode(
|
|
112
|
+
types: ReadonlyArray<string | ParamType>,
|
|
113
|
+
values: ReadonlyArray<any>,
|
|
114
|
+
): string {
|
|
115
|
+
if (types.length !== values.length) {
|
|
116
|
+
logger.throwError(
|
|
117
|
+
"types/values length mismatch",
|
|
118
|
+
Logger.errors.INVALID_ARGUMENT,
|
|
119
|
+
{
|
|
120
|
+
count: { types: types.length, values: values.length },
|
|
121
|
+
value: { types: types, values: values },
|
|
122
|
+
},
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const coders = types.map((type) => this._getCoder(ParamType.from(type)));
|
|
127
|
+
const coder = new TupleCoder(coders, "_");
|
|
128
|
+
|
|
129
|
+
const writer = this._getWriter();
|
|
130
|
+
coder.encode(writer, values);
|
|
131
|
+
return writer.data;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
decode(
|
|
135
|
+
types: ReadonlyArray<string | ParamType>,
|
|
136
|
+
data: BytesLike,
|
|
137
|
+
loose?: boolean,
|
|
138
|
+
): Result {
|
|
139
|
+
const coders: Array<Coder> = types.map((type) =>
|
|
140
|
+
this._getCoder(ParamType.from(type)),
|
|
141
|
+
);
|
|
142
|
+
const coder = new TupleCoder(coders, "_");
|
|
143
|
+
return coder.decode(this._getReader(arrayify(data), loose));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export const defaultAbiCoder: AbiCoder = new AbiCoder();
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { BytesLike } from "./bytes";
|
|
4
|
+
import { BigNumberish } from "./bignumber";
|
|
5
|
+
|
|
6
|
+
import { Logger } from "../logger";
|
|
7
|
+
|
|
8
|
+
import * as cryptoJs from "crypto-js";
|
|
9
|
+
import * as bs58 from "@bifproject/bs58";
|
|
10
|
+
|
|
11
|
+
const version = "address/5.7.0";
|
|
12
|
+
const logger = new Logger(version);
|
|
13
|
+
|
|
14
|
+
function remove0xPrefix(str: string): string {
|
|
15
|
+
if (str.startsWith("0x")) {
|
|
16
|
+
return str.substring(2);
|
|
17
|
+
}
|
|
18
|
+
return str;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isHexadecimalString(str: string): boolean {
|
|
22
|
+
const hexRegex = /^[0-9a-fA-F]+$/;
|
|
23
|
+
return hexRegex.test(remove0xPrefix(str));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function startsWithDidBid(identifier: string): boolean {
|
|
27
|
+
const regex = /^(did:bid:ef|did:bid:zf)/;
|
|
28
|
+
return regex.test(identifier);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function hexAddressToDid(address: string): string {
|
|
32
|
+
if (startsWithDidBid(address)) {
|
|
33
|
+
return address;
|
|
34
|
+
} else {
|
|
35
|
+
if (!isHexadecimalString(address)) {
|
|
36
|
+
return "";
|
|
37
|
+
}
|
|
38
|
+
// 去除0x前缀(如果存在)
|
|
39
|
+
let addressWithout0x = remove0xPrefix(address);
|
|
40
|
+
// 截取前两个字节
|
|
41
|
+
const prefixBytes = addressWithout0x.slice(0, 4);
|
|
42
|
+
let prefix;
|
|
43
|
+
if (prefixBytes === "6566") {
|
|
44
|
+
prefix = "ef";
|
|
45
|
+
} else if (prefixBytes === "7a66") {
|
|
46
|
+
prefix = "zf";
|
|
47
|
+
} else {
|
|
48
|
+
return "";
|
|
49
|
+
}
|
|
50
|
+
// 对剩余数据进行Base58编码
|
|
51
|
+
const dataToEncode = addressWithout0x.slice(4);
|
|
52
|
+
const base58Encoded = bs58.encode(Buffer.from(dataToEncode, "hex"));
|
|
53
|
+
// 拼接并返回最终的地址字符串
|
|
54
|
+
const result = `did:bid:${prefix}${base58Encoded}`;
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function getAddress(address: string): string {
|
|
60
|
+
const ad = hexAddressToDid(address);
|
|
61
|
+
logger.debug(`getAddress before:${address}, after:${ad}`);
|
|
62
|
+
return ad;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function hexStringToByteArray(hexString: string): Array<number> {
|
|
66
|
+
if (hexString.length % 2 !== 0) {
|
|
67
|
+
throw new Error("Invalid hex string length");
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const byteArray: Array<number> = [];
|
|
71
|
+
for (let i = 0; i < hexString.length; i += 2) {
|
|
72
|
+
// 解析每两个十六进制字符为一个字节
|
|
73
|
+
const byteString = hexString.substr(i, 2);
|
|
74
|
+
const byte = parseInt(byteString, 16); // 将十六进制字符串解析为十进制整数
|
|
75
|
+
byteArray.push(byte);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return byteArray;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function getContractAddress(transaction: {
|
|
82
|
+
from: string;
|
|
83
|
+
nonce: BigNumberish;
|
|
84
|
+
}): string {
|
|
85
|
+
const srcAddress = transaction.from;
|
|
86
|
+
let raw = "";
|
|
87
|
+
raw += srcAddress;
|
|
88
|
+
raw += "-";
|
|
89
|
+
raw += Number(transaction.nonce).toString();
|
|
90
|
+
raw += "-";
|
|
91
|
+
raw += Number(0).toString();
|
|
92
|
+
raw += "-";
|
|
93
|
+
raw += Number(0).toString();
|
|
94
|
+
|
|
95
|
+
const sha256Hash = cryptoJs.SHA256(raw);
|
|
96
|
+
const hashStr = sha256Hash.toString(cryptoJs.enc.Hex);
|
|
97
|
+
const address = bs58.encode(hexStringToByteArray(hashStr).slice(10));
|
|
98
|
+
|
|
99
|
+
return `did:bid:ef${address}`;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function getCreate2Address(
|
|
103
|
+
from: string,
|
|
104
|
+
salt: BytesLike,
|
|
105
|
+
initCodeHash: BytesLike,
|
|
106
|
+
): string {
|
|
107
|
+
//not support
|
|
108
|
+
return "0x000000000000000000000000000000000000000000000000";
|
|
109
|
+
}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BigNumber
|
|
5
|
+
*
|
|
6
|
+
* A wrapper around the BN.js object. We use the BN.js library
|
|
7
|
+
* because it is used by elliptic, so it is required regardless.
|
|
8
|
+
*
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import _BN from "bn.js";
|
|
12
|
+
import BN = _BN.BN;
|
|
13
|
+
|
|
14
|
+
import { Bytes, Hexable, hexlify, isBytes, isHexString } from "./bytes";
|
|
15
|
+
|
|
16
|
+
import { Logger } from "../logger";
|
|
17
|
+
const version = "bignumber/5.7.0";
|
|
18
|
+
const logger = new Logger(version);
|
|
19
|
+
|
|
20
|
+
const _constructorGuard = {};
|
|
21
|
+
|
|
22
|
+
const MAX_SAFE = 0x1fffffffffffff;
|
|
23
|
+
|
|
24
|
+
export type BigNumberish = BigNumber | Bytes | bigint | string | number;
|
|
25
|
+
|
|
26
|
+
export function isBigNumberish(value: any): value is BigNumberish {
|
|
27
|
+
return (
|
|
28
|
+
value != null &&
|
|
29
|
+
(BigNumber.isBigNumber(value) ||
|
|
30
|
+
(typeof value === "number" && value % 1 === 0) ||
|
|
31
|
+
(typeof value === "string" && !!value.match(/^-?[0-9]+$/)) ||
|
|
32
|
+
isHexString(value) ||
|
|
33
|
+
typeof value === "bigint" ||
|
|
34
|
+
isBytes(value))
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Only warn about passing 10 into radix once
|
|
39
|
+
let _warnedToStringRadix = false;
|
|
40
|
+
|
|
41
|
+
export class BigNumber implements Hexable {
|
|
42
|
+
readonly _hex: string;
|
|
43
|
+
readonly _isBigNumber: boolean;
|
|
44
|
+
|
|
45
|
+
constructor(constructorGuard: any, hex: string) {
|
|
46
|
+
if (constructorGuard !== _constructorGuard) {
|
|
47
|
+
logger.throwError(
|
|
48
|
+
"cannot call constructor directly; use BigNumber.from",
|
|
49
|
+
Logger.errors.UNSUPPORTED_OPERATION,
|
|
50
|
+
{
|
|
51
|
+
operation: "new (BigNumber)",
|
|
52
|
+
},
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this._hex = hex;
|
|
57
|
+
this._isBigNumber = true;
|
|
58
|
+
|
|
59
|
+
Object.freeze(this);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
fromTwos(value: number): BigNumber {
|
|
63
|
+
return toBigNumber(toBN(this).fromTwos(value));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
toTwos(value: number): BigNumber {
|
|
67
|
+
return toBigNumber(toBN(this).toTwos(value));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
abs(): BigNumber {
|
|
71
|
+
if (this._hex[0] === "-") {
|
|
72
|
+
return BigNumber.from(this._hex.substring(1));
|
|
73
|
+
}
|
|
74
|
+
return this;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
add(other: BigNumberish): BigNumber {
|
|
78
|
+
return toBigNumber(toBN(this).add(toBN(other)));
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
sub(other: BigNumberish): BigNumber {
|
|
82
|
+
return toBigNumber(toBN(this).sub(toBN(other)));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
div(other: BigNumberish): BigNumber {
|
|
86
|
+
const o = BigNumber.from(other);
|
|
87
|
+
if (o.isZero()) {
|
|
88
|
+
throwFault("division-by-zero", "div");
|
|
89
|
+
}
|
|
90
|
+
return toBigNumber(toBN(this).div(toBN(other)));
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
mul(other: BigNumberish): BigNumber {
|
|
94
|
+
return toBigNumber(toBN(this).mul(toBN(other)));
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
mod(other: BigNumberish): BigNumber {
|
|
98
|
+
const value = toBN(other);
|
|
99
|
+
if (value.isNeg()) {
|
|
100
|
+
throwFault("division-by-zero", "mod");
|
|
101
|
+
}
|
|
102
|
+
return toBigNumber(toBN(this).umod(value));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
pow(other: BigNumberish): BigNumber {
|
|
106
|
+
const value = toBN(other);
|
|
107
|
+
if (value.isNeg()) {
|
|
108
|
+
throwFault("negative-power", "pow");
|
|
109
|
+
}
|
|
110
|
+
return toBigNumber(toBN(this).pow(value));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
and(other: BigNumberish): BigNumber {
|
|
114
|
+
const value = toBN(other);
|
|
115
|
+
if (this.isNegative() || value.isNeg()) {
|
|
116
|
+
throwFault("unbound-bitwise-result", "and");
|
|
117
|
+
}
|
|
118
|
+
return toBigNumber(toBN(this).and(value));
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
or(other: BigNumberish): BigNumber {
|
|
122
|
+
const value = toBN(other);
|
|
123
|
+
if (this.isNegative() || value.isNeg()) {
|
|
124
|
+
throwFault("unbound-bitwise-result", "or");
|
|
125
|
+
}
|
|
126
|
+
return toBigNumber(toBN(this).or(value));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
xor(other: BigNumberish): BigNumber {
|
|
130
|
+
const value = toBN(other);
|
|
131
|
+
if (this.isNegative() || value.isNeg()) {
|
|
132
|
+
throwFault("unbound-bitwise-result", "xor");
|
|
133
|
+
}
|
|
134
|
+
return toBigNumber(toBN(this).xor(value));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
mask(value: number): BigNumber {
|
|
138
|
+
if (this.isNegative() || value < 0) {
|
|
139
|
+
throwFault("negative-width", "mask");
|
|
140
|
+
}
|
|
141
|
+
return toBigNumber(toBN(this).maskn(value));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
shl(value: number): BigNumber {
|
|
145
|
+
if (this.isNegative() || value < 0) {
|
|
146
|
+
throwFault("negative-width", "shl");
|
|
147
|
+
}
|
|
148
|
+
return toBigNumber(toBN(this).shln(value));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
shr(value: number): BigNumber {
|
|
152
|
+
if (this.isNegative() || value < 0) {
|
|
153
|
+
throwFault("negative-width", "shr");
|
|
154
|
+
}
|
|
155
|
+
return toBigNumber(toBN(this).shrn(value));
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
eq(other: BigNumberish): boolean {
|
|
159
|
+
return toBN(this).eq(toBN(other));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
lt(other: BigNumberish): boolean {
|
|
163
|
+
return toBN(this).lt(toBN(other));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
lte(other: BigNumberish): boolean {
|
|
167
|
+
return toBN(this).lte(toBN(other));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
gt(other: BigNumberish): boolean {
|
|
171
|
+
return toBN(this).gt(toBN(other));
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
gte(other: BigNumberish): boolean {
|
|
175
|
+
return toBN(this).gte(toBN(other));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
isNegative(): boolean {
|
|
179
|
+
return this._hex[0] === "-";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
isZero(): boolean {
|
|
183
|
+
return toBN(this).isZero();
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
toNumber(): number {
|
|
187
|
+
try {
|
|
188
|
+
return toBN(this).toNumber();
|
|
189
|
+
} catch (error) {
|
|
190
|
+
throwFault("overflow", "toNumber", this.toString());
|
|
191
|
+
}
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
toBigInt(): bigint {
|
|
196
|
+
try {
|
|
197
|
+
return BigInt(this.toString());
|
|
198
|
+
} catch (e) {}
|
|
199
|
+
|
|
200
|
+
return logger.throwError(
|
|
201
|
+
"this platform does not support BigInt",
|
|
202
|
+
Logger.errors.UNSUPPORTED_OPERATION,
|
|
203
|
+
{
|
|
204
|
+
value: this.toString(),
|
|
205
|
+
},
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
toString(): string {
|
|
210
|
+
// Lots of people expect this, which we do not support, so check (See: #889)
|
|
211
|
+
if (arguments.length > 0) {
|
|
212
|
+
if (arguments[0] === 10) {
|
|
213
|
+
if (!_warnedToStringRadix) {
|
|
214
|
+
_warnedToStringRadix = true;
|
|
215
|
+
logger.warn(
|
|
216
|
+
"BigNumber.toString does not accept any parameters; base-10 is assumed",
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
} else if (arguments[0] === 16) {
|
|
220
|
+
logger.throwError(
|
|
221
|
+
"BigNumber.toString does not accept any parameters; use bigNumber.toHexString()",
|
|
222
|
+
Logger.errors.UNEXPECTED_ARGUMENT,
|
|
223
|
+
{},
|
|
224
|
+
);
|
|
225
|
+
} else {
|
|
226
|
+
logger.throwError(
|
|
227
|
+
"BigNumber.toString does not accept parameters",
|
|
228
|
+
Logger.errors.UNEXPECTED_ARGUMENT,
|
|
229
|
+
{},
|
|
230
|
+
);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
return toBN(this).toString(10);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
toHexString(): string {
|
|
237
|
+
return this._hex;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
toJSON(key?: string): any {
|
|
241
|
+
return { type: "BigNumber", hex: this.toHexString() };
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static from(value: any): BigNumber {
|
|
245
|
+
if (value instanceof BigNumber) {
|
|
246
|
+
return value;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if (typeof value === "string") {
|
|
250
|
+
if (value.match(/^-?0x[0-9a-f]+$/i)) {
|
|
251
|
+
return new BigNumber(_constructorGuard, toHex(value));
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if (value.match(/^-?[0-9]+$/)) {
|
|
255
|
+
return new BigNumber(_constructorGuard, toHex(new BN(value)));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
return logger.throwArgumentError(
|
|
259
|
+
"invalid BigNumber string",
|
|
260
|
+
"value",
|
|
261
|
+
value,
|
|
262
|
+
);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (typeof value === "number") {
|
|
266
|
+
if (value % 1) {
|
|
267
|
+
throwFault("underflow", "BigNumber.from", value);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (value >= MAX_SAFE || value <= -MAX_SAFE) {
|
|
271
|
+
throwFault("overflow", "BigNumber.from", value);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return BigNumber.from(String(value));
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const anyValue = <any>value;
|
|
278
|
+
|
|
279
|
+
if (typeof anyValue === "bigint") {
|
|
280
|
+
return BigNumber.from(anyValue.toString());
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
if (isBytes(anyValue)) {
|
|
284
|
+
return BigNumber.from(hexlify(anyValue));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
if (anyValue) {
|
|
288
|
+
// Hexable interface (takes priority)
|
|
289
|
+
if (anyValue.toHexString) {
|
|
290
|
+
const hex = anyValue.toHexString();
|
|
291
|
+
if (typeof hex === "string") {
|
|
292
|
+
return BigNumber.from(hex);
|
|
293
|
+
}
|
|
294
|
+
} else {
|
|
295
|
+
// For now, handle legacy JSON-ified values (goes away in v6)
|
|
296
|
+
let hex = anyValue._hex;
|
|
297
|
+
|
|
298
|
+
// New-form JSON
|
|
299
|
+
if (hex == null && anyValue.type === "BigNumber") {
|
|
300
|
+
hex = anyValue.hex;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (typeof hex === "string") {
|
|
304
|
+
if (
|
|
305
|
+
isHexString(hex) ||
|
|
306
|
+
(hex[0] === "-" && isHexString(hex.substring(1)))
|
|
307
|
+
) {
|
|
308
|
+
return BigNumber.from(hex);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
return logger.throwArgumentError("invalid BigNumber value", "value", value);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
static isBigNumber(value: any): value is BigNumber {
|
|
318
|
+
return !!(value && value._isBigNumber);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Normalize the hex string
|
|
323
|
+
function toHex(value: string | BN): string {
|
|
324
|
+
// For BN, call on the hex string
|
|
325
|
+
if (typeof value !== "string") {
|
|
326
|
+
return toHex(value.toString(16));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
// If negative, prepend the negative sign to the normalized positive value
|
|
330
|
+
if (value[0] === "-") {
|
|
331
|
+
// Strip off the negative sign
|
|
332
|
+
value = value.substring(1);
|
|
333
|
+
|
|
334
|
+
// Cannot have multiple negative signs (e.g. "--0x04")
|
|
335
|
+
if (value[0] === "-") {
|
|
336
|
+
logger.throwArgumentError("invalid hex", "value", value);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// Call toHex on the positive component
|
|
340
|
+
value = toHex(value);
|
|
341
|
+
|
|
342
|
+
// Do not allow "-0x00"
|
|
343
|
+
if (value === "0x00") {
|
|
344
|
+
return value;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Negate the value
|
|
348
|
+
return "-" + value;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Add a "0x" prefix if missing
|
|
352
|
+
if (value.substring(0, 2) !== "0x") {
|
|
353
|
+
value = "0x" + value;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Normalize zero
|
|
357
|
+
if (value === "0x") {
|
|
358
|
+
return "0x00";
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Make the string even length
|
|
362
|
+
if (value.length % 2) {
|
|
363
|
+
value = "0x0" + value.substring(2);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Trim to smallest even-length string
|
|
367
|
+
while (value.length > 4 && value.substring(0, 4) === "0x00") {
|
|
368
|
+
value = "0x" + value.substring(4);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return value;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
function toBigNumber(value: BN): BigNumber {
|
|
375
|
+
return BigNumber.from(toHex(value));
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
function toBN(value: BigNumberish): BN {
|
|
379
|
+
const hex = BigNumber.from(value).toHexString();
|
|
380
|
+
if (hex[0] === "-") {
|
|
381
|
+
return new BN("-" + hex.substring(3), 16);
|
|
382
|
+
}
|
|
383
|
+
return new BN(hex.substring(2), 16);
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function throwFault(fault: string, operation: string, value?: any): never {
|
|
387
|
+
const params: any = { fault: fault, operation: operation };
|
|
388
|
+
if (value != null) {
|
|
389
|
+
params.value = value;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
return logger.throwError(fault, Logger.errors.NUMERIC_FAULT, params);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// value should have no prefix
|
|
396
|
+
export function _base36To16(value: string): string {
|
|
397
|
+
return new BN(value, 36).toString(16);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// value should have no prefix
|
|
401
|
+
export function _base16To36(value: string): string {
|
|
402
|
+
return new BN(value, 16).toString(36);
|
|
403
|
+
}
|