@talismn/util 0.0.0-pr2080-20250710073919 → 0.0.0-pr2091-20250715125148
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/classNames.d.ts +1 -0
- package/dist/declarations/src/index.d.ts +1 -10
- package/dist/declarations/src/keepAlive.d.ts +17 -0
- package/dist/declarations/src/validateHexString.d.ts +2 -3
- package/dist/talismn-util.cjs.dev.js +38 -109
- package/dist/talismn-util.cjs.prod.js +38 -109
- package/dist/talismn-util.esm.js +38 -101
- package/package.json +1 -7
- package/dist/declarations/src/blake2Concat.d.ts +0 -1
- package/dist/declarations/src/convertAddress.d.ts +0 -7
- package/dist/declarations/src/decodeAnyAddress.d.ts +0 -1
- package/dist/declarations/src/decodeSs58Format.d.ts +0 -1
- package/dist/declarations/src/encodeAnyAddress.d.ts +0 -1
- package/dist/declarations/src/isAddressEqual.d.ts +0 -1
- package/dist/declarations/src/isEthereumAddress.d.ts +0 -1
- package/dist/declarations/src/isValidSubstrateAddress.d.ts +0 -7
- package/dist/declarations/src/normalizeAddress.d.ts +0 -1
- package/dist/declarations/src/twox64Concat.d.ts +0 -1
@@ -1,12 +1,7 @@
|
|
1
1
|
export * from "./addTrailingSlash";
|
2
2
|
export * from "./BigMath";
|
3
|
-
export * from "./blake2Concat";
|
4
3
|
export * from "./classNames";
|
5
|
-
export * from "./convertAddress";
|
6
|
-
export * from "./decodeAnyAddress";
|
7
|
-
export * from "./decodeSs58Format";
|
8
4
|
export * from "./deferred";
|
9
|
-
export * from "./encodeAnyAddress";
|
10
5
|
export * from "./firstThenDebounce";
|
11
6
|
export * from "./formatDecimals";
|
12
7
|
export * from "./formatPrice";
|
@@ -15,18 +10,14 @@ export * from "./hasOwnProperty";
|
|
15
10
|
export * from "./isArrayOf";
|
16
11
|
export * from "./isBigInt";
|
17
12
|
export * from "./isBooleanTrue";
|
18
|
-
export * from "./isEthereumAddress";
|
19
|
-
export * from "./isValidSubstrateAddress";
|
20
13
|
export * from "./planckToTokens";
|
21
14
|
export * from "./sleep";
|
22
15
|
export * from "./throwAfter";
|
23
16
|
export * from "./tokensToPlanck";
|
24
|
-
export * from "./twox64Concat";
|
25
17
|
export * from "./validateHexString";
|
26
|
-
export * from "./normalizeAddress";
|
27
|
-
export * from "./isAddressEqual";
|
28
18
|
export * from "./isAscii";
|
29
19
|
export * from "./isNotNil";
|
30
20
|
export * from "./isTruthy";
|
31
21
|
export * from "./isAbortError";
|
32
22
|
export * from "./getSharedObservable";
|
23
|
+
export * from "./keepAlive";
|
@@ -0,0 +1,17 @@
|
|
1
|
+
import type { OperatorFunction } from "rxjs";
|
2
|
+
/**
|
3
|
+
* An RxJS operator that keeps the source observable alive for a specified duration
|
4
|
+
* after all subscribers have unsubscribed. This prevents expensive re-subscriptions
|
5
|
+
* when subscribers come and go frequently.
|
6
|
+
*
|
7
|
+
* @param keepAliveMs - Duration in milliseconds to keep the source alive after last unsubscription
|
8
|
+
* @returns MonoTypeOperatorFunction that can be used in pipe()
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* ```typescript
|
12
|
+
* const data$ = expensive_api_call$.pipe(
|
13
|
+
* keepAlive(3000) // Keep alive for 3 seconds
|
14
|
+
* );
|
15
|
+
* ```
|
16
|
+
*/
|
17
|
+
export declare const keepAlive: <T>(timeout: number) => OperatorFunction<T, T>;
|
@@ -1,12 +1,11 @@
|
|
1
|
-
import { HexString } from "@polkadot/util/types";
|
2
1
|
/**
|
3
2
|
* @name validateHexString
|
4
3
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
5
4
|
* @param {string} str - string to check
|
6
|
-
* @returns {
|
5
|
+
* @returns {`0x${string}`} - boolean
|
7
6
|
* @example
|
8
7
|
* validateHexString("0x1234") // "0x1234"
|
9
8
|
* validateHexString("1234") // Error: Expected a hex string
|
10
9
|
* validateHexString(1234) // Error: Expected a string
|
11
10
|
**/
|
12
|
-
export declare const validateHexString: (str: string) =>
|
11
|
+
export declare const validateHexString: (str: string) => `0x${string}`;
|
@@ -1,9 +1,6 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var util = require('@polkadot/util');
|
4
|
-
var utilCrypto = require('@polkadot/util-crypto');
|
5
3
|
var tailwindMerge = require('tailwind-merge');
|
6
|
-
var keyring = require('@polkadot/keyring');
|
7
4
|
var rxjs = require('rxjs');
|
8
5
|
var BigNumber = require('bignumber.js');
|
9
6
|
|
@@ -45,54 +42,8 @@ const BigMath = {
|
|
45
42
|
}
|
46
43
|
};
|
47
44
|
|
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
|
-
|
53
45
|
const classNames = tailwindMerge.twMerge;
|
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
|
-
};
|
46
|
+
const cn = tailwindMerge.twMerge;
|
96
47
|
|
97
48
|
/**
|
98
49
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -210,30 +161,6 @@ const isBigInt = value => typeof value === "bigint";
|
|
210
161
|
|
211
162
|
const isBooleanTrue = x => !!x;
|
212
163
|
|
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
|
-
|
237
164
|
function planckToTokens(planck, tokenDecimals) {
|
238
165
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
239
166
|
const base = 10;
|
@@ -256,17 +183,11 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
256
183
|
return new BigNumber__default.default(tokens).multipliedBy(multiplier).toString(10);
|
257
184
|
}
|
258
185
|
|
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
|
-
|
265
186
|
/**
|
266
187
|
* @name validateHexString
|
267
188
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
268
189
|
* @param {string} str - string to check
|
269
|
-
* @returns {
|
190
|
+
* @returns {`0x${string}`} - boolean
|
270
191
|
* @example
|
271
192
|
* validateHexString("0x1234") // "0x1234"
|
272
193
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -282,24 +203,6 @@ const validateHexString = str => {
|
|
282
203
|
throw new Error("Expected a hex string");
|
283
204
|
};
|
284
205
|
|
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
|
-
|
303
206
|
const isAscii = str => {
|
304
207
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
305
208
|
};
|
@@ -345,35 +248,61 @@ const getSharedObservable = (namespace, args, createObservable, serializer = arg
|
|
345
248
|
return sharedObs;
|
346
249
|
};
|
347
250
|
|
251
|
+
/**
|
252
|
+
* An RxJS operator that keeps the source observable alive for a specified duration
|
253
|
+
* after all subscribers have unsubscribed. This prevents expensive re-subscriptions
|
254
|
+
* when subscribers come and go frequently.
|
255
|
+
*
|
256
|
+
* @param keepAliveMs - Duration in milliseconds to keep the source alive after last unsubscription
|
257
|
+
* @returns MonoTypeOperatorFunction that can be used in pipe()
|
258
|
+
*
|
259
|
+
* @example
|
260
|
+
* ```typescript
|
261
|
+
* const data$ = expensive_api_call$.pipe(
|
262
|
+
* keepAlive(3000) // Keep alive for 3 seconds
|
263
|
+
* );
|
264
|
+
* ```
|
265
|
+
*/
|
266
|
+
const keepAlive = timeout => {
|
267
|
+
let release;
|
268
|
+
return source => source.pipe(rxjs.tap({
|
269
|
+
subscribe: () => {
|
270
|
+
release = keepSourceSubscribed(source, timeout);
|
271
|
+
},
|
272
|
+
unsubscribe: () => {
|
273
|
+
release?.();
|
274
|
+
}
|
275
|
+
}), rxjs.shareReplay({
|
276
|
+
refCount: true,
|
277
|
+
bufferSize: 1
|
278
|
+
}));
|
279
|
+
};
|
280
|
+
const keepSourceSubscribed = (observable, ms) => {
|
281
|
+
const sub = observable.subscribe();
|
282
|
+
return () => setTimeout(() => sub.unsubscribe(), ms);
|
283
|
+
};
|
284
|
+
|
348
285
|
exports.BigMath = BigMath;
|
349
286
|
exports.Deferred = Deferred;
|
350
287
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
351
288
|
exports.addTrailingSlash = addTrailingSlash;
|
352
|
-
exports.blake2Concat = blake2Concat;
|
353
289
|
exports.classNames = classNames;
|
354
|
-
exports.
|
355
|
-
exports.decodeAnyAddress = decodeAnyAddress;
|
356
|
-
exports.decodeSs58Format = decodeSs58Format;
|
357
|
-
exports.encodeAnyAddress = encodeAnyAddress;
|
290
|
+
exports.cn = cn;
|
358
291
|
exports.firstThenDebounce = firstThenDebounce;
|
359
292
|
exports.formatDecimals = formatDecimals;
|
360
293
|
exports.formatPrice = formatPrice;
|
361
294
|
exports.getSharedObservable = getSharedObservable;
|
362
295
|
exports.hasOwnProperty = hasOwnProperty;
|
363
296
|
exports.isAbortError = isAbortError;
|
364
|
-
exports.isAddressEqual = isAddressEqual;
|
365
297
|
exports.isArrayOf = isArrayOf;
|
366
298
|
exports.isAscii = isAscii;
|
367
299
|
exports.isBigInt = isBigInt;
|
368
300
|
exports.isBooleanTrue = isBooleanTrue;
|
369
|
-
exports.isEthereumAddress = isEthereumAddress;
|
370
301
|
exports.isNotNil = isNotNil;
|
371
302
|
exports.isTruthy = isTruthy;
|
372
|
-
exports.
|
373
|
-
exports.normalizeAddress = normalizeAddress;
|
303
|
+
exports.keepAlive = keepAlive;
|
374
304
|
exports.planckToTokens = planckToTokens;
|
375
305
|
exports.sleep = sleep;
|
376
306
|
exports.throwAfter = throwAfter;
|
377
307
|
exports.tokensToPlanck = tokensToPlanck;
|
378
|
-
exports.twox64Concat = twox64Concat;
|
379
308
|
exports.validateHexString = validateHexString;
|
@@ -1,9 +1,6 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
-
var util = require('@polkadot/util');
|
4
|
-
var utilCrypto = require('@polkadot/util-crypto');
|
5
3
|
var tailwindMerge = require('tailwind-merge');
|
6
|
-
var keyring = require('@polkadot/keyring');
|
7
4
|
var rxjs = require('rxjs');
|
8
5
|
var BigNumber = require('bignumber.js');
|
9
6
|
|
@@ -45,54 +42,8 @@ const BigMath = {
|
|
45
42
|
}
|
46
43
|
};
|
47
44
|
|
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
|
-
|
53
45
|
const classNames = tailwindMerge.twMerge;
|
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
|
-
};
|
46
|
+
const cn = tailwindMerge.twMerge;
|
96
47
|
|
97
48
|
/**
|
98
49
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -210,30 +161,6 @@ const isBigInt = value => typeof value === "bigint";
|
|
210
161
|
|
211
162
|
const isBooleanTrue = x => !!x;
|
212
163
|
|
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
|
-
|
237
164
|
function planckToTokens(planck, tokenDecimals) {
|
238
165
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
239
166
|
const base = 10;
|
@@ -256,17 +183,11 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
256
183
|
return new BigNumber__default.default(tokens).multipliedBy(multiplier).toString(10);
|
257
184
|
}
|
258
185
|
|
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
|
-
|
265
186
|
/**
|
266
187
|
* @name validateHexString
|
267
188
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
268
189
|
* @param {string} str - string to check
|
269
|
-
* @returns {
|
190
|
+
* @returns {`0x${string}`} - boolean
|
270
191
|
* @example
|
271
192
|
* validateHexString("0x1234") // "0x1234"
|
272
193
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -282,24 +203,6 @@ const validateHexString = str => {
|
|
282
203
|
throw new Error("Expected a hex string");
|
283
204
|
};
|
284
205
|
|
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
|
-
|
303
206
|
const isAscii = str => {
|
304
207
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
305
208
|
};
|
@@ -345,35 +248,61 @@ const getSharedObservable = (namespace, args, createObservable, serializer = arg
|
|
345
248
|
return sharedObs;
|
346
249
|
};
|
347
250
|
|
251
|
+
/**
|
252
|
+
* An RxJS operator that keeps the source observable alive for a specified duration
|
253
|
+
* after all subscribers have unsubscribed. This prevents expensive re-subscriptions
|
254
|
+
* when subscribers come and go frequently.
|
255
|
+
*
|
256
|
+
* @param keepAliveMs - Duration in milliseconds to keep the source alive after last unsubscription
|
257
|
+
* @returns MonoTypeOperatorFunction that can be used in pipe()
|
258
|
+
*
|
259
|
+
* @example
|
260
|
+
* ```typescript
|
261
|
+
* const data$ = expensive_api_call$.pipe(
|
262
|
+
* keepAlive(3000) // Keep alive for 3 seconds
|
263
|
+
* );
|
264
|
+
* ```
|
265
|
+
*/
|
266
|
+
const keepAlive = timeout => {
|
267
|
+
let release;
|
268
|
+
return source => source.pipe(rxjs.tap({
|
269
|
+
subscribe: () => {
|
270
|
+
release = keepSourceSubscribed(source, timeout);
|
271
|
+
},
|
272
|
+
unsubscribe: () => {
|
273
|
+
release?.();
|
274
|
+
}
|
275
|
+
}), rxjs.shareReplay({
|
276
|
+
refCount: true,
|
277
|
+
bufferSize: 1
|
278
|
+
}));
|
279
|
+
};
|
280
|
+
const keepSourceSubscribed = (observable, ms) => {
|
281
|
+
const sub = observable.subscribe();
|
282
|
+
return () => setTimeout(() => sub.unsubscribe(), ms);
|
283
|
+
};
|
284
|
+
|
348
285
|
exports.BigMath = BigMath;
|
349
286
|
exports.Deferred = Deferred;
|
350
287
|
exports.MAX_DECIMALS_FORMAT = MAX_DECIMALS_FORMAT;
|
351
288
|
exports.addTrailingSlash = addTrailingSlash;
|
352
|
-
exports.blake2Concat = blake2Concat;
|
353
289
|
exports.classNames = classNames;
|
354
|
-
exports.
|
355
|
-
exports.decodeAnyAddress = decodeAnyAddress;
|
356
|
-
exports.decodeSs58Format = decodeSs58Format;
|
357
|
-
exports.encodeAnyAddress = encodeAnyAddress;
|
290
|
+
exports.cn = cn;
|
358
291
|
exports.firstThenDebounce = firstThenDebounce;
|
359
292
|
exports.formatDecimals = formatDecimals;
|
360
293
|
exports.formatPrice = formatPrice;
|
361
294
|
exports.getSharedObservable = getSharedObservable;
|
362
295
|
exports.hasOwnProperty = hasOwnProperty;
|
363
296
|
exports.isAbortError = isAbortError;
|
364
|
-
exports.isAddressEqual = isAddressEqual;
|
365
297
|
exports.isArrayOf = isArrayOf;
|
366
298
|
exports.isAscii = isAscii;
|
367
299
|
exports.isBigInt = isBigInt;
|
368
300
|
exports.isBooleanTrue = isBooleanTrue;
|
369
|
-
exports.isEthereumAddress = isEthereumAddress;
|
370
301
|
exports.isNotNil = isNotNil;
|
371
302
|
exports.isTruthy = isTruthy;
|
372
|
-
exports.
|
373
|
-
exports.normalizeAddress = normalizeAddress;
|
303
|
+
exports.keepAlive = keepAlive;
|
374
304
|
exports.planckToTokens = planckToTokens;
|
375
305
|
exports.sleep = sleep;
|
376
306
|
exports.throwAfter = throwAfter;
|
377
307
|
exports.tokensToPlanck = tokensToPlanck;
|
378
|
-
exports.twox64Concat = twox64Concat;
|
379
308
|
exports.validateHexString = validateHexString;
|
package/dist/talismn-util.esm.js
CHANGED
@@ -1,8 +1,5 @@
|
|
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';
|
3
1
|
import { twMerge } from 'tailwind-merge';
|
4
|
-
import {
|
5
|
-
import { concat, take, skip, debounceTime, shareReplay } from 'rxjs';
|
2
|
+
import { concat, take, skip, debounceTime, shareReplay, tap } from 'rxjs';
|
6
3
|
import BigNumber from 'bignumber.js';
|
7
4
|
|
8
5
|
const addTrailingSlash = url => {
|
@@ -39,54 +36,8 @@ const BigMath = {
|
|
39
36
|
}
|
40
37
|
};
|
41
38
|
|
42
|
-
const bitLength$1 = 128;
|
43
|
-
function blake2Concat(input) {
|
44
|
-
return u8aToHex(u8aConcat(blake2AsU8a(input, bitLength$1), u8aToU8a(input)));
|
45
|
-
}
|
46
|
-
|
47
39
|
const classNames = twMerge;
|
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
|
-
};
|
40
|
+
const cn = twMerge;
|
90
41
|
|
91
42
|
/**
|
92
43
|
* In TypeScript, a deferred promise refers to a pattern that involves creating a promise that can be
|
@@ -204,30 +155,6 @@ const isBigInt = value => typeof value === "bigint";
|
|
204
155
|
|
205
156
|
const isBooleanTrue = x => !!x;
|
206
157
|
|
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
|
-
|
231
158
|
function planckToTokens(planck, tokenDecimals) {
|
232
159
|
if (typeof planck !== "string" || typeof tokenDecimals !== "number") return;
|
233
160
|
const base = 10;
|
@@ -250,17 +177,11 @@ function tokensToPlanck(tokens, tokenDecimals) {
|
|
250
177
|
return new BigNumber(tokens).multipliedBy(multiplier).toString(10);
|
251
178
|
}
|
252
179
|
|
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
|
-
|
259
180
|
/**
|
260
181
|
* @name validateHexString
|
261
182
|
* @description Checks if a string is a hex string. Required to account for type differences between different polkadot libraries
|
262
183
|
* @param {string} str - string to check
|
263
|
-
* @returns {
|
184
|
+
* @returns {`0x${string}`} - boolean
|
264
185
|
* @example
|
265
186
|
* validateHexString("0x1234") // "0x1234"
|
266
187
|
* validateHexString("1234") // Error: Expected a hex string
|
@@ -276,24 +197,6 @@ const validateHexString = str => {
|
|
276
197
|
throw new Error("Expected a hex string");
|
277
198
|
};
|
278
199
|
|
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
|
-
|
297
200
|
const isAscii = str => {
|
298
201
|
return [...str].every(char => char.charCodeAt(0) <= 127);
|
299
202
|
};
|
@@ -339,4 +242,38 @@ const getSharedObservable = (namespace, args, createObservable, serializer = arg
|
|
339
242
|
return sharedObs;
|
340
243
|
};
|
341
244
|
|
342
|
-
|
245
|
+
/**
|
246
|
+
* An RxJS operator that keeps the source observable alive for a specified duration
|
247
|
+
* after all subscribers have unsubscribed. This prevents expensive re-subscriptions
|
248
|
+
* when subscribers come and go frequently.
|
249
|
+
*
|
250
|
+
* @param keepAliveMs - Duration in milliseconds to keep the source alive after last unsubscription
|
251
|
+
* @returns MonoTypeOperatorFunction that can be used in pipe()
|
252
|
+
*
|
253
|
+
* @example
|
254
|
+
* ```typescript
|
255
|
+
* const data$ = expensive_api_call$.pipe(
|
256
|
+
* keepAlive(3000) // Keep alive for 3 seconds
|
257
|
+
* );
|
258
|
+
* ```
|
259
|
+
*/
|
260
|
+
const keepAlive = timeout => {
|
261
|
+
let release;
|
262
|
+
return source => source.pipe(tap({
|
263
|
+
subscribe: () => {
|
264
|
+
release = keepSourceSubscribed(source, timeout);
|
265
|
+
},
|
266
|
+
unsubscribe: () => {
|
267
|
+
release?.();
|
268
|
+
}
|
269
|
+
}), shareReplay({
|
270
|
+
refCount: true,
|
271
|
+
bufferSize: 1
|
272
|
+
}));
|
273
|
+
};
|
274
|
+
const keepSourceSubscribed = (observable, ms) => {
|
275
|
+
const sub = observable.subscribe();
|
276
|
+
return () => setTimeout(() => sub.unsubscribe(), ms);
|
277
|
+
};
|
278
|
+
|
279
|
+
export { BigMath, Deferred, MAX_DECIMALS_FORMAT, addTrailingSlash, classNames, cn, firstThenDebounce, formatDecimals, formatPrice, getSharedObservable, hasOwnProperty, isAbortError, isArrayOf, isAscii, isBigInt, isBooleanTrue, isNotNil, isTruthy, keepAlive, planckToTokens, sleep, throwAfter, tokensToPlanck, 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-pr2091-20250715125148",
|
4
4
|
"author": "Talisman",
|
5
5
|
"homepage": "https://talisman.xyz",
|
6
6
|
"license": "GPL-3.0-or-later",
|
@@ -26,9 +26,6 @@
|
|
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",
|
32
29
|
"@types/jest": "^29.5.14",
|
33
30
|
"eslint": "^8.57.1",
|
34
31
|
"jest": "^29.7.0",
|
@@ -38,9 +35,6 @@
|
|
38
35
|
"@talismn/tsconfig": "0.0.2"
|
39
36
|
},
|
40
37
|
"peerDependencies": {
|
41
|
-
"@polkadot/keyring": "*",
|
42
|
-
"@polkadot/util": "*",
|
43
|
-
"@polkadot/util-crypto": "*",
|
44
38
|
"rxjs": ">= 7.8.1"
|
45
39
|
},
|
46
40
|
"eslintConfig": {
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare function blake2Concat(input: Uint8Array): `0x${string}`;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare function decodeAnyAddress(encoded?: string | Uint8Array | null | undefined, ignoreChecksum?: boolean | undefined, ss58Format?: number | undefined): Uint8Array;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare const decodeSs58Format: (address?: string) => number | undefined;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare function encodeAnyAddress(key: string | Uint8Array, ss58Format?: number | undefined): string;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare const isAddressEqual: (address1: string, address2: string) => boolean;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare const isEthereumAddress: (address: string | undefined | null) => address is `0x${string}`;
|
@@ -1,7 +0,0 @@
|
|
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;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare const normalizeAddress: (address: string) => string;
|
@@ -1 +0,0 @@
|
|
1
|
-
export declare function twox64Concat(input: string | Buffer | Uint8Array): `0x${string}`;
|