@talismn/balances 0.8.1 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -37,7 +37,7 @@ export type Hydrate = {
37
37
  export type NewBalanceModule<TModuleType extends string, TTokenType extends SelectableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams> = (hydrate: Hydrate) => BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>;
38
38
  export interface BalanceModule<TModuleType extends string, TTokenType extends SelectableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams> extends BalanceModuleSubstrate<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>, BalanceModuleEvm<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams> {
39
39
  }
40
- export declare const DefaultBalanceModule: <TModuleType extends string, TTokenType extends SelectableTokenType, TChainMeta extends ExtendableChainMeta = undefined, TModuleConfig extends ExtendableModuleConfig = undefined, TTransferParams extends ExtendableTransferParams = undefined>(type: TModuleType) => BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>;
40
+ export declare const DefaultBalanceModule: <TModuleType extends string, TTokenType extends SelectableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams>(type: TModuleType) => BalanceModule<TModuleType, TTokenType, TChainMeta, TModuleConfig, TTransferParams>;
41
41
  interface BalanceModuleSubstrate<TModuleType extends string, TTokenType extends SelectableTokenType, TChainMeta extends ExtendableChainMeta = DefaultChainMeta, TModuleConfig extends ExtendableModuleConfig = DefaultModuleConfig, TTransferParams extends ExtendableTransferParams = DefaultTransferParams> extends BalanceModuleCommon<TModuleType, TTokenType, TTransferParams> {
42
42
  /** Pre-processes any substrate chain metadata required by this module ahead of time */
43
43
  fetchSubstrateChainMeta(chainId: ChainId, moduleConfig?: TModuleConfig, metadataRpc?: `0x${string}`, systemProperties?: Record<string, any>): Promise<TChainMeta | null>;
@@ -1,56 +1,20 @@
1
+ import type { bittensor } from "@polkadot-api/descriptors";
2
+ export type GetStakeInfoForColdkeyParams = (typeof bittensor)["descriptors"]["apis"]["StakeInfoRuntimeApi"]["get_stake_info_for_coldkey"][0];
3
+ export type GetStakeInfoForColdkeyResult = (typeof bittensor)["descriptors"]["apis"]["StakeInfoRuntimeApi"]["get_stake_info_for_coldkey"][1];
4
+ export type GetDynamicInfoParams = (typeof bittensor)["descriptors"]["apis"]["SubnetInfoRuntimeApi"]["get_dynamic_info"][0];
5
+ export type GetDynamicInfoResult = (typeof bittensor)["descriptors"]["apis"]["SubnetInfoRuntimeApi"]["get_dynamic_info"][1];
1
6
  export declare const SUBTENSOR_ROOT_NETUID = 0;
2
7
  export declare const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK = 1000000n;
3
8
  export declare const SCALE_FACTOR: bigint;
4
9
  export declare const ONE_ALPHA_TOKEN: bigint;
5
- export declare const BITTENSOR_TESTNET_CHAIN_ID = "bittensor-testnet";
6
- export declare const EncodeParams_GetStakeInfoForColdkey: (address: string) => string;
7
- export declare const DecodeResult_GetStakeInfoForColdkey: (result: string) => {
8
- hotkey: import("polkadot-api").SS58String;
9
- coldkey: import("polkadot-api").SS58String;
10
- netuid: number | bigint;
11
- stake: number | bigint;
12
- locked: number | bigint;
13
- emission: number | bigint;
14
- tao_emission: number | bigint;
15
- drain: number | bigint;
16
- isRegistered: boolean;
17
- }[];
18
- /** Encoding/decoding for GetStakeDynamicInfo */
19
- export declare const EncodeParams_GetDynamicInfo: (netuid: number) => string;
20
- export type DynamicInfoType = ReturnType<typeof DecodeResult_GetDynamicInfo>;
21
- export declare const DecodeResult_GetDynamicInfo: (result: string) => {
22
- netuid: number;
23
- tokenSymbol: string;
24
- subnetIdentity: Record<string, string>;
25
- taoIn: bigint;
26
- alphaIn: bigint;
27
- subnetName: string;
28
- ownerHotkey: import("polkadot-api").SS58String;
29
- ownerColdkey: import("polkadot-api").SS58String;
30
- tempo: number | bigint;
31
- lastStep: number | bigint;
32
- blocksSinceLastStep: number | bigint;
33
- emission: number | bigint;
34
- alphaOut: number | bigint;
35
- alphaOutEmission: number | bigint;
36
- alphaInEmission: number | bigint;
37
- taoInEmission: number | bigint;
38
- pendingAlphaEmission: number | bigint;
39
- pendingRootEmission: number | bigint;
40
- subnetVolume: number | bigint;
41
- networkRegisteredAt: number | bigint;
42
- movingPrice: {
43
- bits: number | bigint;
44
- };
45
- };
46
10
  export declare const calculateAlphaPrice: ({ dynamicInfo, }: {
47
- dynamicInfo: DynamicInfoType | void | null;
11
+ dynamicInfo: GetDynamicInfoResult | null | undefined;
48
12
  }) => bigint;
49
13
  export declare const calculateTaoAmountFromAlpha: ({ alphaPrice, alphaStaked, }: {
50
14
  alphaPrice: bigint;
51
15
  alphaStaked: bigint;
52
16
  }) => bigint;
53
17
  export declare const calculateTaoFromDynamicInfo: ({ dynamicInfo, alphaStaked, }: {
54
- dynamicInfo: DynamicInfoType | void | null;
18
+ dynamicInfo: GetDynamicInfoResult | null | undefined;
55
19
  alphaStaked: bigint;
56
20
  }) => bigint;
@@ -18,9 +18,11 @@ export declare const buildStorageCoders: <TBalanceModule extends AnyNewBalanceMo
18
18
  moduleType: InferModuleType<TBalanceModule>;
19
19
  coders: TCoders;
20
20
  }) => Map<string, { [Property in keyof TCoders]: {
21
+ keys: {
22
+ enc: (...args: any[]) => string;
23
+ dec: (value: string) => any[];
24
+ };
25
+ value: import("@talismn/scale").Codec<any>;
21
26
  len: number;
22
- fallback: unknown;
23
- enc: (...args: any[]) => string;
24
- dec: import("scale-ts").Decoder<unknown>;
25
- keyDecoder: (value: string) => any[];
27
+ fallback: any;
26
28
  } | undefined; }>;
