@talismn/util 0.0.0-pr2091-20250715125148 → 0.0.0-pr2092-20250715131755
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/dist/declarations/src/blake2Concat.d.ts +1 -0
- package/dist/declarations/src/classNames.d.ts +0 -1
- package/dist/declarations/src/convertAddress.d.ts +7 -0
- package/dist/declarations/src/decodeAnyAddress.d.ts +1 -0
- package/dist/declarations/src/decodeSs58Format.d.ts +1 -0
- package/dist/declarations/src/encodeAnyAddress.d.ts +1 -0
- package/dist/declarations/src/index.d.ts +10 -0
- package/dist/declarations/src/isAddressEqual.d.ts +1 -0
- package/dist/declarations/src/isEthereumAddress.d.ts +1 -0
- package/dist/declarations/src/isValidSubstrateAddress.d.ts +7 -0
- package/dist/declarations/src/normalizeAddress.d.ts +1 -0
- package/dist/declarations/src/twox64Concat.d.ts +1 -0
- package/dist/declarations/src/validateHexString.d.ts +3 -2
- package/dist/talismn-util.cjs.dev.js +109 -3
- package/dist/talismn-util.cjs.prod.js +109 -3
- package/dist/talismn-util.esm.js +100 -3
- package/package.json +7 -1
@@ -0,0 +1 @@
|
|
1
|
+
export declare function blake2Concat(input: Uint8Array): `0x${string}`;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function decodeAnyAddress(encoded?: string | Uint8Array | null | undefined, ignoreChecksum?: boolean | undefined, ss58Format?: number | undefined): Uint8Array;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const decodeSs58Format: (address?: string) => number | undefined;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function encodeAnyAddress(key: string | Uint8Array, ss58Format?: number | undefined): string;
|
@@ -1,7 +1,12 @@
|
|
1
1
|
export * from "./addTrailingSlash";
|
2
2
|
export * from "./BigMath";
|
3
|
+
export * from "./blake2Concat";
|
3
4
|
export * from "./classNames";
|
5
|
+
export * from "./convertAddress";
|
6
|
+
export * from "./decodeAnyAddress";
|
7
|
+
export * from "./decodeSs58Format";
|
4
8
|
export * from "./deferred";
|
9
|
+
export * from "./encodeAnyAddress";
|
5
10
|
export * from "./firstThenDebounce";
|
6
11
|
export * from "./formatDecimals";
|
7
12
|
export * from "./formatPrice";
|
@@ -10,11 +15,16 @@ export * from "./hasOwnProperty";
|
|
10
15
|
export * from "./isArrayOf";
|
11
16
|
export * from "./isBigInt";
|
12
17
|
export * from "./isBooleanTrue";
|
18
|
+
export * from "./isEthereumAddress";
|
19
|
+
export * from "./isValidSubstrateAddress";
|
13
20
|
export * from "./planckToTokens";
|
14
21
|
export * from "./sleep";
|
15
22
|
export * from "./throwAfter";
|
16
23
|
export * from "./tokensToPlanck";
|
24
|
+
export * from "./twox64Concat";
|
17
25
|
export * from "./validateHexString";
|
26
|
+
export * from "./normalizeAddress";
|
27
|
+
export * from "./isAddressEqual";
|
18
28
|
export * from "./isAscii";
|
19
29
|
export * from "./isNotNil";
|
20
30
|
export * from "./isTruthy";
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const isAddressEqual: (address1: string, address2: string) => boolean;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const isEthereumAddress: (address: string | undefined | null) => address is `0x${string}`;
|
@@ -0,0 +1,7 @@
|
|
1
|
+
/**
|
2
|
+
* Similar to isValidAddress but will not call isEthereumAddress under the hood
|
3
|
+
* @param address
|
4
|
+
* @param prefix if supplied, the method will also check the prefix
|
5
|
+
* @returns true if valid substrate (SS58) address, false otherwise
|
6
|
+
*/
|
7
|
+
export declare const isValidSubstrateAddress: (address: string, prefix?: number | null) => boolean;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const normalizeAddress: (address: string) => string;
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare function twox64Concat(input: string | Buffer | Uint8Array): `0x${string}`;
|
@@ -1,11 +1,12 @@
|
|
1
|
+
import { HexString } from "@polkadot/util/types";
|
1
2
|
/**
|
2
3
|
* @name validateHexString
|
3
4
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
4
5
|
* @param {string} str - string to check
|
5
|
-
* @returns {
|
6
|
+
* @returns {HexString} - boolean
|
6
7
|
* @example
|
7
8
|
* validateHexString("0x1234") // "0x1234"
|
8
9
|
* validateHexString("1234") // Error: Expected a hex string
|
9
10
|
* validateHexString(1234) // Error: Expected a string
|
10
11
|
**/
|
11
|
-
export declare const validateHexString: (str: string) =>
|
12
|
+
export declare const validateHexString: (str: string) => HexString;
|
@@ -1,6 +1,9 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
+
var util = require('@polkadot/util');
|
4
|
+
var utilCrypto = require('@polkadot/util-crypto');
|
3
5
|
var tailwindMerge = require('tailwind-merge');
|
6
|
+
var keyring = require('@polkadot/keyring');
|
4
7
|
var rxjs = require('rxjs');
|
5
8
|
var BigNumber = require('bignumber.js');
|
6
9
|
|
@@ -42,8 +45,54 @@ const BigMath = {
|
|
42
45
|
}
|
43
46
|
};
|
44
47
|
|
48
|
+
const bitLength$1 = 128;
|
49
|
+
function blake2Concat(input) {
|
50
|
+
return util.u8aToHex(util.u8aConcat(utilCrypto.blake2AsU8a(input, bitLength$1), util.u8aToU8a(input)));
|
51
|
+
}
|
52
|
+
|
45
53
|
const classNames = tailwindMerge.twMerge;
|
46
|
-
|
54
|
+
|
55
|
+
function encodeAnyAddress(key, ss58Format) {
|
56
|
+
try {
|
57
|
+
return keyring.encodeAddress(key, ss58Format);
|
58
|
+
} catch (error) {
|
59
|
+
if (typeof key !== "string") throw error;
|
60
|
+
if (!utilCrypto.isEthereumAddress(key)) throw error;
|
61
|
+
return utilCrypto.ethereumEncode(key);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
*
|
67
|
+
* @param address substrate SS58 address
|
68
|
+
* @param prefix prefix used to format the address
|
69
|
+
* @returns address encoded with supplied prefix
|
70
|
+
*/
|
71
|
+
const convertAddress = (address, prefix) => {
|
72
|
+
return encodeAnyAddress(address, prefix ?? undefined);
|
73
|
+
};
|
74
|
+
|
75
|
+
function decodeAnyAddress(encoded, ignoreChecksum, ss58Format) {
|
76
|
+
try {
|
77
|
+
return keyring.decodeAddress(encoded, ignoreChecksum, ss58Format);
|
78
|
+
} catch (error) {
|
79
|
+
if (typeof encoded !== "string") throw error;
|
80
|
+
if (!utilCrypto.isEthereumAddress(encoded)) throw error;
|
81
|
+
return util.hexToU8a(encoded.slice("0x".length));
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
const decodeSs58Format = address => {
|
86
|
+
if (!address) return;
|
87
|
+
try {
|
88
|
+
utilCrypto.decodeAddress(address);
|
89
|
+
const decoded = utilCrypto.base58Decode(address);
|
90
|
+
const [,,, ss58Format] = utilCrypto.checkAddressChecksum(decoded);
|
91
|
+
return ss58Format;
|
92
|
+
} catch {
|
93
|
+
return; // invalid address
|
94
|
+
}
|
95
|
+
};
|
47
96
|
|
48
97
|
/**
|
49
98
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -161,6 +210,30 @@ const isBigInt = value => typeof value === "bigint";
|
|
161
210
|
|
162
211
|
const isBooleanTrue = x => !!x;
|
163
212
|
|
213
|
+
const isEthereumAddress = address => !!address && address.startsWith("0x") && address.length === 42;
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Similar to isValidAddress but will not call isEthereumAddress under the hood
|
217
|
+
* @param address
|
218
|
+
* @param prefix if supplied, the method will also check the prefix
|
219
|
+
* @returns true if valid substrate (SS58) address, false otherwise
|
220
|
+
*/
|
221
|
+
const isValidSubstrateAddress = (address, prefix) => {
|
222
|
+
try {
|
223
|
+
// attempt to encode, it will throw an error if address is invalid
|
224
|
+
const encoded = keyring.encodeAddress(address, prefix ?? undefined);
|
225
|
+
|
226
|
+
//if a prefix is supplied, check that reencoding using this prefix matches the input address
|
227
|
+
if (prefix !== undefined) return address === encoded;
|
228
|
+
|
229
|
+
//if no prefix supplied, the fact that decoding + encoding succeded indicates that the address is valid
|
230
|
+
return true;
|
231
|
+
} catch (error) {
|
232
|
+
// input is not a substrate (SS58) address
|
233
|
+
return false;
|
234
|
+
}
|
235
|
+
};
|
236
|
+
|
164
237
|
function planckToTokens(planck, tokenDecimals) {
|
165
238
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
166
239
|
const base = 10;
|
@@ -183,11 +256,17 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
183
256
|
return new BigNumber__default.default(tokens).multipliedBy(multiplier).toString(10);
|
184
257
|
}
|
185
258
|
|
259
|
+
const bitLength = 64;
|
260
|
+
function twox64Concat(input) {
|
261
|
+
const inputAsU8a = typeof input === "string" ? input : new Uint8Array(input);
|
262
|
+
return util.u8aToHex(util.u8aConcat(utilCrypto.xxhashAsU8a(inputAsU8a, bitLength), util.u8aToU8a(inputAsU8a)));
|
263
|
+
}
|
264
|
+
|
186
265
|
/**
|
187
266
|
* @name validateHexString
|
188
267
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
189
268
|
* @param {string} str - string to check
|
190
|
-
* @returns {
|
269
|
+
* @returns {HexString} - boolean
|
191
270
|
* @example
|
192
271
|
* validateHexString("0x1234") // "0x1234"
|
193
272
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -203,6 +282,24 @@ const validateHexString = str => {
|
|
203
282
|
throw new Error("Expected a hex string");
|
204
283
|
};
|
205
284
|
|
285
|
+
const CACHE$1 = new Map();
|
286
|
+
|
287
|
+
// Normalize an address in a way that it can be compared to other addresses that have also been normalized
|
288
|
+
const normalizeAddress = address => {
|
289
|
+
try {
|
290
|
+
if (!CACHE$1.has(address)) CACHE$1.set(address, encodeAnyAddress(address));
|
291
|
+
return CACHE$1.get(address);
|
292
|
+
} catch (cause) {
|
293
|
+
throw new Error(`Unable to normalize address: ${address}`, {
|
294
|
+
cause
|
295
|
+
});
|
296
|
+
}
|
297
|
+
};
|
298
|
+
|
299
|
+
const isAddressEqual = (address1, address2) => {
|
300
|
+
return normalizeAddress(address1) === normalizeAddress(address2);
|
301
|
+
};
|
302
|
+
|
206
303
|
const isAscii = str => {
|
207
304
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
208
305
|
};
|
@@ -286,23 +383,32 @@ exports.BigMath = BigMath;
|
|
286
383
|
exports.Deferred = Deferred;
|
287
384
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
288
385
|
exports.addTrailingSlash = addTrailingSlash;
|
386
|
+
exports.blake2Concat = blake2Concat;
|
289
387
|
exports.classNames = classNames;
|
290
|
-
exports.
|
388
|
+
exports.convertAddress = convertAddress;
|
389
|
+
exports.decodeAnyAddress = decodeAnyAddress;
|
390
|
+
exports.decodeSs58Format = decodeSs58Format;
|
391
|
+
exports.encodeAnyAddress = encodeAnyAddress;
|
291
392
|
exports.firstThenDebounce = firstThenDebounce;
|
292
393
|
exports.formatDecimals = formatDecimals;
|
293
394
|
exports.formatPrice = formatPrice;
|
294
395
|
exports.getSharedObservable = getSharedObservable;
|
295
396
|
exports.hasOwnProperty = hasOwnProperty;
|
296
397
|
exports.isAbortError = isAbortError;
|
398
|
+
exports.isAddressEqual = isAddressEqual;
|
297
399
|
exports.isArrayOf = isArrayOf;
|
298
400
|
exports.isAscii = isAscii;
|
299
401
|
exports.isBigInt = isBigInt;
|
300
402
|
exports.isBooleanTrue = isBooleanTrue;
|
403
|
+
exports.isEthereumAddress = isEthereumAddress;
|
301
404
|
exports.isNotNil = isNotNil;
|
302
405
|
exports.isTruthy = isTruthy;
|
406
|
+
exports.isValidSubstrateAddress = isValidSubstrateAddress;
|
303
407
|
exports.keepAlive = keepAlive;
|
408
|
+
exports.normalizeAddress = normalizeAddress;
|
304
409
|
exports.planckToTokens = planckToTokens;
|
305
410
|
exports.sleep = sleep;
|
306
411
|
exports.throwAfter = throwAfter;
|
307
412
|
exports.tokensToPlanck = tokensToPlanck;
|
413
|
+
exports.twox64Concat = twox64Concat;
|
308
414
|
exports.validateHexString = validateHexString;
|
@@ -1,6 +1,9 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
+
var util = require('@polkadot/util');
|
4
|
+
var utilCrypto = require('@polkadot/util-crypto');
|
3
5
|
var tailwindMerge = require('tailwind-merge');
|
6
|
+
var keyring = require('@polkadot/keyring');
|
4
7
|
var rxjs = require('rxjs');
|
5
8
|
var BigNumber = require('bignumber.js');
|
6
9
|
|
@@ -42,8 +45,54 @@ const BigMath = {
|
|
42
45
|
}
|
43
46
|
};
|
44
47
|
|
48
|
+
const bitLength$1 = 128;
|
49
|
+
function blake2Concat(input) {
|
50
|
+
return util.u8aToHex(util.u8aConcat(utilCrypto.blake2AsU8a(input, bitLength$1), util.u8aToU8a(input)));
|
51
|
+
}
|
52
|
+
|
45
53
|
const classNames = tailwindMerge.twMerge;
|
46
|
-
|
54
|
+
|
55
|
+
function encodeAnyAddress(key, ss58Format) {
|
56
|
+
try {
|
57
|
+
return keyring.encodeAddress(key, ss58Format);
|
58
|
+
} catch (error) {
|
59
|
+
if (typeof key !== "string") throw error;
|
60
|
+
if (!utilCrypto.isEthereumAddress(key)) throw error;
|
61
|
+
return utilCrypto.ethereumEncode(key);
|
62
|
+
}
|
63
|
+
}
|
64
|
+
|
65
|
+
/**
|
66
|
+
*
|
67
|
+
* @param address substrate SS58 address
|
68
|
+
* @param prefix prefix used to format the address
|
69
|
+
* @returns address encoded with supplied prefix
|
70
|
+
*/
|
71
|
+
const convertAddress = (address, prefix) => {
|
72
|
+
return encodeAnyAddress(address, prefix ?? undefined);
|
73
|
+
};
|
74
|
+
|
75
|
+
function decodeAnyAddress(encoded, ignoreChecksum, ss58Format) {
|
76
|
+
try {
|
77
|
+
return keyring.decodeAddress(encoded, ignoreChecksum, ss58Format);
|
78
|
+
} catch (error) {
|
79
|
+
if (typeof encoded !== "string") throw error;
|
80
|
+
if (!utilCrypto.isEthereumAddress(encoded)) throw error;
|
81
|
+
return util.hexToU8a(encoded.slice("0x".length));
|
82
|
+
}
|
83
|
+
}
|
84
|
+
|
85
|
+
const decodeSs58Format = address => {
|
86
|
+
if (!address) return;
|
87
|
+
try {
|
88
|
+
utilCrypto.decodeAddress(address);
|
89
|
+
const decoded = utilCrypto.base58Decode(address);
|
90
|
+
const [,,, ss58Format] = utilCrypto.checkAddressChecksum(decoded);
|
91
|
+
return ss58Format;
|
92
|
+
} catch {
|
93
|
+
return; // invalid address
|
94
|
+
}
|
95
|
+
};
|
47
96
|
|
48
97
|
/**
|
49
98
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -161,6 +210,30 @@ const isBigInt = value => typeof value === "bigint";
|
|
161
210
|
|
162
211
|
const isBooleanTrue = x => !!x;
|
163
212
|
|
213
|
+
const isEthereumAddress = address => !!address && address.startsWith("0x") && address.length === 42;
|
214
|
+
|
215
|
+
/**
|
216
|
+
* Similar to isValidAddress but will not call isEthereumAddress under the hood
|
217
|
+
* @param address
|
218
|
+
* @param prefix if supplied, the method will also check the prefix
|
219
|
+
* @returns true if valid substrate (SS58) address, false otherwise
|
220
|
+
*/
|
221
|
+
const isValidSubstrateAddress = (address, prefix) => {
|
222
|
+
try {
|
223
|
+
// attempt to encode, it will throw an error if address is invalid
|
224
|
+
const encoded = keyring.encodeAddress(address, prefix ?? undefined);
|
225
|
+
|
226
|
+
//if a prefix is supplied, check that reencoding using this prefix matches the input address
|
227
|
+
if (prefix !== undefined) return address === encoded;
|
228
|
+
|
229
|
+
//if no prefix supplied, the fact that decoding + encoding succeded indicates that the address is valid
|
230
|
+
return true;
|
231
|
+
} catch (error) {
|
232
|
+
// input is not a substrate (SS58) address
|
233
|
+
return false;
|
234
|
+
}
|
235
|
+
};
|
236
|
+
|
164
237
|
function planckToTokens(planck, tokenDecimals) {
|
165
238
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
166
239
|
const base = 10;
|
@@ -183,11 +256,17 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
183
256
|
return new BigNumber__default.default(tokens).multipliedBy(multiplier).toString(10);
|
184
257
|
}
|
185
258
|
|
259
|
+
const bitLength = 64;
|
260
|
+
function twox64Concat(input) {
|
261
|
+
const inputAsU8a = typeof input === "string" ? input : new Uint8Array(input);
|
262
|
+
return util.u8aToHex(util.u8aConcat(utilCrypto.xxhashAsU8a(inputAsU8a, bitLength), util.u8aToU8a(inputAsU8a)));
|
263
|
+
}
|
264
|
+
|
186
265
|
/**
|
187
266
|
* @name validateHexString
|
188
267
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
189
268
|
* @param {string} str - string to check
|
190
|
-
* @returns {
|
269
|
+
* @returns {HexString} - boolean
|
191
270
|
* @example
|
192
271
|
* validateHexString("0x1234") // "0x1234"
|
193
272
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -203,6 +282,24 @@ const validateHexString = str => {
|
|
203
282
|
throw new Error("Expected a hex string");
|
204
283
|
};
|
205
284
|
|
285
|
+
const CACHE$1 = new Map();
|
286
|
+
|
287
|
+
// Normalize an address in a way that it can be compared to other addresses that have also been normalized
|
288
|
+
const normalizeAddress = address => {
|
289
|
+
try {
|
290
|
+
if (!CACHE$1.has(address)) CACHE$1.set(address, encodeAnyAddress(address));
|
291
|
+
return CACHE$1.get(address);
|
292
|
+
} catch (cause) {
|
293
|
+
throw new Error(`Unable to normalize address: ${address}`, {
|
294
|
+
cause
|
295
|
+
});
|
296
|
+
}
|
297
|
+
};
|
298
|
+
|
299
|
+
const isAddressEqual = (address1, address2) => {
|
300
|
+
return normalizeAddress(address1) === normalizeAddress(address2);
|
301
|
+
};
|
302
|
+
|
206
303
|
const isAscii = str => {
|
207
304
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
208
305
|
};
|
@@ -286,23 +383,32 @@ exports.BigMath = BigMath;
|
|
286
383
|
exports.Deferred = Deferred;
|
287
384
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
288
385
|
exports.addTrailingSlash = addTrailingSlash;
|
386
|
+
exports.blake2Concat = blake2Concat;
|
289
387
|
exports.classNames = classNames;
|
290
|
-
exports.
|
388
|
+
exports.convertAddress = convertAddress;
|
389
|
+
exports.decodeAnyAddress = decodeAnyAddress;
|
390
|
+
exports.decodeSs58Format = decodeSs58Format;
|
391
|
+
exports.encodeAnyAddress = encodeAnyAddress;
|
291
392
|
exports.firstThenDebounce = firstThenDebounce;
|
292
393
|
exports.formatDecimals = formatDecimals;
|
293
394
|
exports.formatPrice = formatPrice;
|
294
395
|
exports.getSharedObservable = getSharedObservable;
|
295
396
|
exports.hasOwnProperty = hasOwnProperty;
|
296
397
|
exports.isAbortError = isAbortError;
|
398
|
+
exports.isAddressEqual = isAddressEqual;
|
297
399
|
exports.isArrayOf = isArrayOf;
|
298
400
|
exports.isAscii = isAscii;
|
299
401
|
exports.isBigInt = isBigInt;
|
300
402
|
exports.isBooleanTrue = isBooleanTrue;
|
403
|
+
exports.isEthereumAddress = isEthereumAddress;
|
301
404
|
exports.isNotNil = isNotNil;
|
302
405
|
exports.isTruthy = isTruthy;
|
406
|
+
exports.isValidSubstrateAddress = isValidSubstrateAddress;
|
303
407
|
exports.keepAlive = keepAlive;
|
408
|
+
exports.normalizeAddress = normalizeAddress;
|
304
409
|
exports.planckToTokens = planckToTokens;
|
305
410
|
exports.sleep = sleep;
|
306
411
|
exports.throwAfter = throwAfter;
|
307
412
|
exports.tokensToPlanck = tokensToPlanck;
|
413
|
+
exports.twox64Concat = twox64Concat;
|
308
414
|
exports.validateHexString = validateHexString;
|
package/dist/talismn-util.esm.js
CHANGED
@@ -1,4 +1,7 @@
|
|
1
|
+
import { u8aToHex, u8aConcat, u8aToU8a, hexToU8a } from '@polkadot/util';
|
2
|
+
import { blake2AsU8a, isEthereumAddress as isEthereumAddress$1, ethereumEncode, decodeAddress as decodeAddress$1, base58Decode, checkAddressChecksum, xxhashAsU8a } from '@polkadot/util-crypto';
|
1
3
|
import { twMerge } from 'tailwind-merge';
|
4
|
+
import { encodeAddress, decodeAddress } from '@polkadot/keyring';
|
2
5
|
import { concat, take, skip, debounceTime, shareReplay, tap } from 'rxjs';
|
3
6
|
import BigNumber from 'bignumber.js';
|
4
7
|
|
@@ -36,8 +39,54 @@ const BigMath = {
|
|
36
39
|
}
|
37
40
|
};
|
38
41
|
|
42
|
+
const bitLength$1 = 128;
|
43
|
+
function blake2Concat(input) {
|
44
|
+
return u8aToHex(u8aConcat(blake2AsU8a(input, bitLength$1), u8aToU8a(input)));
|
45
|
+
}
|
46
|
+
|
39
47
|
const classNames = twMerge;
|
40
|
-
|
48
|
+
|
49
|
+
function encodeAnyAddress(key, ss58Format) {
|
50
|
+
try {
|
51
|
+
return encodeAddress(key, ss58Format);
|
52
|
+
} catch (error) {
|
53
|
+
if (typeof key !== "string") throw error;
|
54
|
+
if (!isEthereumAddress$1(key)) throw error;
|
55
|
+
return ethereumEncode(key);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
|
59
|
+
/**
|
60
|
+
*
|
61
|
+
* @param address substrate SS58 address
|
62
|
+
* @param prefix prefix used to format the address
|
63
|
+
* @returns address encoded with supplied prefix
|
64
|
+
*/
|
65
|
+
const convertAddress = (address, prefix) => {
|
66
|
+
return encodeAnyAddress(address, prefix ?? undefined);
|
67
|
+
};
|
68
|
+
|
69
|
+
function decodeAnyAddress(encoded, ignoreChecksum, ss58Format) {
|
70
|
+
try {
|
71
|
+
return decodeAddress(encoded, ignoreChecksum, ss58Format);
|
72
|
+
} catch (error) {
|
73
|
+
if (typeof encoded !== "string") throw error;
|
74
|
+
if (!isEthereumAddress$1(encoded)) throw error;
|
75
|
+
return hexToU8a(encoded.slice("0x".length));
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
const decodeSs58Format = address => {
|
80
|
+
if (!address) return;
|
81
|
+
try {
|
82
|
+
decodeAddress$1(address);
|
83
|
+
const decoded = base58Decode(address);
|
84
|
+
const [,,, ss58Format] = checkAddressChecksum(decoded);
|
85
|
+
return ss58Format;
|
86
|
+
} catch {
|
87
|
+
return; // invalid address
|
88
|
+
}
|
89
|
+
};
|
41
90
|
|
42
91
|
/**
|
43
92
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -155,6 +204,30 @@ const isBigInt = value => typeof value === "bigint";
|
|
155
204
|
|
156
205
|
const isBooleanTrue = x => !!x;
|
157
206
|
|
207
|
+
const isEthereumAddress = address => !!address && address.startsWith("0x") && address.length === 42;
|
208
|
+
|
209
|
+
/**
|
210
|
+
* Similar to isValidAddress but will not call isEthereumAddress under the hood
|
211
|
+
* @param address
|
212
|
+
* @param prefix if supplied, the method will also check the prefix
|
213
|
+
* @returns true if valid substrate (SS58) address, false otherwise
|
214
|
+
*/
|
215
|
+
const isValidSubstrateAddress = (address, prefix) => {
|
216
|
+
try {
|
217
|
+
// attempt to encode, it will throw an error if address is invalid
|
218
|
+
const encoded = encodeAddress(address, prefix ?? undefined);
|
219
|
+
|
220
|
+
//if a prefix is supplied, check that reencoding using this prefix matches the input address
|
221
|
+
if (prefix !== undefined) return address === encoded;
|
222
|
+
|
223
|
+
//if no prefix supplied, the fact that decoding + encoding succeded indicates that the address is valid
|
224
|
+
return true;
|
225
|
+
} catch (error) {
|
226
|
+
// input is not a substrate (SS58) address
|
227
|
+
return false;
|
228
|
+
}
|
229
|
+
};
|
230
|
+
|
158
231
|
function planckToTokens(planck, tokenDecimals) {
|
159
232
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
160
233
|
const base = 10;
|
@@ -177,11 +250,17 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
177
250
|
return new BigNumber(tokens).multipliedBy(multiplier).toString(10);
|
178
251
|
}
|
179
252
|
|
253
|
+
const bitLength = 64;
|
254
|
+
function twox64Concat(input) {
|
255
|
+
const inputAsU8a = typeof input === "string" ? input : new Uint8Array(input);
|
256
|
+
return u8aToHex(u8aConcat(xxhashAsU8a(inputAsU8a, bitLength), u8aToU8a(inputAsU8a)));
|
257
|
+
}
|
258
|
+
|
180
259
|
/**
|
181
260
|
* @name validateHexString
|
182
261
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
183
262
|
* @param {string} str - string to check
|
184
|
-
* @returns {
|
263
|
+
* @returns {HexString} - boolean
|
185
264
|
* @example
|
186
265
|
* validateHexString("0x1234") // "0x1234"
|
187
266
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -197,6 +276,24 @@ const validateHexString = str => {
|
|
197
276
|
throw new Error("Expected a hex string");
|
198
277
|
};
|
199
278
|
|
279
|
+
const CACHE$1 = new Map();
|
280
|
+
|
281
|
+
// Normalize an address in a way that it can be compared to other addresses that have also been normalized
|
282
|
+
const normalizeAddress = address => {
|
283
|
+
try {
|
284
|
+
if (!CACHE$1.has(address)) CACHE$1.set(address, encodeAnyAddress(address));
|
285
|
+
return CACHE$1.get(address);
|
286
|
+
} catch (cause) {
|
287
|
+
throw new Error(`Unable to normalize address: ${address}`, {
|
288
|
+
cause
|
289
|
+
});
|
290
|
+
}
|
291
|
+
};
|
292
|
+
|
293
|
+
const isAddressEqual = (address1, address2) => {
|
294
|
+
return normalizeAddress(address1) === normalizeAddress(address2);
|
295
|
+
};
|
296
|
+
|
200
297
|
const isAscii = str => {
|
201
298
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
202
299
|
};
|
@@ -276,4 +373,4 @@ const keepSourceSubscribed = (observable, ms) => {
|
|
276
373
|
return () => setTimeout(() => sub.unsubscribe(), ms);
|
277
374
|
};
|
278
375
|
|
279
|
-
export { BigMath, Deferred, MAX_DECIMALS_FORMAT, addTrailingSlash, classNames,
|
376
|
+
export { BigMath, Deferred, MAX_DECIMALS_FORMAT, addTrailingSlash, blake2Concat, classNames, convertAddress, decodeAnyAddress, decodeSs58Format, encodeAnyAddress, firstThenDebounce, formatDecimals, formatPrice, getSharedObservable, hasOwnProperty, isAbortError, isAddressEqual, isArrayOf, isAscii, isBigInt, isBooleanTrue, isEthereumAddress, isNotNil, isTruthy, isValidSubstrateAddress, keepAlive, normalizeAddress, planckToTokens, sleep, throwAfter, tokensToPlanck, twox64Concat, validateHexString };
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@talismn/util",
|
3
|
-
"version": "0.0.0-
|
3
|
+
"version": "0.0.0-pr2092-20250715131755",
|
4
4
|
"author": "Talisman",
|
5
5
|
"homepage": "https://talisman.xyz",
|
6
6
|
"license": "GPL-3.0-or-later",
|
@@ -26,6 +26,9 @@
|
|
26
26
|
"tailwind-merge": "^2.5.4"
|
27
27
|
},
|
28
28
|
"devDependencies": {
|
29
|
+
"@polkadot/keyring": "13.5.1",
|
30
|
+
"@polkadot/util": "13.5.1",
|
31
|
+
"@polkadot/util-crypto": "13.5.1",
|
29
32
|
"@types/jest": "^29.5.14",
|
30
33
|
"eslint": "^8.57.1",
|
31
34
|
"jest": "^29.7.0",
|
@@ -35,6 +38,9 @@
|
|
35
38
|
"@talismn/tsconfig": "0.0.2"
|
36
39
|
},
|
37
40
|
"peerDependencies": {
|
41
|
+
"@polkadot/keyring": "*",
|
42
|
+
"@polkadot/util": "*",
|
43
|
+
"@polkadot/util-crypto": "*",
|
38
44
|
"rxjs": ">= 7.8.1"
|
39
45
|
},
|
40
46
|
"eslintConfig": {
|