@talismn/balances 0.8.2 → 0.9.1

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.
@@ -4,10 +4,10 @@ import { toHex, decodeMetadata, getDynamicBuilder, getLookupFn, compactMetadata,
4
4
  import { Dexie, liveQuery } from 'dexie';
5
5
  import isEqual from 'lodash/isEqual';
6
6
  import { from, Observable, scan, share, map, switchAll, combineLatest, mergeMap, toArray, interval, startWith, exhaustMap, pipe, filter, shareReplay, combineLatestWith, distinctUntilChanged, firstValueFrom, BehaviorSubject, debounceTime, takeUntil, switchMap, withLatestFrom, concatMap } from 'rxjs';
7
- import { u32, Option, Bytes, u128, Struct, compact, bool, Vector } from 'scale-ts';
7
+ import { u32, Option, Bytes, u128, Struct } from 'scale-ts';
8
8
  import anylogger from 'anylogger';
9
9
  import { newTokenRates } from '@talismn/token-rates';
10
- import { BigMath, isArrayOf, isBigInt, planckToTokens, isEthereumAddress, hasOwnProperty, decodeAnyAddress, blake2Concat, firstThenDebounce, Deferred } from '@talismn/util';
10
+ import { isBigInt, BigMath, planckToTokens, isTruthy, isArrayOf, isEthereumAddress, hasOwnProperty, decodeAnyAddress, isNotNil, blake2Concat, firstThenDebounce, Deferred } from '@talismn/util';
11
11
  import BigNumber from 'bignumber.js';
12
12
  import { u8aToHex, assert, stringCamelCase, u8aConcatStrict, u8aConcat, arrayChunk, u8aToString, hexToNumber, hexToU8a } from '@polkadot/util';
13
13
  import { xxhashAsU8a, blake2AsU8a } from '@polkadot/util-crypto';
@@ -20,6 +20,7 @@ import groupBy from 'lodash/groupBy';
20
20
  import { mergeUint8, toHex as toHex$1 } from '@polkadot-api/utils';
21
21
  import { Binary, AccountId } from 'polkadot-api';
22
22
  import { ChainConnectionError } from '@talismn/chain-connector';
23
+ import { getScaleApi } from '@talismn/sapi';
23
24
  import upperFirst from 'lodash/upperFirst';
24
25
  import { Abi } from '@polkadot/api-contract';
25
26
 
@@ -95,88 +96,7 @@ class EvmTokenFetcher {
95
96
  }
96
97
 
97
98
  var packageJson = {
98
- name: "@talismn/balances",
99
- version: "0.8.2",
100
- author: "Talisman",
101
- homepage: "https://talisman.xyz",
102
- license: "GPL-3.0-or-later",
103
- publishConfig: {
104
- access: "public"
105
- },
106
- repository: {
107
- directory: "packages/balances",
108
- type: "git",
109
- url: "https://github.com/talismansociety/talisman.git"
110
- },
111
- main: "dist/talismn-balances.cjs.js",
112
- module: "dist/talismn-balances.esm.js",
113
- files: [
114
- "/dist",
115
- "/plugins"
116
- ],
117
- engines: {
118
- node: ">=18"
119
- },
120
- scripts: {
121
- test: "jest",
122
- lint: "eslint src --max-warnings 0",
123
- clean: "rm -rf dist plugins/dist .turbo node_modules"
124
- },
125
- dependencies: {
126
- "@polkadot-api/utils": "^0.1.2",
127
- "@supercharge/promise-pool": "^3.2.0",
128
- "@talismn/chain-connector": "workspace:*",
129
- "@talismn/chain-connector-evm": "workspace:*",
130
- "@talismn/chaindata-provider": "workspace:*",
131
- "@talismn/scale": "workspace:*",
132
- "@talismn/token-rates": "workspace:*",
133
- "@talismn/util": "workspace:*",
134
- anylogger: "^1.0.11",
135
- "bignumber.js": "^9.1.2",
136
- dexie: "^4.0.9",
137
- lodash: "4.17.21",
138
- pako: "^2.1.0",
139
- "polkadot-api": "1.7.6",
140
- rxjs: "^7.8.1",
141
- "scale-ts": "^1.6.1",
142
- viem: "^2.21.34"
143
- },
144
- devDependencies: {
145
- "@polkadot/api-contract": "15.8.1",
146
- "@polkadot/types": "15.8.1",
147
- "@polkadot/util": "13.4.3",
148
- "@polkadot/util-crypto": "13.4.3",
149
- "@substrate/txwrapper-core": "7.5.3",
150
- "@talismn/eslint-config": "workspace:*",
151
- "@talismn/tsconfig": "workspace:*",
152
- "@types/jest": "^29.5.14",
153
- "@types/lodash": "^4.17.12",
154
- "@types/pako": "^2.0.3",
155
- eslint: "^8.57.1",
156
- jest: "^29.7.0",
157
- "ts-jest": "^29.2.5",
158
- typescript: "^5.6.3"
159
- },
160
- peerDependencies: {
161
- "@polkadot/api-contract": "*",
162
- "@polkadot/types": "*",
163
- "@polkadot/util": "*",
164
- "@polkadot/util-crypto": "*",
165
- "@substrate/txwrapper-core": "*"
166
- },
167
- preconstruct: {
168
- entrypoints: [
169
- "index.ts",
170
- "plugins.ts"
171
- ]
172
- },
173
- eslintConfig: {
174
- root: true,
175
- "extends": [
176
- "@talismn/eslint-config/base"
177
- ]
178
- }
179
- };
99
+ name: "@talismn/balances"};
180
100
 
