@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.
Files changed (115) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +5 -0
  4. package/README.md +112 -0
  5. package/package.json +90 -0
  6. package/src/bop/bop-base/README.md +5 -0
  7. package/src/bop/bop-base/base.ts +366 -0
  8. package/src/bop/bop-base/index.ts +83 -0
  9. package/src/bop/bop-base/permit.ts +116 -0
  10. package/src/bop/bop-base/test/base.test.ts +867 -0
  11. package/src/bop/bop-base/test/index.test.ts +69 -0
  12. package/src/bop/bop-base/test/permit.test.ts +125 -0
  13. package/src/bop/bop-base/tsconfig.json +8 -0
  14. package/src/bop/bop-proto/README.md +2 -0
  15. package/src/bop/bop-proto/bop-ws.proto +266 -0
  16. package/src/bop/bop-proto/bop-ws.ts +4447 -0
  17. package/src/bop/bop-proto/bop.proto +898 -0
  18. package/src/bop/bop-proto/bop.ts +12890 -0
  19. package/src/bop/bop-proto/tsconfig.json +8 -0
  20. package/src/bop/bop-ws/index.ts +315 -0
  21. package/src/bop/bop-ws/sample/sample.ts +107 -0
  22. package/src/bop/bop-ws/tsconfig.json +8 -0
  23. package/src/bop/index.ts +14 -0
  24. package/src/bop-sdk/index.ts +22 -0
  25. package/src/bop-sdk/interface/abstract-service/abstract-account.ts +23 -0
  26. package/src/bop-sdk/interface/abstract-service/abstract-chain.ts +9 -0
  27. package/src/bop-sdk/interface/abstract-service/abstract-contract.ts +16 -0
  28. package/src/bop-sdk/interface/abstract-service/abstract-ledger.ts +15 -0
  29. package/src/bop-sdk/interface/abstract-service/abstract-provider.ts +13 -0
  30. package/src/bop-sdk/interface/abstract-service/abstract-signer.ts +133 -0
  31. package/src/bop-sdk/interface/abstract-service/abstract-transaction.ts +86 -0
  32. package/src/bop-sdk/interface/provider-ws.ts +10 -0
  33. package/src/bop-sdk/interface/provider.ts +22 -0
  34. package/src/bop-sdk/interface/service/3rd.ts +54 -0
  35. package/src/bop-sdk/interface/service/account.ts +86 -0
  36. package/src/bop-sdk/interface/service/chain.ts +27 -0
  37. package/src/bop-sdk/interface/service/contract.ts +51 -0
  38. package/src/bop-sdk/interface/service/helper.ts +426 -0
  39. package/src/bop-sdk/interface/service/ledger.ts +75 -0
  40. package/src/bop-sdk/interface/service/offline/check/index.js +138 -0
  41. package/src/bop-sdk/interface/service/offline/common/constant.js +6 -0
  42. package/src/bop-sdk/interface/service/offline/common/snowFlakeUtils.js +192 -0
  43. package/src/bop-sdk/interface/service/offline/common/util.js +511 -0
  44. package/src/bop-sdk/interface/service/offline/exception/customErrors.js +29 -0
  45. package/src/bop-sdk/interface/service/offline/exception/errors.js +90 -0
  46. package/src/bop-sdk/interface/service/offline/exception/index.js +5 -0
  47. package/src/bop-sdk/interface/service/offline/operation/accountCreateOperation.js +28 -0
  48. package/src/bop-sdk/interface/service/offline/operation/accountSetMetadataOperation.js +44 -0
  49. package/src/bop-sdk/interface/service/offline/operation/accountSetPrivilegeOperation.js +49 -0
  50. package/src/bop-sdk/interface/service/offline/operation/contractCreateOperation.js +43 -0
  51. package/src/bop-sdk/interface/service/offline/operation/contractInvokeOperation.js +42 -0
  52. package/src/bop-sdk/interface/service/offline/operation/contractInvokeRequestOperation.js +69 -0
  53. package/src/bop-sdk/interface/service/offline/operation/gasSendOperation.js +29 -0
  54. package/src/bop-sdk/interface/service/offline/operation/gasSendRequestOperation.js +61 -0
  55. package/src/bop-sdk/interface/service/offline/operation/index.js +20 -0
  56. package/src/bop-sdk/interface/service/offline/proto/chain_pb.js +12079 -0
  57. package/src/bop-sdk/interface/service/offline/proto/common_pb.js +2867 -0
  58. package/src/bop-sdk/interface/service/offline/transaction/index.js +988 -0
  59. package/src/bop-sdk/interface/service/offline/transaction/operations.js +188 -0
  60. package/src/bop-sdk/interface/service/offline/validate/account.js +152 -0
  61. package/src/bop-sdk/interface/service/offline/validate/contract.js +101 -0
  62. package/src/bop-sdk/interface/service/offline/validate/index.js +10 -0
  63. package/src/bop-sdk/interface/service/offline/validate/transaction.js +51 -0
  64. package/src/bop-sdk/interface/service/transaction.ts +731 -0
  65. package/src/bop-sdk/interface/signer.ts +46 -0
  66. package/src/bop-sdk/interface/test/3rd.test.ts +1571 -0
  67. package/src/bop-sdk/interface/test/account.test.ts +284 -0
  68. package/src/bop-sdk/interface/test/chain.test.ts +45 -0
  69. package/src/bop-sdk/interface/test/contract.test.ts +283 -0
  70. package/src/bop-sdk/interface/test/ledger.test.ts +166 -0
  71. package/src/bop-sdk/interface/test/provider.test.ts +407 -0
  72. package/src/bop-sdk/interface/test/signer.test.ts +105 -0
  73. package/src/bop-sdk/interface/test/transaction.test.ts +713 -0
  74. package/src/bop-sdk/proto/bop-sdk-common.proto +159 -0
  75. package/src/bop-sdk/proto/bop-sdk-common.ts +829 -0
  76. package/src/bop-sdk/proto/bop-sdk-interface.proto +581 -0
  77. package/src/bop-sdk/proto/bop-sdk-interface.ts +10839 -0
  78. package/src/bop-sdk/proto/bop-sdk-utils.proto +86 -0
  79. package/src/bop-sdk/proto/bop-sdk-utils.ts +1495 -0
  80. package/src/bop-sdk/utils/abi/abi-coder.ts +147 -0
  81. package/src/bop-sdk/utils/abi/address.ts +109 -0
  82. package/src/bop-sdk/utils/abi/bignumber.ts +403 -0
  83. package/src/bop-sdk/utils/abi/bytes.ts +565 -0
  84. package/src/bop-sdk/utils/abi/coders/abstract-coder.ts +239 -0
  85. package/src/bop-sdk/utils/abi/coders/address.ts +58 -0
  86. package/src/bop-sdk/utils/abi/coders/anonymous.ts +25 -0
  87. package/src/bop-sdk/utils/abi/coders/array.ts +275 -0
  88. package/src/bop-sdk/utils/abi/coders/boolean.ts +21 -0
  89. package/src/bop-sdk/utils/abi/coders/bytes.ts +36 -0
  90. package/src/bop-sdk/utils/abi/coders/fixed-bytes.ts +35 -0
  91. package/src/bop-sdk/utils/abi/coders/null.ts +25 -0
  92. package/src/bop-sdk/utils/abi/coders/number.ts +56 -0
  93. package/src/bop-sdk/utils/abi/coders/string.ts +24 -0
  94. package/src/bop-sdk/utils/abi/coders/tuple.ts +73 -0
  95. package/src/bop-sdk/utils/abi/constants/addresses.ts +1 -0
  96. package/src/bop-sdk/utils/abi/constants/bignumbers.ts +30 -0
  97. package/src/bop-sdk/utils/abi/constants/hashes.ts +2 -0
  98. package/src/bop-sdk/utils/abi/constants/index.ts +15 -0
  99. package/src/bop-sdk/utils/abi/constants/strings.ts +2 -0
  100. package/src/bop-sdk/utils/abi/fragments.ts +1243 -0
  101. package/src/bop-sdk/utils/abi/id.ts +6 -0
  102. package/src/bop-sdk/utils/abi/index.ts +46 -0
  103. package/src/bop-sdk/utils/abi/interface.ts +921 -0
  104. package/src/bop-sdk/utils/abi/keccak256.ts +9 -0
  105. package/src/bop-sdk/utils/abi/properties.ts +172 -0
  106. package/src/bop-sdk/utils/abi/strings/bytes32.ts +40 -0
  107. package/src/bop-sdk/utils/abi/strings/idna.ts +258 -0
  108. package/src/bop-sdk/utils/abi/strings/index.ts +28 -0
  109. package/src/bop-sdk/utils/abi/strings/utf8.ts +373 -0
  110. package/src/bop-sdk/utils/encryption-address.ts +501 -0
  111. package/src/bop-sdk/utils/encryption-crypto.ts +427 -0
  112. package/src/bop-sdk/utils/encryption-mnemonics.ts +120 -0
  113. package/src/bop-sdk/utils/index.ts +27 -0
  114. package/src/bop-sdk/utils/logger.ts +480 -0
  115. package/src/index.ts +35 -0
