quantumcoin 7.0.11 → 7.0.12
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 +16 -0
- package/README.md +13 -0
- package/examples/node_modules/.package-lock.json +18 -109
- package/examples/node_modules/get-tsconfig/dist/index.cjs +4 -4
- package/examples/node_modules/get-tsconfig/dist/index.mjs +7 -7
- package/examples/node_modules/get-tsconfig/package.json +1 -1
- package/examples/node_modules/quantum-coin-js-sdk/README.md +113 -103
- package/examples/node_modules/quantum-coin-js-sdk/example/example.js +2 -2
- package/examples/node_modules/quantum-coin-js-sdk/example/package-lock.json +1 -1
- package/examples/node_modules/quantum-coin-js-sdk/index.d.ts +1031 -1024
- package/examples/node_modules/quantum-coin-js-sdk/index.js +169 -87
- package/examples/node_modules/quantum-coin-js-sdk/package.json +1 -1
- package/examples/node_modules/quantum-coin-js-sdk/tests/non-transactional.test.js +705 -2
- package/examples/node_modules/quantum-coin-js-sdk/wasmBase64.js +2 -2
- package/examples/package-lock.json +1 -1
- package/generate-sdk.js +1 -1
- package/package.json +1 -1
- package/src/wallet/wallet.d.ts +5 -0
- package/src/wallet/wallet.js +20 -0
- package/test/unit/address-wallet.test.js +141 -0
- package/test/unit/address-wallet.test.ts +141 -0
- package/SPEC.md +0 -3784
- package/examples/node_modules/quantum-coin-js-sdk/.github/workflows/publish-npmjs.yaml +0 -22
|
@@ -56,6 +56,7 @@ const BASE_SEED_BYTES_HYBRIDEDMLDSASLHDSA = 64;
|
|
|
56
56
|
const MIN_PASSPHRASE_LENGTH = 12;
|
|
57
57
|
const INVALID_KEY_TYPE = -1001;
|
|
58
58
|
const CIRCL_CRYPTO_FAILURE = -1002;
|
|
59
|
+
const EXPECTED_WASM_SHA256 = "bcab6389db37af9cc6538fb54a872f416131392d3ad5ea23a0969d8aac3b1c85";
|
|
59
60
|
|
|
60
61
|
/**
|
|
61
62
|
* @class
|
|
@@ -122,9 +123,10 @@ class Wallet {
|
|
|
122
123
|
* Creates a Wallet class. The constructor does not verify the wallet. To verify a wallet, call the verifyWallet function explicitly.
|
|
123
124
|
* @param {string} address - Address of the wallet
|
|
124
125
|
* @param {number[]} privateKey - Private Key byte array of the wallet
|
|
125
|
-
* @param {number[]} publicKey -
|
|
126
|
+
* @param {number[]} publicKey - Public Key byte array of the wallet
|
|
127
|
+
* @param {Uint8Array|number[]|null} [preExpansionSeed=null] - Optional pre-expansion seed bytes. Non-null only for seed-derived wallets.
|
|
126
128
|
*/
|
|
127
|
-
constructor(address, privateKey, publicKey) {
|
|
129
|
+
constructor(address, privateKey, publicKey, preExpansionSeed) {
|
|
128
130
|
|
|
129
131
|
/**
|
|
130
132
|
* Address of the wallet. Is 66 bytes in length including 0x (if the wallet is valid).
|
|
@@ -146,6 +148,13 @@ class Wallet {
|
|
|
146
148
|
* @public
|
|
147
149
|
*/
|
|
148
150
|
this.publicKey = publicKey;
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Pre-expansion seed bytes. Can be null if the wallet was not created from a seed.
|
|
154
|
+
* @type {Uint8Array|number[]|null}
|
|
155
|
+
* @public
|
|
156
|
+
*/
|
|
157
|
+
this.preExpansionSeed = preExpansionSeed || null;
|
|
149
158
|
}
|
|
150
159
|
}
|
|
151
160
|
|
|
@@ -841,6 +850,10 @@ function isLargeNumber(val) {
|
|
|
841
850
|
return false;
|
|
842
851
|
}
|
|
843
852
|
|
|
853
|
+
function getGlobalObject() {
|
|
854
|
+
return (typeof globalThis !== 'undefined' ? globalThis : typeof global !== 'undefined' ? global : typeof window !== 'undefined' ? window : this);
|
|
855
|
+
}
|
|
856
|
+
|
|
844
857
|
async function InitAccountsWebAssembly() {
|
|
845
858
|
const go = new global.Go();
|
|
846
859
|
let mod, inst;
|
|
@@ -851,14 +864,75 @@ async function InitAccountsWebAssembly() {
|
|
|
851
864
|
throw new Error("Error parsing base64");
|
|
852
865
|
}
|
|
853
866
|
const wasmBytes = Uint8Array.from(atob(base64wasm), c => c.charCodeAt(0));
|
|
867
|
+
|
|
868
|
+
const hashHex = crypto.createHash('sha256').update(wasmBytes).digest('hex');
|
|
869
|
+
if (hashHex !== EXPECTED_WASM_SHA256) {
|
|
870
|
+
throw new Error("WASM integrity check failed");
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
const g = getGlobalObject();
|
|
874
|
+
if (g) {
|
|
875
|
+
delete g.circl;
|
|
876
|
+
}
|
|
877
|
+
|
|
854
878
|
let result = await WebAssembly.instantiate(wasmBytes, go.importObject);
|
|
855
879
|
mod = result.module;
|
|
856
880
|
inst = result.instance;
|
|
857
881
|
go.run(inst);
|
|
858
|
-
|
|
882
|
+
|
|
859
883
|
if (g && g.circl) {
|
|
860
884
|
circl = g.circl;
|
|
885
|
+
delete g.circl;
|
|
886
|
+
if (circl.hybridedmldsaslhdsa) Object.freeze(circl.hybridedmldsaslhdsa);
|
|
887
|
+
if (circl.hybridedmldsaslhdsa5) Object.freeze(circl.hybridedmldsaslhdsa5);
|
|
888
|
+
if (circl.hybridedmldsaslhds5) Object.freeze(circl.hybridedmldsaslhds5);
|
|
889
|
+
if (circl.hybrideds) Object.freeze(circl.hybrideds);
|
|
890
|
+
Object.freeze(circl);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
function validateCryptoRandom() {
|
|
895
|
+
if (!circl || !circl.cryptoRandom) {
|
|
896
|
+
return false;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const sampleSize = 64;
|
|
900
|
+
const res1 = circl.cryptoRandom(sampleSize);
|
|
901
|
+
const res2 = circl.cryptoRandom(sampleSize);
|
|
902
|
+
|
|
903
|
+
if (!res1 || res1.error || !res1.result || res1.result.length !== sampleSize) {
|
|
904
|
+
return false;
|
|
905
|
+
}
|
|
906
|
+
if (!res2 || res2.error || !res2.result || res2.result.length !== sampleSize) {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
const a = res1.result instanceof Uint8Array ? res1.result : new Uint8Array(res1.result);
|
|
911
|
+
const b = res2.result instanceof Uint8Array ? res2.result : new Uint8Array(res2.result);
|
|
912
|
+
|
|
913
|
+
let identical = true;
|
|
914
|
+
for (let i = 0; i < sampleSize; i++) {
|
|
915
|
+
if (a[i] !== b[i]) { identical = false; break; }
|
|
916
|
+
}
|
|
917
|
+
if (identical) {
|
|
918
|
+
return false;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
let aAllZero = true, bAllZero = true;
|
|
922
|
+
for (let i = 0; i < sampleSize; i++) {
|
|
923
|
+
if (a[i] !== 0) aAllZero = false;
|
|
924
|
+
if (b[i] !== 0) bAllZero = false;
|
|
925
|
+
}
|
|
926
|
+
if (aAllZero || bAllZero) {
|
|
927
|
+
return false;
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
const seen = new Set(a);
|
|
931
|
+
if (seen.size < 48) {
|
|
932
|
+
return false;
|
|
861
933
|
}
|
|
934
|
+
|
|
935
|
+
return true;
|
|
862
936
|
}
|
|
863
937
|
|
|
864
938
|
/**
|
|
@@ -879,7 +953,10 @@ async function initialize(clientConfig) {
|
|
|
879
953
|
if (clientConfig.readUrl === null || clientConfig.writeUrl === null || clientConfig.chainId === null) {
|
|
880
954
|
return false;
|
|
881
955
|
}
|
|
882
|
-
await InitAccountsWebAssembly();
|
|
956
|
+
await InitAccountsWebAssembly();
|
|
957
|
+
if (!validateCryptoRandom()) {
|
|
958
|
+
throw new Error("CSPRNG validation failed");
|
|
959
|
+
}
|
|
883
960
|
config = clientConfig;
|
|
884
961
|
isInitialized = await seedwords.initialize();
|
|
885
962
|
|
|
@@ -1004,13 +1081,13 @@ function newWallet(keyType) {
|
|
|
1004
1081
|
}
|
|
1005
1082
|
|
|
1006
1083
|
/**
|
|
1007
|
-
* The
|
|
1084
|
+
* The newWalletSeedWords function creates a new wallet seed word list. The returned array can then be passed to the openWalletFromSeedWords function to create a new wallet.
|
|
1008
1085
|
*
|
|
1009
|
-
* @function
|
|
1086
|
+
* @function newWalletSeedWords
|
|
1010
1087
|
* @param {number|null} keyType - Optional. KEY_TYPE_HYBRIDEDMLDSASLHDSA (3) or KEY_TYPE_HYBRIDEDMLDSASLHDSA5 (5). null/undefined defaults to 3.
|
|
1011
|
-
* @return {
|
|
1088
|
+
* @return {string[]|number|null} Returns an array of seed words (32 or 36 words depending on keyType). Returns -1000 if not initialized, null on failure.
|
|
1012
1089
|
*/
|
|
1013
|
-
function
|
|
1090
|
+
function newWalletSeedWords(keyType) {
|
|
1014
1091
|
if (isInitialized === false) {
|
|
1015
1092
|
return -1000;
|
|
1016
1093
|
}
|
|
@@ -1046,7 +1123,7 @@ function newWalletSeed(keyType) {
|
|
|
1046
1123
|
*
|
|
1047
1124
|
* @function openWalletFromSeed
|
|
1048
1125
|
* @param {Array<number>|Uint8Array} seedArray - The raw seed bytes. Length 96, 72, or 64 depending on scheme.
|
|
1049
|
-
* @return {Wallet|number} Returns a Wallet object. Returns -1000 if not initialized, null if the operation failed.
|
|
1126
|
+
* @return {Wallet|number|null} Returns a Wallet object. Returns -1000 if not initialized, null if the operation failed.
|
|
1050
1127
|
*/
|
|
1051
1128
|
function openWalletFromSeed(seedArray) {
|
|
1052
1129
|
if (isInitialized === false) {
|
|
@@ -1092,7 +1169,7 @@ function openWalletFromSeed(seedArray) {
|
|
|
1092
1169
|
const publicKey = keyPairRes.result.publicKey instanceof Uint8Array ? Array.from(keyPairRes.result.publicKey) : keyPairRes.result.publicKey;
|
|
1093
1170
|
const privateKey = keyPairRes.result.privateKey instanceof Uint8Array ? Array.from(keyPairRes.result.privateKey) : keyPairRes.result.privateKey;
|
|
1094
1171
|
const address = PublicKeyToAddress(publicKey);
|
|
1095
|
-
return new Wallet(address, privateKey, publicKey);
|
|
1172
|
+
return new Wallet(address, privateKey, publicKey, seedU8);
|
|
1096
1173
|
}
|
|
1097
1174
|
|
|
1098
1175
|
/**
|
|
@@ -1100,8 +1177,8 @@ function openWalletFromSeed(seedArray) {
|
|
|
1100
1177
|
* Supports 48 words (hybrideds), 36 words (hybrid5), or 32 words (hybrid) per seed length.
|
|
1101
1178
|
*
|
|
1102
1179
|
* @function openWalletFromSeedWords
|
|
1103
|
-
* @param {
|
|
1104
|
-
* @return {Wallet|number} Returns a Wallet object. Returns -1000 if not initialized, null if the operation failed.
|
|
1180
|
+
* @param {string[]} seedWordList - An array of seed words. Length 48, 36, or 32 depending on scheme.
|
|
1181
|
+
* @return {Wallet|number|null} Returns a Wallet object. Returns -1000 if not initialized, null if the operation failed.
|
|
1105
1182
|
*/
|
|
1106
1183
|
function openWalletFromSeedWords(seedWordList) {
|
|
1107
1184
|
if (isInitialized === false) {
|
|
@@ -1115,7 +1192,7 @@ function openWalletFromSeedWords(seedWordList) {
|
|
|
1115
1192
|
return null;
|
|
1116
1193
|
}
|
|
1117
1194
|
const seedArray = seedwords.getSeedArrayFromWordList(seedWordList);
|
|
1118
|
-
if (seedArray == null || seedArray.length
|
|
1195
|
+
if (seedArray == null || seedArray.length === undefined) {
|
|
1119
1196
|
return null;
|
|
1120
1197
|
}
|
|
1121
1198
|
return openWalletFromSeed(seedArray);
|
|
@@ -1131,26 +1208,22 @@ function openWalletFromSeedWords(seedWordList) {
|
|
|
1131
1208
|
*/
|
|
1132
1209
|
function deserializeEncryptedWallet(walletJsonString, passphrase) {
|
|
1133
1210
|
if (isInitialized === false) {
|
|
1134
|
-
console.error('deserializeEncryptedWallet: SDK not initialized');
|
|
1135
1211
|
return -1000;
|
|
1136
1212
|
}
|
|
1137
1213
|
|
|
1138
1214
|
if (walletJsonString == null || passphrase == null) {
|
|
1139
|
-
console.error('deserializeEncryptedWallet: walletJsonString or passphrase is null');
|
|
1140
1215
|
return null;
|
|
1141
1216
|
}
|
|
1142
1217
|
|
|
1143
1218
|
if (typeof walletJsonString === 'string' || walletJsonString instanceof String) {
|
|
1144
1219
|
|
|
1145
1220
|
} else {
|
|
1146
|
-
console.error('deserializeEncryptedWallet: walletJsonString is not a string');
|
|
1147
1221
|
return null;
|
|
1148
1222
|
}
|
|
1149
1223
|
|
|
1150
1224
|
if (typeof passphrase === 'string' || passphrase instanceof String) {
|
|
1151
1225
|
|
|
1152
1226
|
} else {
|
|
1153
|
-
console.error('deserializeEncryptedWallet: passphrase is not a string');
|
|
1154
1227
|
return null;
|
|
1155
1228
|
}
|
|
1156
1229
|
|
|
@@ -1158,54 +1231,50 @@ function deserializeEncryptedWallet(walletJsonString, passphrase) {
|
|
|
1158
1231
|
try {
|
|
1159
1232
|
walletJsonObj = JSON.parse(walletJsonString);
|
|
1160
1233
|
} catch (e) {
|
|
1161
|
-
console.error('deserializeEncryptedWallet: JSON parse failed', e.message);
|
|
1162
1234
|
return null;
|
|
1163
1235
|
}
|
|
1164
1236
|
|
|
1165
1237
|
if (walletJsonObj == null) {
|
|
1166
|
-
console.error('deserializeEncryptedWallet: parsed JSON is null');
|
|
1167
1238
|
return null;
|
|
1168
1239
|
}
|
|
1169
1240
|
|
|
1170
1241
|
if (walletJsonObj.address == null) {
|
|
1171
|
-
console.error('deserializeEncryptedWallet: wallet JSON missing address');
|
|
1172
1242
|
return null;
|
|
1173
1243
|
}
|
|
1174
1244
|
|
|
1175
1245
|
let keyPairString = JsonToWalletKeyPair(walletJsonString, passphrase);
|
|
1176
1246
|
if (keyPairString == null) {
|
|
1177
|
-
console.error('deserializeEncryptedWallet: failed to derive key pair (wrong passphrase or invalid crypto)');
|
|
1178
1247
|
return null;
|
|
1179
1248
|
}
|
|
1180
1249
|
|
|
1181
1250
|
let keyPairSplit = keyPairString.split(",");
|
|
1182
1251
|
if (keyPairSplit.length < 2) {
|
|
1183
|
-
console.error('deserializeEncryptedWallet: key pair format invalid');
|
|
1184
1252
|
return null;
|
|
1185
1253
|
}
|
|
1186
1254
|
|
|
1187
1255
|
let privateKeyArray = base64ToBytes(keyPairSplit[0]);
|
|
1188
1256
|
let publicKeyArray = base64ToBytes(keyPairSplit[1]);
|
|
1257
|
+
let preExpansionSeed = null;
|
|
1258
|
+
if (keyPairSplit.length >= 3 && keyPairSplit[2].length > 0) {
|
|
1259
|
+
preExpansionSeed = base64ToBytes(keyPairSplit[2]);
|
|
1260
|
+
}
|
|
1189
1261
|
let address = PublicKeyToAddress(publicKeyArray);
|
|
1190
1262
|
if (address == null) {
|
|
1191
|
-
console.error('deserializeEncryptedWallet: failed to derive address from public key');
|
|
1192
1263
|
return null;
|
|
1193
1264
|
}
|
|
1194
1265
|
|
|
1195
1266
|
if (typeof address === 'string' || address instanceof String) {
|
|
1196
1267
|
|
|
1197
1268
|
} else {
|
|
1198
|
-
console.error('deserializeEncryptedWallet: address is not a string');
|
|
1199
1269
|
return null;
|
|
1200
1270
|
}
|
|
1201
1271
|
|
|
1202
1272
|
let addressCheck = "0x" + walletJsonObj.address.toLowerCase();
|
|
1203
|
-
if (addressCheck
|
|
1204
|
-
console.error('deserializeEncryptedWallet: address mismatch with wallet JSON');
|
|
1273
|
+
if (addressCheck !== address.toLowerCase()) {
|
|
1205
1274
|
return null;
|
|
1206
1275
|
}
|
|
1207
1276
|
|
|
1208
|
-
let wallet = new Wallet(address, privateKeyArray, publicKeyArray);
|
|
1277
|
+
let wallet = new Wallet(address, privateKeyArray, publicKeyArray, preExpansionSeed);
|
|
1209
1278
|
|
|
1210
1279
|
return wallet;
|
|
1211
1280
|
}
|
|
@@ -1237,11 +1306,21 @@ function serializeEncryptedWallet(wallet, passphrase) {
|
|
|
1237
1306
|
return null;
|
|
1238
1307
|
}
|
|
1239
1308
|
|
|
1240
|
-
let walletJsonString
|
|
1309
|
+
let walletJsonString;
|
|
1310
|
+
if (wallet.preExpansionSeed != null && wallet.preExpansionSeed.length > 0) {
|
|
1311
|
+
const seedU8 = wallet.preExpansionSeed instanceof Uint8Array ? wallet.preExpansionSeed : new Uint8Array(wallet.preExpansionSeed);
|
|
1312
|
+
const result = EncryptPreExpansionSeed(seedU8, passphrase);
|
|
1313
|
+
if (result == null || result instanceof Error) {
|
|
1314
|
+
return null;
|
|
1315
|
+
}
|
|
1316
|
+
walletJsonString = result;
|
|
1317
|
+
} else {
|
|
1318
|
+
walletJsonString = KeyPairToWalletJson(wallet.privateKey, wallet.publicKey, passphrase);
|
|
1319
|
+
}
|
|
1241
1320
|
|
|
1242
1321
|
let walletJson = JSON.parse(walletJsonString);
|
|
1243
1322
|
let addressCheck = "0x" + walletJson.address;
|
|
1244
|
-
if (addressCheck.toLowerCase()
|
|
1323
|
+
if (addressCheck.toLowerCase() !== wallet.address.toLowerCase()) {
|
|
1245
1324
|
return null;
|
|
1246
1325
|
}
|
|
1247
1326
|
|
|
@@ -1319,43 +1398,34 @@ function isByteArray(array) {
|
|
|
1319
1398
|
*/
|
|
1320
1399
|
function verifyWallet(wallet) {
|
|
1321
1400
|
if (isInitialized === false) {
|
|
1322
|
-
console.log('[verifyWallet] FAIL: not initialized');
|
|
1323
1401
|
return -1000;
|
|
1324
1402
|
}
|
|
1325
1403
|
if (wallet === null || wallet.address === null || wallet.privateKey === null || wallet.publicKey === null) {
|
|
1326
|
-
console.log('[verifyWallet] FAIL: wallet or wallet.address/privateKey/publicKey is null');
|
|
1327
1404
|
return false;
|
|
1328
1405
|
}
|
|
1329
1406
|
if (isAddressValid(wallet.address) === false) {
|
|
1330
|
-
console.log('[verifyWallet] FAIL: isAddressValid(wallet.address) === false');
|
|
1331
1407
|
return false;
|
|
1332
1408
|
}
|
|
1333
1409
|
if (isByteArray(wallet.privateKey) === false) {
|
|
1334
|
-
console.log('[verifyWallet] FAIL: isByteArray(wallet.privateKey) === false');
|
|
1335
1410
|
return false;
|
|
1336
1411
|
}
|
|
1337
1412
|
if (isByteArray(wallet.publicKey) === false) {
|
|
1338
|
-
console.log('[verifyWallet] FAIL: isByteArray(wallet.publicKey) === false');
|
|
1339
1413
|
return false;
|
|
1340
1414
|
}
|
|
1341
1415
|
const keyType = getKeyTypeFromPrivateKey(wallet.privateKey);
|
|
1342
1416
|
if (keyType == null) {
|
|
1343
|
-
console.log('[verifyWallet] FAIL: getKeyTypeFromPrivateKey returned null (privateKey.length=' + wallet.privateKey.length + ', circl.hybridedmldsaslhdsa.PrivateKeySize=' + (circl && circl.hybridedmldsaslhdsa ? circl.hybridedmldsaslhdsa.PrivateKeySize : 'N/A') + ', hybrid5.PrivateKeySize=' + (circl && (circl.hybridedmldsaslhdsa5 || circl.hybridedmldsaslhds5) ? (circl.hybridedmldsaslhdsa5 || circl.hybridedmldsaslhds5).PrivateKeySize : 'N/A') + ')');
|
|
1344
1417
|
return false;
|
|
1345
1418
|
}
|
|
1346
1419
|
const hybridNs = circl && circl.hybridedmldsaslhdsa;
|
|
1347
1420
|
const hybrid5Ns = circl && (circl.hybridedmldsaslhdsa5 || circl.hybridedmldsaslhds5);
|
|
1348
1421
|
if (keyType === KEY_TYPE_HYBRIDEDMLDSASLHDSA && hybridNs && wallet.privateKey.length !== hybridNs.PrivateKeySize) {
|
|
1349
|
-
console.log('[verifyWallet] FAIL: keyType 3 but privateKey.length !== hybridNs.PrivateKeySize');
|
|
1350
1422
|
return false;
|
|
1351
1423
|
}
|
|
1352
1424
|
if (keyType === KEY_TYPE_HYBRIDEDMLDSASLHDSA5 && hybrid5Ns && wallet.privateKey.length !== hybrid5Ns.PrivateKeySize) {
|
|
1353
|
-
console.log('[verifyWallet] FAIL: keyType 5 but privateKey.length !== hybrid5Ns.PrivateKeySize');
|
|
1354
1425
|
return false;
|
|
1355
1426
|
}
|
|
1356
1427
|
const address = PublicKeyToAddress(wallet.publicKey);
|
|
1357
1428
|
if (address !== wallet.address) {
|
|
1358
|
-
console.log('[verifyWallet] FAIL: PublicKeyToAddress(wallet.publicKey) !== wallet.address');
|
|
1359
1429
|
return false;
|
|
1360
1430
|
}
|
|
1361
1431
|
const message = new TextEncoder().encode("verifyverifyverifyverifyverifyok");
|
|
@@ -1366,27 +1436,22 @@ function verifyWallet(wallet) {
|
|
|
1366
1436
|
if (keyType === KEY_TYPE_HYBRIDEDMLDSASLHDSA && hybridNs) {
|
|
1367
1437
|
sigRes = hybridNs.sign(privU8, message);
|
|
1368
1438
|
if (sigRes && sigRes.error) {
|
|
1369
|
-
console.log('[verifyWallet] FAIL: hybridNs.sign returned error:', sigRes.error);
|
|
1370
1439
|
return false;
|
|
1371
1440
|
}
|
|
1372
1441
|
verRes = hybridNs.verify(pubU8, message, sigRes.result);
|
|
1373
1442
|
} else if (keyType === KEY_TYPE_HYBRIDEDMLDSASLHDSA5 && hybrid5Ns) {
|
|
1374
1443
|
sigRes = hybrid5Ns.sign(privU8, message);
|
|
1375
1444
|
if (sigRes && sigRes.error) {
|
|
1376
|
-
console.log('[verifyWallet] FAIL: hybrid5Ns.sign returned error:', sigRes.error);
|
|
1377
1445
|
return false;
|
|
1378
1446
|
}
|
|
1379
1447
|
verRes = hybrid5Ns.verify(pubU8, message, sigRes.result);
|
|
1380
1448
|
} else {
|
|
1381
|
-
console.log('[verifyWallet] FAIL: no CIRCL namespace for keyType (keyType=' + keyType + ', hybridNs=' + !!hybridNs + ', hybrid5Ns=' + !!hybrid5Ns + ')');
|
|
1382
1449
|
return false;
|
|
1383
1450
|
}
|
|
1384
1451
|
if (verRes && verRes.error) {
|
|
1385
|
-
console.log('[verifyWallet] FAIL: verify returned error:', verRes.error);
|
|
1386
1452
|
return false;
|
|
1387
1453
|
}
|
|
1388
1454
|
if (!(verRes && verRes.result === true)) {
|
|
1389
|
-
console.log('[verifyWallet] FAIL: verRes.result !== true (verRes=', verRes, ')');
|
|
1390
1455
|
return false;
|
|
1391
1456
|
}
|
|
1392
1457
|
return true;
|
|
@@ -1414,6 +1479,10 @@ function serializeWallet(wallet) {
|
|
|
1414
1479
|
"publicKey": bytesToBase64(wallet.publicKey),
|
|
1415
1480
|
}
|
|
1416
1481
|
|
|
1482
|
+
if (wallet.preExpansionSeed != null && wallet.preExpansionSeed.length > 0) {
|
|
1483
|
+
walletJson.preExpansionSeed = bytesToBase64(wallet.preExpansionSeed);
|
|
1484
|
+
}
|
|
1485
|
+
|
|
1417
1486
|
return JSON.stringify(walletJson);
|
|
1418
1487
|
}
|
|
1419
1488
|
|
|
@@ -1421,23 +1490,35 @@ function serializeWallet(wallet) {
|
|
|
1421
1490
|
* The deserializeWallet function creates a Wallet object from a JSON string.
|
|
1422
1491
|
*
|
|
1423
1492
|
* @function deserializeWallet
|
|
1424
|
-
* @param {string} walletJson - A
|
|
1425
|
-
* @return {Wallet} Returns the Wallet corresponding to the walletJson. If the wallet is invalid, null is returned.
|
|
1493
|
+
* @param {string} walletJson - A JSON string representing the wallet to deserialize.
|
|
1494
|
+
* @return {Wallet|null} Returns the Wallet corresponding to the walletJson. If the wallet is invalid or the JSON is malformed, null is returned.
|
|
1426
1495
|
*/
|
|
1427
1496
|
function deserializeWallet(walletJson) {
|
|
1428
1497
|
if (isInitialized === false) {
|
|
1429
1498
|
return -1000;
|
|
1430
1499
|
}
|
|
1431
1500
|
|
|
1432
|
-
|
|
1501
|
+
try {
|
|
1502
|
+
var tempWallet = JSON.parse(walletJson);
|
|
1503
|
+
if (tempWallet == null || typeof tempWallet !== 'object') {
|
|
1504
|
+
return null;
|
|
1505
|
+
}
|
|
1506
|
+
|
|
1507
|
+
var preExpansionSeed = null;
|
|
1508
|
+
if (tempWallet.preExpansionSeed != null && tempWallet.preExpansionSeed.length > 0) {
|
|
1509
|
+
preExpansionSeed = base64ToBytes(tempWallet.preExpansionSeed);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
var wallet = new Wallet(tempWallet.address, base64ToBytes(tempWallet.privateKey), base64ToBytes(tempWallet.publicKey), preExpansionSeed);
|
|
1433
1513
|
|
|
1434
|
-
|
|
1514
|
+
if (verifyWallet(wallet) === false) {
|
|
1515
|
+
return null;
|
|
1516
|
+
}
|
|
1435
1517
|
|
|
1436
|
-
|
|
1518
|
+
return wallet;
|
|
1519
|
+
} catch (e) {
|
|
1437
1520
|
return null;
|
|
1438
1521
|
}
|
|
1439
|
-
|
|
1440
|
-
return wallet;
|
|
1441
1522
|
}
|
|
1442
1523
|
|
|
1443
1524
|
function transactionGetSigningHash(fromaddress, nonce, toaddress, amount, gas, chainid, data) {
|
|
@@ -1482,7 +1563,6 @@ function transactionGetData(fromaddress, nonce, toaddress, amount, gas, chainid,
|
|
|
1482
1563
|
function transactionGetSigningHash2(fromaddress, nonce, toaddress, valueInWeiHex, gas, chainid, data, remarks, signingContext) {
|
|
1483
1564
|
let messageDataReturn = TxnSigningHash2(fromaddress, nonce, toaddress, valueInWeiHex, gas, chainid, data, remarks, signingContext);
|
|
1484
1565
|
if (messageDataReturn && messageDataReturn.error) {
|
|
1485
|
-
console.log('[transactionGetSigningHash2] FAIL: messageDataReturn returned error:', messageDataReturn.error);
|
|
1486
1566
|
return null;
|
|
1487
1567
|
}
|
|
1488
1568
|
var messageData = messageDataReturn.result;
|
|
@@ -1506,7 +1586,6 @@ function transactionGetTransactionHash2(fromaddress, nonce, toaddress, valueInWe
|
|
|
1506
1586
|
}
|
|
1507
1587
|
var txnHashReturn = TxnHash2(fromaddress, nonce, toaddress, valueInWeiHex, gas, chainid, data, remarks, signingContext, typedPkArray, typedSigArray)
|
|
1508
1588
|
if (txnHashReturn && txnHashReturn.error) {
|
|
1509
|
-
console.log('[transactionGetTransactionHash2] FAIL: TxnHash2 returned error:', txnHashReturn.error);
|
|
1510
1589
|
return null;
|
|
1511
1590
|
}
|
|
1512
1591
|
return txnHashReturn.result;
|
|
@@ -1525,7 +1604,6 @@ function transactionGetData2(fromaddress, nonce, toaddress, valueInWeiHex, gas,
|
|
|
1525
1604
|
}
|
|
1526
1605
|
var txnDataReturn = TxnData2(fromaddress, nonce, toaddress, valueInWeiHex, gas, chainid, data, remarks, signingContext, typedPkArray, typedSigArray)
|
|
1527
1606
|
if (txnDataReturn && txnDataReturn.error) {
|
|
1528
|
-
console.log('[transactionGetData2] FAIL: TxnData2 returned error:', txnDataReturn.error);
|
|
1529
1607
|
return null;
|
|
1530
1608
|
}
|
|
1531
1609
|
return txnDataReturn.result;
|
|
@@ -1573,7 +1651,7 @@ async function postTransaction(txnData) {
|
|
|
1573
1651
|
return new SendResult(-601, null, null, requestId);
|
|
1574
1652
|
}
|
|
1575
1653
|
|
|
1576
|
-
if (response.status
|
|
1654
|
+
if (response.status === 200 || response.status === 204) {
|
|
1577
1655
|
return new SendResult(0, null, response, requestId);
|
|
1578
1656
|
}
|
|
1579
1657
|
|
|
@@ -1588,7 +1666,7 @@ async function postTransaction(txnData) {
|
|
|
1588
1666
|
*
|
|
1589
1667
|
* @async
|
|
1590
1668
|
* @function getLatestBlockDetails
|
|
1591
|
-
* @return {Promise<LatestBlockDetailsResult>} Returns a promise of an object of type
|
|
1669
|
+
* @return {Promise<LatestBlockDetailsResult>} Returns a promise of an object of type LatestBlockDetailsResult.
|
|
1592
1670
|
*/
|
|
1593
1671
|
async function getLatestBlockDetails() {
|
|
1594
1672
|
if (isInitialized === false) {
|
|
@@ -1634,7 +1712,7 @@ async function getLatestBlockDetails() {
|
|
|
1634
1712
|
}
|
|
1635
1713
|
|
|
1636
1714
|
let blockNumber = parseInt(result.blockNumber);
|
|
1637
|
-
if (Number.isInteger(blockNumber)
|
|
1715
|
+
if (Number.isInteger(blockNumber) === false) {
|
|
1638
1716
|
return new LatestBlockDetailsResult(-105, null, response, requestId);
|
|
1639
1717
|
}
|
|
1640
1718
|
|
|
@@ -1661,7 +1739,7 @@ async function getAccountDetails(address) {
|
|
|
1661
1739
|
if (address == null) {
|
|
1662
1740
|
return new AccountDetailsResult(-200, null, null, null);
|
|
1663
1741
|
}
|
|
1664
|
-
if (isAddressValid(address)
|
|
1742
|
+
if (isAddressValid(address) === false) {
|
|
1665
1743
|
return new AccountDetailsResult(-201, null, null, null);
|
|
1666
1744
|
}
|
|
1667
1745
|
|
|
@@ -1706,7 +1784,7 @@ async function getAccountDetails(address) {
|
|
|
1706
1784
|
}
|
|
1707
1785
|
|
|
1708
1786
|
let blockNumber = parseInt(result.blockNumber);
|
|
1709
|
-
if (Number.isInteger(blockNumber)
|
|
1787
|
+
if (Number.isInteger(blockNumber) === false) {
|
|
1710
1788
|
return new AccountDetailsResult(-207, null, response, requestId);
|
|
1711
1789
|
}
|
|
1712
1790
|
|
|
@@ -1714,7 +1792,7 @@ async function getAccountDetails(address) {
|
|
|
1714
1792
|
nonce = 0;
|
|
1715
1793
|
} else {
|
|
1716
1794
|
let tempNonce = parseInt(result.nonce);
|
|
1717
|
-
if (Number.isInteger(tempNonce)
|
|
1795
|
+
if (Number.isInteger(tempNonce) === true) {
|
|
1718
1796
|
nonce = tempNonce;
|
|
1719
1797
|
if (nonce < 0) {
|
|
1720
1798
|
return new AccountDetailsResult(-208, null, response, requestId);
|
|
@@ -1725,7 +1803,7 @@ async function getAccountDetails(address) {
|
|
|
1725
1803
|
}
|
|
1726
1804
|
|
|
1727
1805
|
if (result.balance != null) {
|
|
1728
|
-
if (isLargeNumber(result.balance)
|
|
1806
|
+
if (isLargeNumber(result.balance) === false) {
|
|
1729
1807
|
return new AccountDetailsResult(-210, null, response, requestId);
|
|
1730
1808
|
} else {
|
|
1731
1809
|
balance = result.balance;
|
|
@@ -1736,7 +1814,7 @@ async function getAccountDetails(address) {
|
|
|
1736
1814
|
return new AccountDetailsResult(0, accountDetails, response, requestId);
|
|
1737
1815
|
|
|
1738
1816
|
} catch (error) {
|
|
1739
|
-
return new AccountDetailsResult(
|
|
1817
|
+
return new AccountDetailsResult(-10000, null, null, requestId, error);
|
|
1740
1818
|
}
|
|
1741
1819
|
}
|
|
1742
1820
|
|
|
@@ -1750,7 +1828,7 @@ async function getAccountDetails(address) {
|
|
|
1750
1828
|
* @async
|
|
1751
1829
|
* @function getTransactionDetails
|
|
1752
1830
|
* @param {string} txnHash - The hash of the transaction to retrieve.
|
|
1753
|
-
* @return {Promise<TransactionDetailsResult>} Returns a promise of type
|
|
1831
|
+
* @return {Promise<TransactionDetailsResult>} Returns a promise of type TransactionDetailsResult.
|
|
1754
1832
|
*/
|
|
1755
1833
|
async function getTransactionDetails(txnHash) {
|
|
1756
1834
|
if (isInitialized === false) {
|
|
@@ -1760,7 +1838,7 @@ async function getTransactionDetails(txnHash) {
|
|
|
1760
1838
|
if (txnHash == null) {
|
|
1761
1839
|
return new TransactionDetailsResult(-300, null, null, null);
|
|
1762
1840
|
}
|
|
1763
|
-
if (isAddressValid(txnHash)
|
|
1841
|
+
if (isAddressValid(txnHash) === false) {
|
|
1764
1842
|
return new TransactionDetailsResult(-301, null, null, null);
|
|
1765
1843
|
}
|
|
1766
1844
|
|
|
@@ -1802,7 +1880,7 @@ async function getTransactionDetails(txnHash) {
|
|
|
1802
1880
|
|
|
1803
1881
|
if (result.blockNumber !== null) {
|
|
1804
1882
|
let tempBlockNumber = parseInt(result.blockNumber);
|
|
1805
|
-
if (Number.isInteger(tempBlockNumber)
|
|
1883
|
+
if (Number.isInteger(tempBlockNumber) === true) {
|
|
1806
1884
|
transactionDetails.blockNumber = tempBlockNumber;
|
|
1807
1885
|
}
|
|
1808
1886
|
if (tempBlockNumber < 0) {
|
|
@@ -1832,7 +1910,7 @@ async function getTransactionDetails(txnHash) {
|
|
|
1832
1910
|
|
|
1833
1911
|
return new TransactionDetailsResult(0, transactionDetails, response, requestId);
|
|
1834
1912
|
} catch (error) {
|
|
1835
|
-
return new TransactionDetailsResult(
|
|
1913
|
+
return new TransactionDetailsResult(-10000, null, null, requestId, error);
|
|
1836
1914
|
}
|
|
1837
1915
|
}
|
|
1838
1916
|
|
|
@@ -1841,14 +1919,14 @@ async function getTransactionDetails(txnHash) {
|
|
|
1841
1919
|
* Transactions may take a while to get registered in the blockchain. After a transaction is submitted, it may take a while before it is available for listing.
|
|
1842
1920
|
* Some transactions that have lower balance than the minimum required for gas fees may be discarded.
|
|
1843
1921
|
* In these cases, the transactions may not be returned when invoking the listAccountTransactions function.
|
|
1844
|
-
* You should consider the transaction as succeeded only if the status field
|
|
1922
|
+
* You should consider the transaction as succeeded only if the status field of the AccountTransactionCompact object is 0x1 (success).
|
|
1845
1923
|
* Both transactions from and transactions to the address will be returned in the list.
|
|
1846
1924
|
* Use the getTransactionDetails function, passing the hash of the transaction to get detailed information about the transaction.
|
|
1847
1925
|
* @async
|
|
1848
1926
|
* @function listAccountTransactions
|
|
1849
1927
|
* @param {string} address - The address for which the transactions have to be listed.
|
|
1850
1928
|
* @param {number} pageNumber - The page number for which the transactions has to be listed for the account. Pass 0 to list the latest page. Pass 1 to list the oldest page. A maximum of 20 transactions are returned in each page. The response of this API includes a field that shows the pageCount (total number of pages available). You can pass any number between 1 to pageCount to get the corresponding page.
|
|
1851
|
-
* @return {Promise<
|
|
1929
|
+
* @return {Promise<AccountTransactionsResult>} Returns a promise of type AccountTransactionsResult.
|
|
1852
1930
|
*/
|
|
1853
1931
|
async function listAccountTransactions(address, pageNumber) {
|
|
1854
1932
|
if (isInitialized === false) {
|
|
@@ -1929,7 +2007,7 @@ async function listAccountTransactions(address, pageNumber) {
|
|
|
1929
2007
|
|
|
1930
2008
|
return new AccountTransactionsResult(0, listAccountDetailsResponse, response, requestId);
|
|
1931
2009
|
} catch (error) {
|
|
1932
|
-
return new AccountTransactionsResult(
|
|
2010
|
+
return new AccountTransactionsResult(-10000, null, null, requestId, error);
|
|
1933
2011
|
}
|
|
1934
2012
|
}
|
|
1935
2013
|
|
|
@@ -1945,7 +2023,7 @@ async function listAccountTransactions(address, pageNumber) {
|
|
|
1945
2023
|
* @param {string} toAddress - The address to which the coins should be sent.
|
|
1946
2024
|
* @param {string} coins - The string representing the number of coins (in ether) to send. To convert between ethers and wei, see https://docs.ethers.org/v4/api-utils.html#ether-strings-and-wei
|
|
1947
2025
|
* @param {number} nonce - The nonce of the account retrieved by invoking the getAccountDetails function. You have to carefully manage state of the nonce to avoid sending the coins multiple times, such as when retrying sendCoins after a network error.
|
|
1948
|
-
* @return {SignResult} Returns a promise of type SignResult.
|
|
2026
|
+
* @return {Promise<SignResult>} Returns a promise of type SignResult.
|
|
1949
2027
|
*/
|
|
1950
2028
|
async function signSendCoinTransaction(wallet, toAddress, coins, nonce) {
|
|
1951
2029
|
if (isInitialized === false) {
|
|
@@ -1956,20 +2034,20 @@ async function signSendCoinTransaction(wallet, toAddress, coins, nonce) {
|
|
|
1956
2034
|
return new SignResult(-500, null, null);
|
|
1957
2035
|
}
|
|
1958
2036
|
|
|
1959
|
-
if (isAddressValid(toAddress)
|
|
2037
|
+
if (isAddressValid(toAddress) === false) {
|
|
1960
2038
|
return new SignResult(-501, null, null);
|
|
1961
2039
|
}
|
|
1962
2040
|
|
|
1963
|
-
if (verifyWallet(wallet)
|
|
2041
|
+
if (verifyWallet(wallet) === false) {
|
|
1964
2042
|
return new SignResult(-502, null, null);
|
|
1965
2043
|
}
|
|
1966
2044
|
|
|
1967
|
-
if (isLargeNumber(coins)
|
|
2045
|
+
if (isLargeNumber(coins) === false) {
|
|
1968
2046
|
return new SignResult(-503, null, null);
|
|
1969
2047
|
}
|
|
1970
2048
|
|
|
1971
2049
|
let tempNonce = parseInt(nonce);
|
|
1972
|
-
if (Number.isInteger(tempNonce)
|
|
2050
|
+
if (Number.isInteger(tempNonce) === false) {
|
|
1973
2051
|
return new SignResult(-504, null, null);
|
|
1974
2052
|
}
|
|
1975
2053
|
nonce = tempNonce;
|
|
@@ -2026,8 +2104,8 @@ async function signSendCoinTransaction(wallet, toAddress, coins, nonce) {
|
|
|
2026
2104
|
* @param {string} toAddress - The address to which the coins should be sent.
|
|
2027
2105
|
* @param {string} coins - The string representing the number of coins (in ether) to send. To convert between ethers and wei, see https://docs.ethers.org/v4/api-utils.html#ether-strings-and-wei
|
|
2028
2106
|
* @param {number} nonce - The nonce of the account retrieved by invoking the getAccountDetails function. You have to carefully manage state of the nonce to avoid sending the coins multiple times, such as when retrying sendCoins after a network error.
|
|
2029
|
-
* @param {
|
|
2030
|
-
* @return {SignResult} Returns a promise of type SignResult.
|
|
2107
|
+
* @param {string} data - Ignored. This parameter is accepted but not used. Use signRawTransaction to pass contract data.
|
|
2108
|
+
* @return {Promise<SignResult>} Returns a promise of type SignResult.
|
|
2031
2109
|
*/
|
|
2032
2110
|
async function signTransaction(wallet, toAddress, coins, nonce, data) {
|
|
2033
2111
|
if (isInitialized === false) {
|
|
@@ -2038,20 +2116,20 @@ async function signTransaction(wallet, toAddress, coins, nonce, data) {
|
|
|
2038
2116
|
return new SignResult(-500, null, null);
|
|
2039
2117
|
}
|
|
2040
2118
|
|
|
2041
|
-
if (isAddressValid(toAddress)
|
|
2119
|
+
if (isAddressValid(toAddress) === false) {
|
|
2042
2120
|
return new SignResult(-501, null, null);
|
|
2043
2121
|
}
|
|
2044
2122
|
|
|
2045
|
-
if (verifyWallet(wallet)
|
|
2123
|
+
if (verifyWallet(wallet) === false) {
|
|
2046
2124
|
return new SignResult(-502, null, null);
|
|
2047
2125
|
}
|
|
2048
2126
|
|
|
2049
|
-
if (isLargeNumber(coins)
|
|
2127
|
+
if (isLargeNumber(coins) === false) {
|
|
2050
2128
|
return new SignResult(-503, null, null);
|
|
2051
2129
|
}
|
|
2052
2130
|
|
|
2053
2131
|
let tempNonce = parseInt(nonce);
|
|
2054
|
-
if (Number.isInteger(tempNonce)
|
|
2132
|
+
if (Number.isInteger(tempNonce) === false) {
|
|
2055
2133
|
return new SignResult(-504, null, null);
|
|
2056
2134
|
}
|
|
2057
2135
|
nonce = tempNonce;
|
|
@@ -2112,6 +2190,10 @@ function hexStringToUint8Array(hex) {
|
|
|
2112
2190
|
hex = hex.slice(2);
|
|
2113
2191
|
}
|
|
2114
2192
|
|
|
2193
|
+
if (/[^0-9a-fA-F]/.test(hex)) {
|
|
2194
|
+
return new Uint8Array(0);
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2115
2197
|
// Ensure even length (pad with leading zero if needed)
|
|
2116
2198
|
if (hex.length % 2 !== 0) {
|
|
2117
2199
|
hex = '0' + hex;
|
|
@@ -2162,7 +2244,7 @@ function signRawTransaction(transactionSigningRequest) {
|
|
|
2162
2244
|
// Convert BigInt to hex string
|
|
2163
2245
|
valueInWeiHex = '0x' + transactionSigningRequest.valueInWei.toString(16);
|
|
2164
2246
|
} else if (typeof transactionSigningRequest.valueInWei === 'string') {
|
|
2165
|
-
if (transactionSigningRequest.valueInWei.startsWith('0x') === false) {
|
|
2247
|
+
if (transactionSigningRequest.valueInWei.startsWith('0x') === false || /[^0-9a-fA-F]/.test(transactionSigningRequest.valueInWei.slice(2))) {
|
|
2166
2248
|
return new SignResult(-903, null, null);
|
|
2167
2249
|
}
|
|
2168
2250
|
valueInWeiHex = transactionSigningRequest.valueInWei;
|
|
@@ -2182,7 +2264,7 @@ function signRawTransaction(transactionSigningRequest) {
|
|
|
2182
2264
|
|
|
2183
2265
|
let data = null;
|
|
2184
2266
|
if (transactionSigningRequest.data !== null) {
|
|
2185
|
-
if (typeof transactionSigningRequest.data !== 'string' || transactionSigningRequest.data.startsWith('0x') === false) {
|
|
2267
|
+
if (typeof transactionSigningRequest.data !== 'string' || transactionSigningRequest.data.startsWith('0x') === false || /[^0-9a-fA-F]/.test(transactionSigningRequest.data.slice(2))) {
|
|
2186
2268
|
return new SignResult(-906, null, null);
|
|
2187
2269
|
}
|
|
2188
2270
|
data = hexStringToUint8Array(transactionSigningRequest.data);
|
|
@@ -2199,7 +2281,7 @@ function signRawTransaction(transactionSigningRequest) {
|
|
|
2199
2281
|
|
|
2200
2282
|
let remarks = null;
|
|
2201
2283
|
if (transactionSigningRequest.remarks !== null) {
|
|
2202
|
-
if (typeof transactionSigningRequest.remarks !== 'string' || transactionSigningRequest.remarks.startsWith('0x') === false) {
|
|
2284
|
+
if (typeof transactionSigningRequest.remarks !== 'string' || transactionSigningRequest.remarks.startsWith('0x') === false || /[^0-9a-fA-F]/.test(transactionSigningRequest.remarks.slice(2))) {
|
|
2203
2285
|
return new SignResult(-909, null, null);
|
|
2204
2286
|
}
|
|
2205
2287
|
remarks = hexStringToUint8Array(transactionSigningRequest.remarks);
|
|
@@ -2399,20 +2481,20 @@ async function sendCoins(wallet, toAddress, coins, nonce) {
|
|
|
2399
2481
|
return new SendResult(-1, null, null, null);
|
|
2400
2482
|
}
|
|
2401
2483
|
|
|
2402
|
-
if (isAddressValid(toAddress)
|
|
2484
|
+
if (isAddressValid(toAddress) === false) {
|
|
2403
2485
|
return new SendResult(-2, null, null, null);
|
|
2404
2486
|
}
|
|
2405
2487
|
|
|
2406
|
-
if (verifyWallet(wallet)
|
|
2488
|
+
if (verifyWallet(wallet) === false) {
|
|
2407
2489
|
return new SendResult(-3, null, null, null);
|
|
2408
2490
|
}
|
|
2409
2491
|
|
|
2410
|
-
if (isLargeNumber(coins)
|
|
2492
|
+
if (isLargeNumber(coins) === false) {
|
|
2411
2493
|
return new SendResult(-4, null, null, null);
|
|
2412
2494
|
}
|
|
2413
2495
|
|
|
2414
2496
|
let tempNonce = parseInt(nonce);
|
|
2415
|
-
if (Number.isInteger(tempNonce)
|
|
2497
|
+
if (Number.isInteger(tempNonce) === false) {
|
|
2416
2498
|
return new SendResult(-5, null, null, null);
|
|
2417
2499
|
}
|
|
2418
2500
|
nonce = tempNonce;
|
|
@@ -3037,7 +3119,7 @@ module.exports = {
|
|
|
3037
3119
|
AccountTransactionsResult,
|
|
3038
3120
|
ListAccountTransactionsResponse,
|
|
3039
3121
|
AccountTransactionCompact,
|
|
3040
|
-
|
|
3122
|
+
newWalletSeedWords,
|
|
3041
3123
|
openWalletFromSeed,
|
|
3042
3124
|
openWalletFromSeedWords,
|
|
3043
3125
|
publicKeyFromSignature,
|