@@ -5,5 +5,5 @@ export declare const configureStore: (dbTable?: Table) => {
5
5
  persistData: (balances: StoredBalanceJson[]) => Promise<void>;
6
6
  retrieveData: () => Promise<StoredBalanceJson[]>;
7
7
  };
8
- export declare const compress: (balances: StoredBalanceJson[]) => Uint8Array;
8
+ export declare const compress: (balances: StoredBalanceJson[]) => Uint8Array<ArrayBufferLike>;
9
9
  export declare const decompress: (data: Uint8Array | ArrayBuffer) => StoredBalanceJson[];
@@ -96,11 +96,7 @@ export declare class Balances {
96
96
  */
97
97
  remove: (ids: string[] | string) => Balances;
98
98
  get each(): Balance[];
99
- /**
100
- * Get an array of balances in this collection, sorted by chain sortIndex.
101
- *
102
- * @returns A sorted array of the balances in this collection.
103
- */
99
+ /** @deprecated use each instead */
104
100
  get sorted(): Balance[];
105
101
  /**
106
102
  * Get the number of balances in this collection.
@@ -22,6 +22,7 @@ var groupBy = require('lodash/groupBy');
22
22
  var utils = require('@polkadot-api/utils');
23
23
  var polkadotApi = require('polkadot-api');
24
24
  var chainConnector = require('@talismn/chain-connector');
25
+ var sapi = require('@talismn/sapi');
25
26
  var upperFirst = require('lodash/upperFirst');
26
27
  var apiContract = require('@polkadot/api-contract');
27
28
 
@@ -108,88 +109,7 @@ class EvmTokenFetcher {
108
109
  }
109
110
 
110
111
  var packageJson = {
111
- name: "@talismn/balances",
112
- version: "0.8.1",
113
- author: "Talisman",
114
- homepage: "https://talisman.xyz",
115
- license: "GPL-3.0-or-later",
116
- publishConfig: {
117
- access: "public"
118
- },
119
- repository: {
120
- directory: "packages/balances",
121
- type: "git",
122
- url: "https://github.com/talismansociety/talisman.git"
123
- },
124
- main: "dist/talismn-balances.cjs.js",
125
- module: "dist/talismn-balances.esm.js",
126
- files: [
127
- "/dist",
128
- "/plugins"
129
- ],
130
- engines: {
131
- node: ">=18"
132
- },
133
- scripts: {
134
- test: "jest",
135
- lint: "eslint src --max-warnings 0",
136
- clean: "rm -rf dist plugins/dist .turbo node_modules"
137
- },
138
- dependencies: {
139
- "@polkadot-api/utils": "^0.1.2",
140
- "@supercharge/promise-pool": "^3.2.0",
141
- "@talismn/chain-connector": "workspace:*",
142
- "@talismn/chain-connector-evm": "workspace:*",
143
- "@talismn/chaindata-provider": "workspace:*",
144
- "@talismn/scale": "workspace:*",
145
- "@talismn/token-rates": "workspace:*",
146
- "@talismn/util": "workspace:*",
147
- anylogger: "^1.0.11",
148
- "bignumber.js": "^9.1.2",
149
- dexie: "^4.0.9",
150
- lodash: "4.17.21",
151
- pako: "^2.1.0",
152
- "polkadot-api": "1.7.6",
153
- rxjs: "^7.8.1",
154
- "scale-ts": "^1.6.1",
155
- viem: "^2.21.34"
156
- },
157
- devDependencies: {
158
- "@polkadot/api-contract": "15.8.1",
159
- "@polkadot/types": "15.8.1",
160
- "@polkadot/util": "13.4.3",
161
- "@polkadot/util-crypto": "13.4.3",
162
- "@substrate/txwrapper-core": "7.5.3",
163
- "@talismn/eslint-config": "workspace:*",
164
- "@talismn/tsconfig": "workspace:*",
165
- "@types/jest": "^29.5.14",
166
- "@types/lodash": "^4.17.12",
167
- "@types/pako": "^2.0.3",
168
- eslint: "^8.57.1",
169
- jest: "^29.7.0",
170
- "ts-jest": "^29.2.5",
171
- typescript: "^5.6.3"
172
- },
173
- peerDependencies: {
174
- "@polkadot/api-contract": "*",
175
- "@polkadot/types": "*",
176
- "@polkadot/util": "*",
177
- "@polkadot/util-crypto": "*",
178
- "@substrate/txwrapper-core": "*"
179
- },
180
- preconstruct: {
181
- entrypoints: [
182
- "index.ts",
183
- "plugins.ts"
184
- ]
185
- },
186
- eslintConfig: {
187
- root: true,
188
- "extends": [
189
- "@talismn/eslint-config/base"
190
- ]
191
- }
192
- };
112
+ name: "@talismn/balances"};
193
113
 
194
114
  var log = anylogger__default.default(packageJson.name);
195
115
 
@@ -375,13 +295,9 @@ class Balances {
375
295
  return [...this];
376
296
  }
377
297
 
378
- /**
379
- * Get an array of balances in this collection, sorted by chain sortIndex.
380
- *
381
- * @returns A sorted array of the balances in this collection.
382
- */
298
+ /** @deprecated use each instead */
383
299
  get sorted() {
384
- return [...this].sort((a, b) => ((a.chain || a.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER) - ((b.chain || b.evmNetwork)?.sortIndex ?? Number.MAX_SAFE_INTEGER));
300
+ return this.each;
385
301
  }
386
302
 
387
303
  /**
@@ -413,7 +329,7 @@ const getBalanceId = balance => {
413
329
  tokenId
414
330
  } = balance;
415
331
  const locationId = isBalanceEvm(balance) ? balance.evmNetworkId : balance.chainId;
416
- return [source, address, locationId, tokenId].filter(Boolean).join("::");
332
+ return [source, address, locationId, tokenId].filter(util.isTruthy).join("::");
417
333
  };
418
334
 
419
335
  /**
@@ -1055,7 +971,7 @@ const upgradeBalancesDataBlob = async tx => {
1055
971
  ...stuffToKeep
1056
972
  } = balance;
1057
973
  return stuffToKeep;
1058
- }).filter(Boolean);
974
+ }).filter(util.isTruthy);
1059
975
  const output = pako__default.default.deflate(JSON.stringify(migratedData));
1060
976
  // now write the compressed data back to the db and clear the old one
1061
977
  await tx.table("balancesBlob").put({
@@ -1796,7 +1712,7 @@ const fetchBalances$3 = async (evmChainConnector, tokenAddressesByNetwork, erc20
1796
1712
  const balances = await getEvmTokenBalances(publicClient, networkParams, result.errors, erc20Aggregators[evmNetworkId]);
1797
1713
 
1798
1714
  // consider only non null balances in the results
1799
- result.results.push(...balances.filter(Boolean).map((free, i) => ({
1715
+ result.results.push(...balances.filter(util.isTruthy).map((free, i) => ({
1800
1716
  source: "evm-erc20",
1801
1717
  status: "live",
1802
1718
  address: networkParams[i].address,
@@ -3309,7 +3225,7 @@ const SubAssetsModule = hydrate => {
3309
3225
  const assetStateKey = tryEncode(assetCoder, BigInt(assetId)) ?? tryEncode(assetCoder, assetId);
3310
3226
  const metadataStateKey = tryEncode(metadataCoder, BigInt(assetId)) ?? tryEncode(metadataCoder, assetId);
3311
3227
  if (assetStateKey === null || metadataStateKey === null) throw new Error(`Failed to encode stateKey for asset ${assetId} on chain ${chainId}`);
3312
- 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)]);
3228
+ 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)]);
3313
3229
  const existentialDeposit = assetsAsset?.min_balance?.toString?.() ?? "0";
3314
3230
  const symbol = assetsMetadata?.symbol?.asText?.() ?? "Unit";
3315
3231
  const decimals = assetsMetadata?.decimals ?? 0;
@@ -3476,15 +3392,9 @@ async function buildQueries$4(chaindataProvider, addressesByToken) {
3476
3392
 
3477
3393
  const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode substrate-assets balance on chain ${chainId}`) ?? {
3478
3394
  balance: 0n,
3479
- is_frozen: false,
3480
- reason: {
3481
- type: "Sufficient"
3482
- },
3483
3395
  status: {
3484
3396
  type: "Liquid"
3485
- },
3486
- extra: undefined
3487
- };
3397
+ }};
3488
3398
  const isFrozen = decoded?.status?.type === "Frozen";
3489
3399
  const amount = (decoded?.balance ?? 0n).toString();
3490
3400
 
@@ -3536,7 +3446,7 @@ async function buildQueries$4(chaindataProvider, addressesByToken) {
3536
3446
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
3537
3447
  const tryEncode = (scaleCoder, ...args) => {
3538
3448
  try {
3539
- return scaleCoder?.enc?.(...args);
3449
+ return scaleCoder?.keys?.enc?.(...args);
3540
3450
  } catch {
3541
3451
  return null;
3542
3452
  }
@@ -3607,11 +3517,11 @@ const SubEquilibriumModule = hydrate => {
3607
3517
  try {
3608
3518
  const scaleBuilder = scale.getDynamicBuilder(scale.getLookupFn(metadata));
3609
3519
  const assetsCoder = scaleBuilder.buildStorage("EqAssets", "Assets");
3610
- const stateKey = assetsCoder.enc();
3520
+ const stateKey = assetsCoder.keys.enc();
3611
3521
 
3612
3522
  /** NOTE: Just a guideline, the RPC can return whatever it wants */
3613
3523
 
3614
- const assetsResult = await chainConnector.send(chainId, "state_getStorage", [stateKey]).then(result => assetsCoder.dec(result) ?? null);
3524
+ const assetsResult = await chainConnector.send(chainId, "state_getStorage", [stateKey]).then(result => assetsCoder.value.dec(result) ?? null);
3615
3525
  const tokens = (Array.isArray(assetsResult) ? assetsResult : []).flatMap(asset => {
3616
3526
  if (!asset) return [];
3617
3527
  if (!asset?.id) return [];
@@ -3896,9 +3806,9 @@ const SubForeignAssetsModule = hydrate => {
3896
3806
  }
3897
3807
  })();
3898
3808
  if (onChainId === undefined) continue;
3899
- const assetStateKey = assetCoder.enc(onChainId);
3900
- const metadataStateKey = metadataCoder.enc(onChainId);
3901
- 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)]);
3809
+ const assetStateKey = assetCoder.keys.enc(onChainId);
3810
+ const metadataStateKey = metadataCoder.keys.enc(onChainId);
3811
+ 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)]);
3902
3812
  const existentialDeposit = assetsAsset?.min_balance?.toString?.() ?? "0";