@@ -0,0 +1,192 @@
1
+ /**
2
+ *
3
+ * 名词说明:
4
+ * Twitter_Snowflake
5
+ * SnowFlake的结构如下(每部分用-分开):
6
+ *
7
+ * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000
8
+ * A-|--------------------B--------------------------|-------C-------|------D------|
9
+ *
10
+ * A区:1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0
11
+ * B区:41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)得到的值,
12
+ * 这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,
13
+ * 年T = (1n << 41n) / (1000n * 60n * 60n * 24n * 365n) = 69n
14
+ * C区:10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId(2^5 * 2^5 = 1024)
15
+ * D区:12位序列,毫秒内的计数,12位 的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号(2^12=4096)
16
+ * 加起来刚好64位,为一个Long型。
17
+ *
18
+ * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据ID和机器ID作区分),并且效率较高。
19
+ * 理论1S内生成的ID数量是 1000*4096 = 4096000(四百零九万六千个)
20
+ * 代码中使用Bigint实现,该类型在Node10.X版本才开始支持,返回出去的结果是Bigint转为String后的字符串类型,toString方法消耗总性能的三分之一时间;
21
+ * 性能测试结果:
22
+ * 生成100W条ID, 约850-1000ms; 如果不toString后再转, 时间约 640-660ms
23
+ * 生成409.6WW条ID, 约3600-3850ms; 如果不toString后再转, 时间约约 2600-2800ms
24
+ */
25
+
26
+ // ==============================Constructors=====================================
27
+ /**
28
+ * 构造函数
29
+ * @param workerId 工作ID (0~31)
30
+ * @param datacenterId 数据标识ID (0~31)
31
+ */
32
+ let Snowflake = (function () {
33
+ function Snowflake(_workerId, _dataCenterId) {
34
+ /** 开始时间截 :2019-12-20 13:52:35 */
35
+ this.twepoch = 1576821155667;
36
+
37
+ /** 机器id所占的位数 */
38
+ this.workerIdBits = 5;
39
+
40
+ /** 数据标识id所占的位数 */
41
+ this.dataCenterIdBits = 5;
42
+
43
+ // this.maxWrokerId = -1 ^ (-1 << this.workerIdBits) // 值为:31
44
+
45
+ /** 支持的最大数据标识id,结果是31 */
46
+ // this.maxDataCenterId = -1 ^ (-1 << this.dataCenterIdBits) // 值为:31
47
+
48
+ /** 序列在id中占的位数 */
49
+ this.sequenceBits = 12;
50
+
51
+ /** 机器ID向左移12位 */
52
+ this.workerIdShift = this.sequenceBits; // 值为:12
53
+
54
+ /** 数据标识id向左移17位(12序列id+5机器ID) */
55
+ this.dataCenterIdShift = this.sequenceBits + this.workerIdBits; // 值为:17
56
+
57
+ /** 时间截向左移22位( 12序列id + 5机器ID + 5数据ID) */
58
+ this.timestampLeftShift =
59
+ this.sequenceBits + this.workerIdBits + this.dataCenterIdBits; // 值为:22
60
+ // this.timestampLeftShift = this.sequenceBits + this.workerIdBits + this.dataCenterIdBits + 10; // 32
61
+ this.sequenceMask = -1 ^ (-1 << this.sequenceBits); //4095
62
+ /** 上次生成ID的时间截 */
63
+ this.lastTimestamp = -1;
64
+
65
+ this.workerId = _workerId || 0; // 工作机器ID(0~31)
66
+
67
+ this.dataCenterId = _dataCenterId || 0; // 数据标识ID(0~31)
68
+ this.sequence = 0; // 毫秒内序列(0~4095)
69
+
70
+ // workerId 校验
71
+ if (this.workerId > ~(-1 << this.workerIdBits) || this.workerId < 0) {
72
+ throw new Error(
73
+ `workerId must be greater than 0 and less than ${~(-1 << this.workerIdBits)}`,
74
+ );
75
+ }
76
+ // dataCenterId 校验
77
+ if (
78
+ this.dataCenterId > ~(-1 << this.dataCenterIdBits) ||
79
+ this.dataCenterId < 0
80
+ ) {
81
+ throw new Error(
82
+ `dataCenterId must be greater than 0 and less than ${~(-1 << this.dataCenterIdBits)}`,
83
+ );
84
+ }
85
+ }
86
+ // ==============================Methods==========================================
87
+ /**
88
+ * 获得下一个ID (该方法是线程安全的)
89
+ * @return SnowflakeId
90
+ */
91
+ Snowflake.prototype.nextId = function () {
92
+ let timestamp = this.timeGen(); // 获取当前时间戳
93
+
94
+ // 如果当前时间小于上一次ID生成的时间戳,抛出异常
95
+ if (timestamp < this.lastTimestamp) {
96
+ throw new Error(
97
+ `Clock moved backwards. Refusing to generate id for ${
98
+ this.lastTimestamp - timestamp
99
+ }`,
100
+ );
101
+ }
102
+
103
+ // 如果是同一时间生成的,则进行毫秒内序列
104
+ if (this.lastTimestamp === timestamp) {
105
+ // 增加序列号,并应用位掩码以确保其在允许的范围内
106
+ this.sequence = (this.sequence + 1) & this.sequenceMask;
107
+
108
+ // 毫秒内序列溢出
109
+ if (this.sequence === 0) {
110
+ // 阻塞到下一个毫秒,获得新的时间戳
111
+ timestamp = this.tilNextMillis(this.lastTimestamp);
112
+ }
113
+ } else {
114
+ // 时间戳改变,毫秒内序列重置
115
+ this.sequence = 0;
116
+ }
117
+
118
+ // 上次生成ID的时间截
119
+ this.lastTimestamp = timestamp;
120
+
121
+ // 用除法和加法替代位移操作
122
+ let timestampPart =
123
+ (timestamp - this.twepoch) * Math.pow(2, this.timestampLeftShift);
124
+ let dataCenterIdPart =
125
+ this.dataCenterId * Math.pow(2, this.dataCenterIdShift);
126
+ let workerIdPart = this.workerId * Math.pow(2, this.workerIdShift);
127
+ let result =
128
+ timestampPart + dataCenterIdPart + workerIdPart + this.sequence; // 如果 result 超过 JavaScript Number 的最大安全整数,返回一个字符串,避免精度丢失
129
+ return result > Number.MAX_SAFE_INTEGER ? result.toString() : result;
130
+ };
131
+
132
+ Snowflake.randomLenNum = function () {
133
+ return singleSnowFlake.nextId();
134
+ };
135
+
136
+ Snowflake.getIPAdress = function () {
137
+ let interfaces = require("os").networkInterfaces();
138
+ for (let devName in interfaces) {
139
+ let iface = interfaces[devName];
140
+ for (let i = 0; i < iface.length; i++) {
141
+ let alias = iface[i];
142
+ if (
143
+ alias.family === "IPv4" &&
144
+ alias.address !== "127.0.0.1" &&
145
+ !alias.internal
146
+ ) {
147
+ console.log(alias.address);
148
+ return alias.address;
149
+ }
150
+ }
151
+ }
152
+ };
153
+
154
+ Snowflake.getHostName = function () {
155
+ let os = require("os");
156
+ console.log(os.hostname());
157
+ return os.hostname();
158
+ };
159
+
160
+ Snowflake.getRangeRandom = function (m, n) {
161
+ return Math.ceil(Math.random() * (n - m + 1) + m - 1);
162
+ };
163
+ Snowflake.getDefaultRangeRandom = function () {
164
+ return this.getRangeRandom(100, 2000);
165
+ };
166
+
167
+ /**
168
+ * 阻塞到下一个毫秒,直到获得新的时间戳
169
+ * @param lastTimestamp 上次生成ID的时间截
170
+ * @return 当前时间戳
171
+ */
172
+ Snowflake.prototype.tilNextMillis = function (lastTimestamp) {
173
+ let timestamp = this.timeGen();
174
+ while (timestamp <= lastTimestamp) {
175
+ timestamp = this.timeGen();
176
+ }
177
+ return timestamp;
178
+ };
179
+
180
+ /**
181
+ * 返回以毫秒为单位的当前时间
182
+ * @return 当前时间(毫秒)
183
+ */
184
+ Snowflake.prototype.timeGen = function () {
185
+ return Date.now();
186
+ };
187
+
188
+ return Snowflake;
189
+ })();
190
+ // console.log(new Snowflake(1n, 1n).nextId())
191
+ var singleSnowFlake = new Snowflake(1, 1);
192
+ module.exports = Snowflake;
@@ -0,0 +1,511 @@
1
+ const is = require("is-type-of");
2
+ const long = require("long");
3
+ const JSONbig = require("json-bigint");
4
+ const BigNumber = require("bignumber.js");
5
+ const keypair = require("@caict/bif-encryption");
6
+ const proto = exports;
7
+ // 星火令 单位转换
8
+ proto.gasToUGas = function (gas) {
9
+ if (!_isAvailableGas(gas)) {
10
+ throw new Error("invalid gas value");
11
+ }
12
+
13
+ const oneUGas = Math.pow(10, 8);
14
+ const uGas = new BigNumber(gas).times(oneUGas);
15
+ return uGas.toString();
16
+ };
17
+ proto.uGasToGas = function (uGas) {
18
+ if (!_isAvailableUGas(uGas)) {
19
+ throw new Error("invalid uGas value");
20
+ }
21
+ const oneUGas = Math.pow(10, 8);
22
+ const gas = new BigNumber(uGas).dividedBy(oneUGas);
23
+ return handleData(gas.toString());
24
+ };
25
+
26
+ const handleData = function (value) {
27
+ const e = String(value);
28
+ let rex = /^([0-9])\.?([0-9]*)e-([0-9])/;
29
+ if (!rex.test(e)) {
30
+ return value;
31
+ }
32
+ const numArr = e.match(rex);
33
+ const n = Number(`${numArr[1]}${numArr[2] || ""}`);
34
+ const num = `0.${String(Math.pow(10, Number(numArr[3]) - 1)).substr(1)}${n}`;
35
+ return num.replace(/0*$/, "");
36
+ };
37
+
38
+ function _isAvailableUGas(value) {
39
+ const reg = /^(0|([1-9]\d*))$/;
40
+ return (
41
+ typeof value === "string" &&
42
+ reg.test(value) &&
43
+ long.fromValue(value).greaterThanOrEqual(0) &&
44
+ long.fromValue(value).lessThanOrEqual(long.MAX_VALUE)
45
+ );
46
+ }
47
+
48
+ function _isAvailableGas(value) {
49
+ const reg = /^(([1-9]\d*)+|0)(\.\d{1,8})?$/;
50
+ return (
51
+ typeof value === "string" &&
52
+ reg.test(value) &&
53
+ long.fromValue(value).greaterThanOrEqual(0) &&
54
+ long
55
+ .fromValue(value)
56
+ .lessThanOrEqual(long.MAX_VALUE.divide(Math.pow(10, 8)))
57
+ );
58
+ }
59
+
60
+ proto._response = function (obj) {
61
+ const data = {
62
+ errorCode: obj.error_code || 0,
63
+ errorDesc: obj.error_desc || "Success",
64
+ };
65
+
66
+ if (is.object(obj) && obj.error_code) {
67
+ if (obj.error_code === 0) {
68
+ data.result = obj.result || {};
69
+ } else {
70
+ data.errorDesc = obj.error_desc || "";
71
+ data.result = {};
72
+ }
73
+ } else if (is.object(obj) && obj.errorCode) {
74
+ data.errorCode = obj.errorCode;
75
+ if (obj.errorCode === 0) {
76
+ data.result = obj.result || {};
77
+ } else {
78
+ data.errorDesc = obj.errorDesc || "";
79
+ data.result = {};
80
+ }
81
+ } else {
82
+ data.result = obj;
83
+ }
84
+
85
+ return data;
86
+ };
87
+
88
+ proto._isEmptyString = function (str) {
89
+ if (!is.string(str)) {
90
+ throw new Error("str must be a string");
91
+ }
92
+ return str.trim().length === 0;
93
+ };
94
+
95
+ proto._postData = function (blob, signature) {
96
+ const data = {
97
+ items: [
98
+ {
99
+ transaction_blob: blob,
100
+ signatures: signature,
101
+ },
102
+ ],
103
+ };
104
+ return JSONbig.stringify(data);
105
+ };
106
+
107
+ proto._isBigNumber = function (object) {
108
+ return (
109
+ object instanceof BigNumber ||
110
+ (object && object.constructor && object.constructor.name === "BigNumber")
111
+ );
112
+ };
113
+
114
+ proto._toBigNumber = function (number) {
115
+ number = number || 0;
116
+ //
117
+ if (this._isBigNumber(number)) {
118
+ return number;
119
+ }
120
+ return new BigNumber(number);
121
+ };
122
+
123
+ proto._stringFromBigNumber = function (number) {
124
+ return this._toBigNumber(number).toString(10);
125
+ };
126
+
127
+ proto._verifyValue = function (str) {
128
+ const reg = /^[0-9]\d*$/;
129
+ return (
130
+ is.string(str) &&
131
+ reg.test(str) &&
132
+ long.fromValue(str).greaterThan(0) &&
133
+ long.fromValue(str).lessThanOrEqual(long.MAX_VALUE)
134
+ );
135
+ };
136
+ proto._verifyIInitBalancelValue = function (str) {
137
+ const reg = /^[0-9]\d*$/;
138
+ return (
139
+ is.string(str) &&
140
+ reg.test(str) &&
141
+ long.fromValue(str).greaterThanOrEqual(0) &&
142
+ long.fromValue(str).lessThanOrEqual(long.MAX_VALUE)
143
+ );
144
+ };
145
+
146
+ proto._isAvailableValue = function (str, from = -1, to = long.MAX_VALUE) {
147
+ const reg = /^(0|([1-9]\d*))$/;
148
+ return (
149
+ is.string(str) &&
150
+ reg.test(str) &&
151
+ long.fromValue(str).greaterThan(from) &&
152
+ long.fromValue(str).lessThanOrEqual(to)
153
+ );
154
+ };
155
+
156
+ proto._responseData = function (data) {
157
+ const errorCode = 0;
158
+ const errorDesc = "Success";
159
+
160
+ return {
161
+ errorCode,
162
+ errorDesc,
163
+ result: data,
164
+ };
165
+ };
166
+
167
+ proto._responseError = function (message) {
168
+ if (!message) {
169
+ throw new Error("require message");
170
+ }
171
+ const errorCode = message.CODE;
172
+
173
+ return {
174
+ errorCode,
175
+ errorDesc: message.MSG,
176
+ };
177
+ };
178
+
179
+ proto._isHexString = function (str) {
180
+ if (str === "" || !is.string(str)) {
181
+ return false;
182
+ }
183
+ const hexString = Buffer.from(str, "hex").toString("hex");
184
+ return hexString === str;
185
+ };
186
+
187
+ proto._isString = function (str) {
188
+ if (!is.string(str) || str.trim().length === 0) {
189
+ return false;
190
+ }
191
+ return true;
192
+ };
193
+
194
+ proto._isOperation = function (arr) {
195
+ let tag = true;
196
+ if (!is.array(arr) || arr.length === 0) {
197
+ tag = false;
198
+ return tag;
199
+ }
200
+
201
+ arr.some((item) => {
202
+ if (!is.object(item)) {
203
+ tag = false;
204
+ return true;
205
+ }
206
+ if (!item.type || !item.data) {
207
+ tag = false;
208
+ return true;
209
+ }
210
+ });
211
+
212
+ return tag;
213
+ };
214
+
215
+ /**
216
+ *
217
+ * @param obj
218
+ * @param schema
219
+ * @returns {boolean}
220
+ * @private
221
+ *
222
+ * eg:
223
+ schema: {
224
+ required: false,
225
+ string: true,
226
+ address: true,
227
+ numeric: true,
228
+ }
229
+ */
230
+ proto._validate = function (obj, schema) {
231
+ let tag = true;
232
+ let msg = "";
233
+
234
+ if (!is.object(obj) || !is.object(schema)) {
235
+ tag = false;
236
+ msg = "INVALID_NUMBER_OF_ARG";
237
+ return {
238
+ tag,
239
+ msg,
240
+ };
241
+ }
242
+
243
+ Object.keys(schema).some((item) => {
244
+ // required is true
245
+ if (schema[item].required && is.undefined(obj[item])) {
246
+ obj[item] = "";
247
+ }
248
+
249
+ // numeric is true
250
+ if (
251
+ !is.undefined(obj[item]) &&
252
+ schema[item].numeric &&
253
+ !this._isAvailableValue(obj[item])
254
+ ) {
255
+ tag = false;
256
+
257
+ switch (item) {
258
+ case "amount":
259
+ msg = "INVALID_AMOUNT_ERROR";
260
+ break;
261
+ case "gasPrice":
262
+ msg = "INVALID_GASPRICE_ERROR";
263
+ break;
264
+ case "feeLimit":
265
+ msg = "INVALID_FEELIMIT_ERROR";
266
+ break;
267
+ case "ceilLedgerSeq":
268
+ msg = "INVALID_CEILLEDGERSEQ_ERROR";
269
+ break;
270
+ case "nonce":
271
+ msg = "INVALID_NONCE_ERROR";
272
+ break;
273
+ case "initBalance":
274
+ msg = "INVALID_INITBALANCE_ERROR";
275
+ break;
276
+ default:
277
+ msg = "REQUEST_NULL_ERROR";
278
+ }
279
+
280
+ return true;
281
+ }
282
+
283
+ // address is true
284
+ if (
285
+ !is.undefined(obj[item]) &&
286
+ schema[item].address &&
287
+ !keypair.isAddress(obj[item])
288
+ ) {
289
+ tag = false;
290
+
291
+ switch (item) {
292
+ case "sourceAddress":
293
+ msg = "INVALID_SOURCEADDRESS_ERROR";
294
+ break;
295
+ case "destAddress":
296
+ msg = "INVALID_DESTADDRESS_ERROR";
297
+ break;
298
+ case "address":
299
+ msg = "INVALID_ADDRESS_ERROR";
300
+ break;
301
+ case "contractAddress":
302
+ msg = "INVALID_CONTRACTADDRESS_ERROR";
303
+ break;
304
+ case "fromAddress":
305
+ msg = "INVALID_FROMADDRESS_ERROR";
306
+ break;
307
+ default:
308
+ msg = "INVALID_ARGUMENTS";
309
+ }
310
+
311
+ return true;
312
+ }
313
+
314
+ // hex is true
315
+ if (
316
+ !is.undefined(obj[item]) &&
317
+ schema[item].hex &&
318
+ !this._isHexString(obj[item])
319
+ ) {
320
+ tag = false;
321
+
322
+ switch (item) {
323
+ case "metadata":
324
+ msg = "METADATA_NOT_HEX_STRING_ERROR";
325
+ break;
326
+ default:
327
+ msg = "METADATA_NOT_HEX_STRING_ERROR";
328
+ }
329
+
330
+ return true;
331
+ }
332
+
333
+ // string is true
334
+ if (
335
+ !is.undefined(obj[item]) &&
336
+ schema[item].string &&
337
+ !this._isString(obj[item])
338
+ ) {
339
+ tag = false;
340
+
341
+ switch (item) {
342
+ case "payload":
343
+ msg = "PAYLOAD_EMPTY_ERROR";
344
+ break;
345
+ case "key":
346
+ msg = "INVALID_DATAKEY_ERROR";
347
+ break;
348
+ case "value":
349
+ msg = "INVALID_DATAVALUE_ERROR";
350
+ break;
351
+ default:
352
+ msg = "INVALID_ARGUMENTS";
353
+ }
354
+
355
+ return true;
356
+ }
357
+ });
358
+
359
+ return {
360
+ tag,
361
+ msg,
362
+ };
363
+ };
364
+
365
+ proto._bufToHex = function (buf) {
366
+ const utf8Str = buf.toString("utf8");
367
+ return Buffer.from(utf8Str, "utf8").toString("hex");
368
+ };
369
+
370
+ proto._isSignature = function (arr) {
371
+ let tag = true;
372
+ if (!is.array(arr) || arr.length === 0) {
373
+ tag = false;
374
+ return tag;
375
+ }
376
+
377
+ arr.some((item) => {
378
+ if (!is.object(item)) {
379
+ tag = false;
380
+ return true;
381
+ }
382
+
383
+ if (!item.signData || !item.publicKey) {
384
+ tag = false;
385
+ return true;
386
+ }
387
+
388
+ if (!this._isHexString(item.signData)) {
389
+ tag = false;
390
+ return true;
391
+ }
392
+
393
+ if (!keypair.isPublicKey(item.publicKey)) {
394
+ tag = false;
395
+ return true;
396
+ }
397
+ });
398
+
399
+ return tag;
400
+ };
401
+ proto._bigNumberToString = function (obj, base) {
402
+ // setup base
403
+ base = base || 10;
404
+
405
+ // check if obj is type object, not an array and does not have BN properties
406
+ if (
407
+ typeof obj === "object" &&
408
+ obj !== null &&
409
+ !Array.isArray(obj) &&
410
+ !("lessThan" in obj)
411
+ ) {
412
+ // move through plain object
413
+ Object.keys(obj).forEach((key) => {
414
+ // recurively converty item
415
+ obj[key] = proto._bigNumberToString(obj[key], base);
416
+ });
417
+ }
418
+
419
+ // obj is an array
420
+ if (Array.isArray(obj)) {
421
+ // convert items in array
422
+ obj = obj.map((item) => {
423
+ // convert item to a string if bignumber
424
+ return proto._bigNumberToString(item, base);
425
+ });
426
+ }
427
+
428
+ // if obj is number, convert to string
429
+ if (typeof obj === "number") {
430
+ return `${obj}`;
431
+ }
432
+
433
+ // if not an object bypass
434
+ if (typeof obj !== "object" || obj === null) {
435
+ return obj;
436
+ }
437
+
438
+ // if the object to does not have BigNumber properties, bypass
439
+ if (!("toString" in obj) || !("lessThan" in obj)) {
440
+ return obj;
441
+ }
442
+
443
+ // if object has bignumber properties, convert to string with base
444
+ return obj.toString(base);
445
+ };
446
+
447
+ proto._longToInt = function (obj) {
448
+ // check if obj is type object, not an array and does not have long properties
449
+ if (
450
+ typeof obj === "object" &&
451
+ obj !== null &&
452
+ !Array.isArray(obj) &&
453
+ !("low" in obj)
454
+ ) {
455
+ // move through plain object
456
+ Object.keys(obj).forEach((key) => {
457
+ // recurively converty item
458
+ obj[key] = proto._longToInt(obj[key]);
459
+ });
460
+ }
461
+
462
+ // obj is an array
463
+ if (Array.isArray(obj)) {
464
+ // convert items in array
465
+ obj = obj.map((item) => {
466
+ // convert item to an int if long
467
+ return proto._longToInt(item);
468
+ });
469
+ }
470
+
471
+ // if not an object bypass
472
+ if (typeof obj !== "object" || obj === null) {
473
+ return obj;
474
+ }
475
+
476
+ // if the object to does not have long properties, bypass
477
+ if (!("low" in obj)) {
478
+ return obj;
479
+ }
480
+
481
+ // if object has long properties, convert to int
482
+ return long.fromValue(obj).toNumber();
483
+ };
484
+
485
+ proto._isAvailableVersion = function (str) {
486
+ const reg = /^\d+(\.\d+)?$/;
487
+ return (
488
+ is.string(str) &&
489
+ reg.test(str) &&
490
+ long.fromValue(str).greaterThanOrEqual(0) &&
491
+ long.fromValue(str).lessThanOrEqual(long.MAX_VALUE)
492
+ );
493
+ };
494
+
495
+ proto._isAvailableBu = function (str) {
496
+ const reg = /^(([1-9]\d*)+|0)(\.\d{1,8})?$/;
497
+ return (
498
+ is.string(str) &&
499
+ reg.test(str) &&
500
+ long.fromValue(str).greaterThanOrEqual(0) &&
501
+ long.fromValue(str).lessThanOrEqual(long.MAX_VALUE.divide(Math.pow(10, 8)))
502
+ );
503
+ };
504
+ proto._containsInvalidUnicodeCharacters = function (str) {
505
+ try {
506
+ const encoded = encodeURIComponent(str);
507
+ return encoded.length !== str.length;
508
+ } catch (e) {
509
+ return true;
510
+ }
511
+ };