181
101
  var log = anylogger(packageJson.name);
182
102
 
@@ -362,13 +282,9 @@ class Balances {
362
282
  return [...this];
363
283
  }
364
284
 
365
- /**
366
- * Get an array of balances in this collection, sorted by chain sortIndex.
367
- *
368
- * @returns A sorted array of the balances in this collection.
369
- */
285
+ /** @deprecated use each instead */
370
286
  get sorted() {
371
- return [...this].sort((a, b) => ((a.chain || a.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER) - ((b.chain || b.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER));
287
+ return this.each;
372
288
  }
373
289
 
374
290
  /**
@@ -400,7 +316,7 @@ const getBalanceId = balance => {
400
316
  tokenId
401
317
  } = balance;
402
318
  const locationId = isBalanceEvm(balance) ? balance.evmNetworkId : balance.chainId;
403
- return [source, address, locationId, tokenId].filter(Boolean).join("::");
319
+ return [source, address, locationId, tokenId].filter(isTruthy).join("::");
404
320
  };
405
321
 
406
322
  /**
@@ -1042,7 +958,7 @@ const upgradeBalancesDataBlob = async tx => {
1042
958
  ...stuffToKeep
1043
959
  } = balance;
1044
960
  return stuffToKeep;
1045
- }).filter(Boolean);
961
+ }).filter(isTruthy);
1046
962
  const output = pako.deflate(JSON.stringify(migratedData));
1047
963
  // now write the compressed data back to the db and clear the old one
1048
964
  await tx.table("balancesBlob").put({
@@ -1783,7 +1699,7 @@ const fetchBalances$3 = async (evmChainConnector, tokenAddressesByNetwork, erc20
1783
1699
  const balances = await getEvmTokenBalances(publicClient, networkParams, result.errors, erc20Aggregators[evmNetworkId]);
1784
1700
 
1785
1701
  // consider only non null balances in the results
1786
- result.results.push(...balances.filter(Boolean).map((free, i) => ({
1702
+ result.results.push(...balances.filter(isTruthy).map((free, i) => ({
1787
1703
  source: "evm-erc20",
1788
1704
  status: "live",
1789
1705
  address: networkParams[i].address,
@@ -3296,7 +3212,7 @@ const SubAssetsModule = hydrate => {
3296
3212
  const assetStateKey = tryEncode(assetCoder, BigInt(assetId)) ?? tryEncode(assetCoder, assetId);
3297
3213
  const metadataStateKey = tryEncode(metadataCoder, BigInt(assetId)) ?? tryEncode(metadataCoder, assetId);
3298
3214
  if (assetStateKey === null || metadataStateKey === null) throw new Error(`Failed to encode stateKey for asset ${assetId} on chain ${chainId}`);
3299
- const [assetsAsset, assetsMetadata] = await Promise.all([chainConnector.send(chainId, "state_getStorage", [assetStateKey]).then(result => assetCoder.dec(result) ?? null), chainConnector.send(chainId, "state_getStorage", [metadataStateKey]).then(result => metadataCoder.dec(result) ?? null)]);
3215
+ const [assetsAsset, assetsMetadata] = await Promise.all([chainConnector.send(chainId, "state_getStorage", [assetStateKey]).then(result => assetCoder.value.dec(result) ?? null), chainConnector.send(chainId, "state_getStorage", [metadataStateKey]).then(result => metadataCoder.value.dec(result) ?? null)]);
3300
3216
  const existentialDeposit = assetsAsset?.min_balance?.toString?.() ?? "0";
3301
3217
  const symbol = assetsMetadata?.symbol?.asText?.() ?? "Unit";
3302
3218
  const decimals = assetsMetadata?.decimals ?? 0;
@@ -3463,15 +3379,9 @@ async function buildQueries$4(chaindataProvider, addressesByToken) {
3463
3379
 
3464
3380
  const decoded = decodeScale(scaleCoder, change, `Failed to decode substrate-assets balance on chain ${chainId}`) ?? {
3465
3381
  balance: 0n,
3466
- is_frozen: false,
3467
- reason: {
3468
- type: "Sufficient"
3469
- },
3470
3382
  status: {
3471
3383
  type: "Liquid"
3472
- },
3473
- extra: undefined
3474
- };
3384
+ }};
3475
3385
  const isFrozen = decoded?.status?.type === "Frozen";
3476
3386
  const amount = (decoded?.balance ?? 0n).toString();
3477
3387
 
@@ -3523,7 +3433,7 @@ async function buildQueries$4(chaindataProvider, addressesByToken) {
3523
3433
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3524
3434
  const tryEncode = (scaleCoder, ...args) => {
3525
3435
  try {
3526
- return scaleCoder?.enc?.(...args);
3436
+ return scaleCoder?.keys?.enc?.(...args);
3527
3437
  } catch {
3528
3438
  return null;
3529
3439
  }
@@ -3594,11 +3504,11 @@ const SubEquilibriumModule = hydrate => {
3594
3504
  try {
3595
3505
  const scaleBuilder = getDynamicBuilder(getLookupFn(metadata));
3596
3506
  const assetsCoder = scaleBuilder.buildStorage("EqAssets", "Assets");
3597
- const stateKey = assetsCoder.enc();
3507
+ const stateKey = assetsCoder.keys.enc();
3598
3508
 
3599
3509
  /** NOTE: Just a guideline, the RPC can return whatever it wants */
3600
3510
 
3601
- const assetsResult = await chainConnector.send(chainId, "state_getStorage", [stateKey]).then(result => assetsCoder.dec(result) ?? null);
3511
+ const assetsResult = await chainConnector.send(chainId, "state_getStorage", [stateKey]).then(result => assetsCoder.value.dec(result) ?? null);
3602
3512
  const tokens = (Array.isArray(assetsResult) ? assetsResult : []).flatMap(asset => {
3603
3513
  if (!asset) return [];
3604
3514
  if (!asset?.id) return [];
@@ -3883,9 +3793,9 @@ const SubForeignAssetsModule = hydrate => {
3883
3793
  }
3884
3794
  })();
3885
3795
  if (onChainId === undefined) continue;
3886
- const assetStateKey = assetCoder.enc(onChainId);
3887
- const metadataStateKey = metadataCoder.enc(onChainId);
3888
- const [assetsAsset, assetsMetadata] = await Promise.all([chainConnector.send(chainId, "state_getStorage", [assetStateKey]).then(result => assetCoder.dec(result) ?? null), chainConnector.send(chainId, "state_getStorage", [metadataStateKey]).then(result => metadataCoder.dec(result) ?? null)]);
3796
+ const assetStateKey = assetCoder.keys.enc(onChainId);
3797
+ const metadataStateKey = metadataCoder.keys.enc(onChainId);
3798
+ const [assetsAsset, assetsMetadata] = await Promise.all([chainConnector.send(chainId, "state_getStorage", [assetStateKey]).then(result => assetCoder.value.dec(result) ?? null), chainConnector.send(chainId, "state_getStorage", [metadataStateKey]).then(result => metadataCoder.value.dec(result) ?? null)]);
3889
3799
  const existentialDeposit = assetsAsset?.min_balance?.toString?.() ?? "0";
3890
3800
  const symbol = assetsMetadata?.symbol?.asText?.() ?? "Unit";
3891
3801
  const decimals = assetsMetadata?.decimals ?? 0;
@@ -4045,15 +3955,9 @@ async function buildQueries$2(chaindataProvider, addressesByToken) {
4045
3955
 
4046
3956
  const decoded = decodeScale(scaleCoder, change, `Failed to decode substrate-foreignassets balance on chain ${chainId}`) ?? {
4047
3957
  balance: 0n,
4048
- is_frozen: false,
4049
- reason: {
4050
- type: "Sufficient"
4051
- },
4052
3958
  status: {
4053
3959
  type: "Liquid"
4054
- },
4055
- extra: undefined
4056
- };
3960
+ }};
4057
3961
  const isFrozen = decoded?.status?.type === "Frozen";
4058
3962
  const amount = (decoded?.balance ?? 0n).toString();
4059
3963
 
@@ -4116,7 +4020,7 @@ async function subscribeBase(queries, chainConnector, callback) {
4116
4020
  * <TArgs, TResult>(...arguments: TArgs, callback: SubscriptionCallback<TResult>) => UnsubscribeFn
4117
4021
  */
4118
4022
  const asObservable = handler => (...args) => new Observable(subscriber => {
4119
- const callback = (error, result) => error ? subscriber.error(error) : subscriber.next(result);
4023
+ const callback = (error, result) => error || result === undefined ? subscriber.error(error) : subscriber.next(result);
4120
4024
  const unsubscribe = handler(...args, callback);
4121
4025
  return unsubscribe;
4122
4026
  });
@@ -4662,7 +4566,7 @@ async function subscribeNompoolStaking(chaindataProvider, chainConnector, addres
4662
4566
  }
4663
4567
  }]