3903
3813
  const symbol = assetsMetadata?.symbol?.asText?.() ?? "Unit";
3904
3814
  const decimals = assetsMetadata?.decimals ?? 0;
@@ -4058,15 +3968,9 @@ async function buildQueries$2(chaindataProvider, addressesByToken) {
4058
3968
 
4059
3969
  const decoded = scale.decodeScale(scaleCoder, change, `Failed to decode substrate-foreignassets balance on chain ${chainId}`) ?? {
4060
3970
  balance: 0n,
4061
- is_frozen: false,
4062
- reason: {
4063
- type: "Sufficient"
4064
- },
4065
3971
  status: {
4066
3972
  type: "Liquid"
4067
- },
4068
- extra: undefined
4069
- };
3973
+ }};
4070
3974
  const isFrozen = decoded?.status?.type === "Frozen";
4071
3975
  const amount = (decoded?.balance ?? 0n).toString();
4072
3976
 
@@ -4129,7 +4033,7 @@ async function subscribeBase(queries, chainConnector, callback) {
4129
4033
  * <TArgs, TResult>(...arguments: TArgs, callback: SubscriptionCallback<TResult>) => UnsubscribeFn
4130
4034
  */
4131
4035
  const asObservable = handler => (...args) => new rxjs.Observable(subscriber => {
4132
- const callback = (error, result) => error ? subscriber.error(error) : subscriber.next(result);
4036
+ const callback = (error, result) => error || result === undefined ? subscriber.error(error) : subscriber.next(result);
4133
4037
  const unsubscribe = handler(...args, callback);
4134
4038
  return unsubscribe;
4135
4039
  });
@@ -4675,7 +4579,7 @@ async function subscribeNompoolStaking(chaindataProvider, chainConnector, addres
4675
4579
  }
4676
4580
  }]
4677
4581
  };
4678
- }).filter(Boolean);
4582
+ }).filter(util.isNotNil);
4679
4583
  if (balances.length > 0) callback(null, balances);
4680
4584
  },
4681
4585
  error: error => callback(error)
@@ -4690,113 +4594,17 @@ const SUBTENSOR_MIN_STAKE_AMOUNT_PLANK = 1000000n;
4690
4594
  const TAO_DECIMALS = 9n;
4691
4595
  const SCALE_FACTOR = 10n ** TAO_DECIMALS; // Equivalent to 10e9 for precision
4692
4596
  const ONE_ALPHA_TOKEN = SCALE_FACTOR;
4693
- const BITTENSOR_TESTNET_CHAIN_ID = "bittensor-testnet";
4694
- const BittensorAccountPrefix = 42;
4695
- const BittensorAccountId = polkadotApi.AccountId(BittensorAccountPrefix);
4696
-
4697
- /** For encoding/decoding the GetStakeInfoForColdkey runtime api *after* they added the netuid parameter */
4698
- const StakeInfo = scaleTs.Struct({
4699
- hotkey: BittensorAccountId,
4700
- coldkey: BittensorAccountId,
4701
- netuid: scaleTs.compact,
4702
- stake: scaleTs.compact,
4703
- locked: scaleTs.compact,
4704
- emission: scaleTs.compact,
4705
- tao_emission: scaleTs.compact,
4706
- drain: scaleTs.compact,
4707
- isRegistered: scaleTs.bool
4708
- });
4709
- const EncodeParams_GetStakeInfoForColdkey = address => utils.toHex(BittensorAccountId.enc(address));
4710
- const DecodeResult_GetStakeInfoForColdkey = result => scaleTs.Vector(StakeInfo).dec(result);
4711
- /** Encoding/decoding for GetStakeDynamicInfo */
4712
- const EncodeParams_GetDynamicInfo = netuid => {
4713
- if (netuid < 0 || netuid > 65535) {
4714
- throw new Error("netuid must be a valid u16 (0-65535)");
4715
- }
4716
-
4717
- // Convert the number to a Uint8Array (LE encoding)
4718
- const encoded = new Uint8Array(2);
4719
- encoded[0] = netuid & 0xff; // Lower byte
4720
- encoded[1] = netuid >> 8 & 0xff; // Upper byte
4721
-
4722
- // Convert to hex string
4723
- return utils.toHex(encoded);
4724
- };
4725
- /** I96F32 representation (Fixed-Point) */
4726
- const I96F32 = scaleTs.Struct({
4727
- bits: scaleTs.compact
4728
- });
4729
- const SubnetIdentityV2 = scaleTs.Struct({
4730
- subnetName: scaleTs.Bytes(),
4731
- githubRepo: scaleTs.Bytes(),
4732
- subnetContact: scaleTs.Bytes(),
4733
- subnetUrl: scaleTs.Bytes(),
4734
- discord: scaleTs.Bytes(),
4735
- description: scaleTs.Bytes()
4736
- });
4737
- const DynamicInfo = scaleTs.Struct({
4738
- netuid: scaleTs.compact,
4739
- ownerHotkey: BittensorAccountId,
4740
- ownerColdkey: BittensorAccountId,
4741
- subnetName: scaleTs.Vector(scaleTs.compact),
4742
- tokenSymbol: scaleTs.Vector(scaleTs.compact),
4743
- tempo: scaleTs.compact,
4744
- lastStep: scaleTs.compact,
4745
- blocksSinceLastStep: scaleTs.compact,
4746
- emission: scaleTs.compact,
4747
- alphaIn: scaleTs.compact,
4748
- alphaOut: scaleTs.compact,
4749
- taoIn: scaleTs.compact,
4750
- alphaOutEmission: scaleTs.compact,
4751
- alphaInEmission: scaleTs.compact,
4752
- taoInEmission: scaleTs.compact,
4753
- pendingAlphaEmission: scaleTs.compact,
4754
- pendingRootEmission: scaleTs.compact,
4755
- subnetVolume: scaleTs.compact,
4756
- networkRegisteredAt: scaleTs.compact,
4757
- subnetIdentity: scaleTs.Option(SubnetIdentityV2),
4758
- movingPrice: I96F32
4759
- });
4760
- const DecodeResult_GetDynamicInfo = result => {
4761
- const LITTLE_ENDIAN_OFFSET = 256;
4762
- const decoded = DynamicInfo.dec(result);
4763
- const {
4764
- netuid: netuidLittleEndian,
4765
- subnetIdentity: subnetIdentityScaleOption = {},
4766
- tokenSymbol: tokenSymbolU8Arr,
4767
- taoIn,
4768
- alphaIn,
4769
- subnetName: subnetNameVector
4770
- } = decoded;
4771
- const netuid = Number(netuidLittleEndian) / LITTLE_ENDIAN_OFFSET;
4772
- const tokenSymbol = new TextDecoder().decode(Uint8Array.from(tokenSymbolU8Arr.map(val => Number(val))));
4773
- const subnetName = new TextDecoder().decode(Uint8Array.from(subnetNameVector.map(val => Number(val))));
4774
- const subnetIdentity = Object.keys(subnetIdentityScaleOption).reduce((acc, key) => {
4775
- const value = subnetIdentityScaleOption[key];
4776
- acc[key] = new TextDecoder().decode(value);
4777
- return acc;
4778
- }, {});
4779
- return {
4780
- ...decoded,
4781
- netuid,
4782
- tokenSymbol,
4783
- subnetIdentity,
4784
- taoIn: BigInt(taoIn),
4785
- alphaIn: BigInt(alphaIn),
4786
- subnetName
4787
- };
4788
- };
4789
4597
  const calculateAlphaPrice = ({
4790
4598
  dynamicInfo
4791
4599
  }) => {
4792
4600
  if (!dynamicInfo) return 0n;
4793
4601
  const {
4794
- alphaIn,
4795
- taoIn
4602
+ alpha_in,
4603
+ tao_in
4796
4604
  } = dynamicInfo;
4797
4605
 
4798
4606
  // Scale taoIn before division to preserve precision
4799
- const result = taoIn * SCALE_FACTOR / alphaIn;
4607
+ const result = tao_in * SCALE_FACTOR / alpha_in;
4800
4608
  return result; // Scaled price as bigint
4801
4609
  };