4664
4568
  };
4665
- }).filter(Boolean);
4569
+ }).filter(isNotNil);
4666
4570
  if (balances.length > 0) callback(null, balances);
4667
4571
  },
4668
4572
  error: error => callback(error)
@@ -4677,113 +4581,17 @@ const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK = 1000000n;
4677
4581
  const TAO_DECIMALS = 9n;
4678
4582
  const SCALE_FACTOR = 10n ** TAO_DECIMALS; // Equivalent to 10e9 for precision
4679
4583
  const ONE_ALPHA_TOKEN = SCALE_FACTOR;
4680
- const BITTENSOR_TESTNET_CHAIN_ID = "bittensor-testnet";
4681
- const BittensorAccountPrefix = 42;
4682
- const BittensorAccountId = AccountId(BittensorAccountPrefix);
4683
-
4684
- /** For encoding/decoding the GetStakeInfoForColdkey runtime api *after* they added the netuid parameter */
4685
- const StakeInfo = Struct({
4686
- hotkey: BittensorAccountId,
4687
- coldkey: BittensorAccountId,
4688
- netuid: compact,
4689
- stake: compact,
4690
- locked: compact,
4691
- emission: compact,
4692
- tao_emission: compact,
4693
- drain: compact,
4694
- isRegistered: bool
4695
- });
4696
- const EncodeParams_GetStakeInfoForColdkey = address => toHex$1(BittensorAccountId.enc(address));
4697
- const DecodeResult_GetStakeInfoForColdkey = result => Vector(StakeInfo).dec(result);
4698
- /** Encoding/decoding for GetStakeDynamicInfo */
4699
- const EncodeParams_GetDynamicInfo = netuid => {
4700
- if (netuid < 0 || netuid > 65535) {
4701
- throw new Error("netuid must be a valid u16 (0-65535)");
4702
- }
4703
-
4704
- // Convert the number to a Uint8Array (LE encoding)
4705
- const encoded = new Uint8Array(2);
4706
- encoded[0] = netuid & 0xff; // Lower byte
4707
- encoded[1] = netuid >> 8 & 0xff; // Upper byte
4708
-
4709
- // Convert to hex string
4710
- return toHex$1(encoded);
4711
- };
4712
- /** I96F32 representation (Fixed-Point) */
4713
- const I96F32 = Struct({
4714
- bits: compact
4715
- });
4716
- const SubnetIdentityV2 = Struct({
4717
- subnetName: Bytes(),
4718
- githubRepo: Bytes(),
4719
- subnetContact: Bytes(),
4720
- subnetUrl: Bytes(),
4721
- discord: Bytes(),
4722
- description: Bytes()
4723
- });
4724
- const DynamicInfo = Struct({
4725
- netuid: compact,
4726
- ownerHotkey: BittensorAccountId,
4727
- ownerColdkey: BittensorAccountId,
4728
- subnetName: Vector(compact),
4729
- tokenSymbol: Vector(compact),
4730
- tempo: compact,
4731
- lastStep: compact,
4732
- blocksSinceLastStep: compact,
4733
- emission: compact,
4734
- alphaIn: compact,
4735
- alphaOut: compact,
4736
- taoIn: compact,
4737
- alphaOutEmission: compact,
4738
- alphaInEmission: compact,
4739
- taoInEmission: compact,
4740
- pendingAlphaEmission: compact,
4741
- pendingRootEmission: compact,
4742
- subnetVolume: compact,
4743
- networkRegisteredAt: compact,
4744
- subnetIdentity: Option(SubnetIdentityV2),
4745
- movingPrice: I96F32
4746
- });
4747
- const DecodeResult_GetDynamicInfo = result => {
4748
- const LITTLE_ENDIAN_OFFSET = 256;
4749
- const decoded = DynamicInfo.dec(result);
4750
- const {
4751
- netuid: netuidLittleEndian,
4752
- subnetIdentity: subnetIdentityScaleOption = {},
4753
- tokenSymbol: tokenSymbolU8Arr,
4754
- taoIn,
4755
- alphaIn,
4756
- subnetName: subnetNameVector
4757
- } = decoded;
4758
- const netuid = Number(netuidLittleEndian) / LITTLE_ENDIAN_OFFSET;
4759
- const tokenSymbol = new TextDecoder().decode(Uint8Array.from(tokenSymbolU8Arr.map(val => Number(val))));
4760
- const subnetName = new TextDecoder().decode(Uint8Array.from(subnetNameVector.map(val => Number(val))));
4761
- const subnetIdentity = Object.keys(subnetIdentityScaleOption).reduce((acc, key) => {
4762
- const value = subnetIdentityScaleOption[key];
4763
- acc[key] = new TextDecoder().decode(value);
4764
- return acc;
4765
- }, {});
4766
- return {
4767
- ...decoded,
4768
- netuid,
4769
- tokenSymbol,
4770
- subnetIdentity,
4771
- taoIn: BigInt(taoIn),
4772
- alphaIn: BigInt(alphaIn),
4773
- subnetName
4774
- };
4775
- };
4776
4584
  const calculateAlphaPrice = ({
4777
4585
  dynamicInfo
4778
4586
  }) => {
4779
4587
  if (!dynamicInfo) return 0n;
4780
4588
  const {
4781
- alphaIn,
4782
- taoIn
4589
+ alpha_in,
4590
+ tao_in
4783
4591
  } = dynamicInfo;
4784
4592
 
4785
4593
  // Scale taoIn before division to preserve precision
4786
- const result = taoIn * SCALE_FACTOR / alphaIn;
4594
+ const result = tao_in * SCALE_FACTOR / alpha_in;
4787
4595
  return result; // Scaled price as bigint
4788
4596
  };