4802
4610
  const calculateTaoAmountFromAlpha = ({
@@ -4861,13 +4669,24 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4861
4669
  log.warn(`Chain ${chainId} for token ${tokenId} not found`);
4862
4670
  continue;
4863
4671
  }
4672
+ const [chainMeta] = findChainMeta(miniMetadatas, "substrate-native", chain);
4673
+ if (!chainMeta?.miniMetadata) {
4674
+ log.warn(`MiniMetadata for chain ${chainId} not found`);
4675
+ continue;
4676
+ }
4677
+ const scaleApi = sapi.getScaleApi({
4678
+ chainId,
4679
+ send: (...args) => chainConnector.send(chainId, ...args, {
4680
+ expectErrors: true
4681
+ } // don't pollute the wallet logs when this request fails
4682
+ )
4683
+ }, chainMeta.miniMetadata, token, chain.hasCheckMetadataHash, chain.signedExtensions, chain.registryTypes);
4864
4684
 
4865
4685
  // sets the number of addresses to query in parallel (per chain, since each chain runs in parallel to the others)
4866
4686
  const concurrency = 4;
4867
4687
  // In-memory cache for successful dynamic info results
4868
4688
  const dynamicInfoCache = new Map();
4869
4689
  const fetchDynamicInfoForNetuids = async uniqueNetuids => {
4870
- const DYNAMIC_INFO_METHOD = "SubnetInfoRuntimeApi_get_dynamic_info";
4871
4690
  const MAX_RETRIES = 3;
4872
4691
  const RETRY_DELAY_MS = 500;
4873
4692
  const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
@@ -4875,12 +4694,10 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4875
4694
  if (netuid === 0) return null;
4876
4695
  for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
4877
4696
  try {
4878
- const response = await chainConnector.send(chainId, "state_call", [DYNAMIC_INFO_METHOD, EncodeParams_GetDynamicInfo(netuid)], undefined, {
4879
- expectErrors: true
4880
- });
4881
- const decodedResult = DecodeResult_GetDynamicInfo(response);
4882
- dynamicInfoCache.set(netuid, decodedResult); // Cache successful response
4883
- return decodedResult;
4697
+ const params = [netuid];
4698
+ const result = await scaleApi.getRuntimeCallValue("SubnetInfoRuntimeApi", "get_dynamic_info", params);
4699
+ dynamicInfoCache.set(netuid, result); // Cache successful response
4700
+ return result;
4884
4701
  } catch (error) {
4885
4702
  log.trace(`Attempt ${attempt} failed for netuid ${netuid}:`, error);
4886
4703
  if (attempt < MAX_RETRIES) {
@@ -4902,14 +4719,9 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4902
4719
  // mergeMap lets us run N concurrent queries, where N is the value of `concurrency`
4903
4720
  rxjs.mergeMap(async address => {
4904
4721
  const queryMethods = [async () => {
4905
- if (chainId === BITTENSOR_TESTNET_CHAIN_ID) return [];
4906
- const method = "StakeInfoRuntimeApi_get_stake_info_for_coldkey";
4907
- const params = EncodeParams_GetStakeInfoForColdkey(address);
4908
- const response = await chainConnector.send(chainId, "state_call", [method, params], undefined, {
4909
- expectErrors: true
4910
- } // don't pollute the wallet logs when this request fails
4911
- );
4912
- const result = DecodeResult_GetStakeInfoForColdkey(response);
4722
+ if (chain.isTestnet) return [];
4723
+ const params = [address];
4724
+ const result = await scaleApi.getRuntimeCallValue("StakeInfoRuntimeApi", "get_stake_info_for_coldkey", params);
4913
4725
  if (!Array.isArray(result)) return [];
4914
4726
  const uniqueNetuids = Array.from(new Set(result.map(item => Number(item.netuid)).filter(netuid => netuid !== SUBTENSOR_ROOT_NETUID)));
4915
4727
  await fetchDynamicInfoForNetuids(uniqueNetuids);
@@ -4959,10 +4771,19 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4959
4771
  dynamicInfo
4960
4772
  }) => {
4961
4773
  const {
4962
- tokenSymbol,
4963
- subnetName,
4964
- subnetIdentity
4774
+ token_symbol,
4775
+ subnet_name,
4776
+ subnet_identity
4965
4777
  } = dynamicInfo ?? {};
4778
+ const tokenSymbol = new TextDecoder().decode(Uint8Array.from(token_symbol ?? []));
4779
+ const subnetName = new TextDecoder().decode(Uint8Array.from(subnet_name ?? []));
4780
+
4781
+ /** Map from Record<string, Binary> to Record<string, string> */
4782
+ const binaryToText = input => Object.entries(input).reduce((acc, [key, value]) => {
4783
+ acc[key] = value.asText();
4784
+ return acc;
4785
+ }, {});
4786
+ const subnetIdentity = subnet_identity ? binaryToText(subnet_identity) : undefined;
4966
4787
 
4967
4788
  // Add 1n balance if failed to fetch dynamic info, so the position is not ignored by Balance lib and is displayed in the UI.
4968
4789
  const alphaStakedInTao = dynamicInfo ? calculateTaoFromDynamicInfo({
@@ -4970,7 +4791,7 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4970
4791
  alphaStaked: stake
4971
4792
  }) : 1n;
4972
4793
  const alphaToTaoRate = calculateTaoFromDynamicInfo({
4973
- dynamicInfo,
4794
+ dynamicInfo: dynamicInfo ?? null,
4974
4795
  alphaStaked: ONE_ALPHA_TOKEN
4975
4796
  }).toString();
4976
4797
  const stakeByNetuid = Number(netuid) === SUBTENSOR_ROOT_NETUID ? stake : alphaStakedInTao;
@@ -4999,7 +4820,7 @@ async function subscribeSubtensorStaking(chaindataProvider, chainConnector, addr
4999
4820
  subnetName,
5000
4821
  subnetIdentity: {
5001
4822
  ...subnetIdentity,
5002
- subnetName: subnetIdentity?.subnetName || subnetName
4823
+ subnetName: subnetIdentity?.subnet_name || subnetName
5003
4824
  }
5004
4825
  }
5005
4826
  }
@@ -5686,6 +5507,7 @@ const SubNativeModule = hydrate => {
5686
5507
 
5687
5508
  scale.compactMetadata(metadata, [{
5688
5509
  pallet: "System",
5510
+ constants: ["Version", "SS58Prefix"],
5689
5511
  items: ["Account"]
5690
5512
  }, {
5691
5513
  pallet: "Balances",
@@ -5708,6 +5530,12 @@ const SubNativeModule = hydrate => {
5708
5530
  {
5709
5531
  pallet: "SubtensorModule",
5710
5532
  items: ["TotalColdkeyStake", "StakingHotkeys", "Stake"]
5533
+ }], [{
5534
+ runtimeApi: "StakeInfoRuntimeApi",
5535
+ methods: ["get_stake_info_for_coldkey"]
5536
+ }, {
5537
+ runtimeApi: "SubnetInfoRuntimeApi",
5538
+ methods: ["get_dynamic_info"]
5711
5539
  }]);
5712
5540
  const miniMetadata = scale.encodeMetadata(tag === "v15" ? {
5713
5541
  tag,