4789
4597
  const calculateTaoAmountFromAlpha = ({
@@ -4848,13 +4656,24 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4848
4656
  log.warn(`Chain ${chainId} for token ${tokenId} not found`);
4849
4657
  continue;
4850
4658
  }
4659
+ const [chainMeta] = findChainMeta(miniMetadatas, "substrate-native", chain);
4660
+ if (!chainMeta?.miniMetadata) {
4661
+ log.warn(`MiniMetadata for chain ${chainId} not found`);
4662
+ continue;
4663
+ }
4664
+ const scaleApi = getScaleApi({
4665
+ chainId,
4666
+ send: (...args) => chainConnector.send(chainId, ...args, {
4667
+ expectErrors: true
4668
+ } // don't pollute the wallet logs when this request fails
4669
+ )
4670
+ }, chainMeta.miniMetadata, token, chain.hasCheckMetadataHash, chain.signedExtensions, chain.registryTypes);
4851
4671
 
4852
4672
  // sets the number of addresses to query in parallel (per chain, since each chain runs in parallel to the others)
4853
4673
  const concurrency = 4;
4854
4674
  // In-memory cache for successful dynamic info results
4855
4675
  const dynamicInfoCache = new Map();
4856
4676
  const fetchDynamicInfoForNetuids = async uniqueNetuids => {
4857
- const DYNAMIC_INFO_METHOD = "SubnetInfoRuntimeApi_get_dynamic_info";
4858
4677
  const MAX_RETRIES = 3;
4859
4678
  const RETRY_DELAY_MS = 500;
4860
4679
  const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
@@ -4862,12 +4681,10 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4862
4681
  if (netuid === 0) return null;
4863
4682
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
4864
4683
  try {
4865
- const response = await chainConnector.send(chainId, "state_call", [DYNAMIC_INFO_METHOD, EncodeParams_GetDynamicInfo(netuid)], undefined, {
4866
- expectErrors: true
4867
- });
4868
- const decodedResult = DecodeResult_GetDynamicInfo(response);
4869
- dynamicInfoCache.set(netuid, decodedResult); // Cache successful response
4870
- return decodedResult;
4684
+ const params = [netuid];
4685
+ const result = await scaleApi.getRuntimeCallValue("SubnetInfoRuntimeApi", "get_dynamic_info", params);
4686
+ dynamicInfoCache.set(netuid, result); // Cache successful response
4687
+ return result;
4871
4688
  } catch (error) {
4872
4689
  log.trace(`Attempt ${attempt} failed for netuid ${netuid}:`, error);
4873
4690
  if (attempt < MAX_RETRIES) {
@@ -4889,14 +4706,9 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4889
4706
  // mergeMap lets us run N concurrent queries, where N is the value of `concurrency`
4890
4707
  mergeMap(async address => {
4891
4708
  const queryMethods = [async () => {
4892
- if (chainId === BITTENSOR_TESTNET_CHAIN_ID) return [];
4893
- const method = "StakeInfoRuntimeApi_get_stake_info_for_coldkey";
4894
- const params = EncodeParams_GetStakeInfoForColdkey(address);
4895
- const response = await chainConnector.send(chainId, "state_call", [method, params], undefined, {
4896
- expectErrors: true
4897
- } // don't pollute the wallet logs when this request fails
4898
- );
4899
- const result = DecodeResult_GetStakeInfoForColdkey(response);
4709
+ if (chain.isTestnet) return [];
4710
+ const params = [address];
4711
+ const result = await scaleApi.getRuntimeCallValue("StakeInfoRuntimeApi", "get_stake_info_for_coldkey", params);
4900
4712
  if (!Array.isArray(result)) return [];
4901
4713
  const uniqueNetuids = Array.from(new Set(result.map(item => Number(item.netuid)).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID)));
4902
4714
  await fetchDynamicInfoForNetuids(uniqueNetuids);
@@ -4946,10 +4758,19 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4946
4758
  dynamicInfo
4947
4759
  }) => {
4948
4760
  const {
4949
- tokenSymbol,
4950
- subnetName,
4951
- subnetIdentity
4761
+ token_symbol,
4762
+ subnet_name,
4763
+ subnet_identity
4952
4764
  } = dynamicInfo ?? {};
4765
+ const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
4766
+ const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
4767
+
4768
+ /** Map from Record<string, Binary> to Record<string, string> */
4769
+ const binaryToText = input => Object.entries(input).reduce((acc, [key, value]) => {
4770
+ acc[key] = value.asText();
4771
+ return acc;
4772
+ }, {});
4773
+ const subnetIdentity = subnet_identity ? binaryToText(subnet_identity) : undefined;
4953
4774
 
4954
4775
  // Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
4955
4776
  const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
@@ -4957,7 +4778,7 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4957
4778
  alphaStaked: stake
4958
4779
  }) : 1n;
4959
4780
  const alphaToTaoRate = calculateTaoFromDynamicInfo({
4960
- dynamicInfo,
4781
+ dynamicInfo: dynamicInfo ?? null,
4961
4782
  alphaStaked: ONE_ALPHA_TOKEN
4962
4783
  }).toString();
4963
4784
  const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
@@ -4986,7 +4807,7 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4986
4807
  subnetName,
4987
4808
  subnetIdentity: {
4988
4809
  ...subnetIdentity,
4989
- subnetName: subnetIdentity?.subnetName || subnetName
4810
+ subnetName: subnetIdentity?.subnet_name || subnetName
4990
4811
  }
4991
4812
  }
4992
4813
  }
@@ -5673,6 +5494,7 @@ const SubNativeModule = hydrate => {
5673
5494
 
5674
5495
  compactMetadata(metadata, [{
5675
5496
  pallet: "System",
5497
+ constants: ["Version", "SS58Prefix"],
5676
5498
  items: ["Account"]
5677
5499
  }, {
5678
5500
  pallet: "Balances",
@@ -5695,6 +5517,12 @@ const SubNativeModule = hydrate => {
5695
5517
  {
5696
5518
  pallet: "SubtensorModule",
5697
5519
  items: ["TotalColdkeyStake", "StakingHotkeys", "Stake"]
5520
+ }], [{
5521
+ runtimeApi: "StakeInfoRuntimeApi",
5522
+ methods: ["get_stake_info_for_coldkey"]
5523
+ }, {
5524
+ runtimeApi: "SubnetInfoRuntimeApi",
5525
+ methods: ["get_dynamic_info"]
5698
5526
  }]);
5699
5527
  const miniMetadata = encodeMetadata(tag === "v15" ? {
5700
5528
  tag,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@talismn/balances",
3
- "version": "0.8.2",
3
+ "version": "0.9.1",
4
4
  "author": "Talisman",
5
5
  "homepage": "https://talisman.xyz",
6
6
  "license": "GPL-3.0-or-later",
@@ -22,7 +22,7 @@
22
22
  "node": ">=18"
23
23
  },
24
24
  "dependencies": {
25
- "@polkadot-api/utils": "^0.1.2",
25
+ "@polkadot-api/utils": "0.1.2",
26
26
  "@supercharge/promise-pool": "^3.2.0",
27
27
  "anylogger": "^1.0.11",
28
28
  "bignumber.js": "^9.1.2",
@@ -32,13 +32,14 @@
32
32
  "polkadot-api": "1.7.6",
33
33
  "rxjs": "^7.8.1",
34
34
  "scale-ts": "^1.6.1",
35
- "viem": "^2.21.34",
36
- "@talismn/chain-connector": "0.8.4",
37
- "@talismn/chaindata-provider": "0.8.4",
38
- "@talismn/chain-connector-evm": "0.8.4",
39
- "@talismn/util": "0.3.1",
40
- "@talismn/token-rates": "1.0.4",
41
- "@talismn/scale": "0.1.0"
35
+ "viem": "^2.27.3",
36
+ "@talismn/chain-connector": "0.10.0",
37
+ "@talismn/chaindata-provider": "0.10.0",
38
+ "@talismn/chain-connector-evm": "0.10.0",
39
+ "@talismn/sapi": "0.0.3",
40
+ "@talismn/scale": "0.1.1",
41
+ "@talismn/token-rates": "2.0.1",
42
+ "@talismn/util": "0.4.0"
42
43
  },
43
44
  "devDependencies": {
44
45
  "@polkadot/api-contract": "15.8.1",