@talismn/balances 3.0.2 → 3.0.4

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/index.mjs CHANGED
@@ -18,7 +18,7 @@ import { publicKey, sol } from "@metaplex-foundation/umi";
18
18
  import { TOKEN_2022_PROGRAM_ADDRESS, fetchMint, getMintDecoder as getMintDecoder$1, getTransferCheckedInstruction, getTransferCheckedWithFeeInstruction } from "@solana-program/token-2022";
19
19
  import { AccountId, Binary, Enum, getSs58AddressInfo } from "@polkadot-api/substrate-bindings";
20
20
  import { fromHex, mergeUint8, toHex as toHex$1 } from "@polkadot-api/utils";
21
- import upperFirst from "lodash-es/upperFirst.js";
21
+ import upperFirst from "lodash-es/upperFirst";
22
22
  import { Bytes, Enum as Enum$1, Result, Struct, compact, enhanceCodec, u128, u32 } from "scale-ts";
23
23
  import { fetchBestMetadata } from "@talismn/sapi";
24
24
  //#region src/configureBigNumber.ts
@@ -1708,7 +1708,8 @@ const getCachedScaleBuilder = (miniMetadata) => {
1708
1708
  }
1709
1709
  let builder = null;
1710
1710
  try {
1711
- builder = getDynamicBuilder(getLookupFn(unifyMetadata(decAnyMetadata(miniMetadata.data))));
1711
+ const metadata = unifyMetadata(decAnyMetadata(miniMetadata.data));
1712
+ builder = getDynamicBuilder(getLookupFn(metadata));
1712
1713
  } catch (cause) {
1713
1714
  log_default.error(`Failed to build scale builder for chain ${miniMetadata.chainId}`, cause);
1714
1715
  }
@@ -3662,7 +3663,8 @@ const fetchBalances$6 = async ({ networkId, tokensWithAddresses, connector, mini
3662
3663
  }))
3663
3664
  };
3664
3665
  }
3665
- const balances = await fetchRpcQueryPack(connector, networkId, buildQueries$2(networkId, balanceDefs, miniMetadata));
3666
+ const queries = buildQueries$2(networkId, balanceDefs, miniMetadata);
3667
+ const balances = await fetchRpcQueryPack(connector, networkId, queries);
3666
3668
  return balanceDefs.reduce((acc, def) => {
3667
3669
  const balance = balances.find((b) => b?.address === def.address && b?.tokenId === def.token.id);
3668
3670
  if (balance) acc.success.push(balance);
@@ -3936,28 +3938,26 @@ const findDTaoClaimablePlancks = (balances, { networkId, address, hotkey }) => {
3936
3938
  return claimablePlancks > 0n ? claimablePlancks : null;
3937
3939
  };
3938
3940
  /**
3939
- * Fetches the TAO each coldkey would realize by redeeming its validator beta baskets
3941
+ * Fetches the TAO each coldkey would receive by claiming its validator beta baskets
3940
3942
  * (Bittensor spec 441 "Root Reborn": root dividends accrue in per-validator escrow funds
3941
3943
  * and must be claimed manually; the payout is TAO staked back onto the root position).
3942
3944
  *
3943
- * Amounts are marked NAV quotes (BetaBasketRuntimeApi), so they move with subnet pool
3944
- * prices as well as accrual. Attribution is per validator hotkey via
3945
- * `get_root_basket_positions`, which walks the chain's own coldkey→hotkeys index and so
3945
+ * Amounts are the chain's own claim preview (`redeemable_tao`, spec 468): the entitlement
3946
+ * minus the dust rows the claim would skip, which is the figure the chain compares to
3947
+ * `RootClaimableThreshold` and pays out. They are marked NAV quotes, so they move with
3948
+ * subnet pool prices as well as accrual. Attribution is per validator hotkey:
3949
+ * `get_root_basket_claim_previews` walks the chain's own coldkey→hotkeys index and so
3946
3950
  * includes validators the coldkey fully unstaked from (entitlement survives unstaking).
3947
- *
3948
- * It is the only entitlement read: the coldkey-wide `get_root_basket_owed` total sums the
3949
- * same positions, and claiming is per validator hotkey, so entitlement outside a position
3950
- * would be unclaimable anyway.
3951
3951
  */
3952
3952
  const fetchBasketClaims = async (connector, networkId, metadataRpc, addresses, at) => {
3953
3953
  if (!addresses.length) return [];
3954
3954
  const { unifiedMetadata, builder } = parseMetadataRpcCached(metadataRpc);
3955
- if (!hasRuntimeApi(unifiedMetadata, "BetaBasketRuntimeApi", "get_root_basket_positions")) return [];
3955
+ if (!hasRuntimeApi(unifiedMetadata, "BetaBasketRuntimeApi", "get_root_basket_claim_previews")) return [];
3956
3956
  try {
3957
- return (await Promise.all(addresses.map(async (address) => [address, await fetchRuntimeCallResult(connector, networkId, builder, "BetaBasketRuntimeApi", "get_root_basket_positions", [address], at)]))).flatMap(([address, positions]) => positions.filter(([, , payoutTao]) => payoutTao > 0n).map(([hotkey, , payoutTao]) => ({
3957
+ return (await Promise.all(addresses.map(async (address) => [address, await fetchRuntimeCallResult(connector, networkId, builder, "BetaBasketRuntimeApi", "get_root_basket_claim_previews", [address], at)]))).flatMap(([address, previews]) => previews.filter((preview) => preview.redeemable_tao > 0n).map((preview) => ({
3958
3958
  address,
3959
- hotkey,
3960
- amount: payoutTao
3959
+ hotkey: preview.hotkey,
3960
+ amount: preview.redeemable_tao
3961
3961
  })));
3962
3962
  } catch (cause) {
3963
3963
  log_default.warn(`Failed to fetch beta basket claims on ${networkId}`, { cause });
@@ -4194,7 +4194,7 @@ const fetchRootStakeHolds = async (connector, networkId, metadataRpc, rootPairs,
4194
4194
  };
4195
4195
  const fetchUnlockInterval = async (connector, networkId, unifiedMetadata, builder, at) => {
4196
4196
  const storageCoder = builder.buildStorage("SubtensorModule", "RootStakeUnlockInterval");
4197
- const [interval] = await fetchRpcQueryPack(connector, networkId, [{
4197
+ const query = {
4198
4198
  stateKeys: [storageCoder.keys.enc()],
4199
4199
  decodeResult: (changes) => {
4200
4200
  const encoded = changes[0] ?? getUnlockIntervalFallback(unifiedMetadata, networkId);
@@ -4202,7 +4202,8 @@ const fetchUnlockInterval = async (connector, networkId, unifiedMetadata, builde
4202
4202
  if (decoded === null) throw new Error(`Failed to decode RootStakeUnlockInterval on ${networkId}`);
4203
4203
  return decoded;
4204
4204
  }
4205
- }], at);
4205
+ };
4206
+ const [interval] = await fetchRpcQueryPack(connector, networkId, [query], at);
4206
4207
  return interval ?? 0n;
4207
4208
  };
4208
4209
  const getUnlockIntervalFallback = (unifiedMetadata, networkId) => {
@@ -4226,7 +4227,7 @@ const fetchLastStakeBlocks = async (connector, networkId, builder, rootPairs, at
4226
4227
  }
4227
4228
  };
4228
4229
  const storageCoder = builder.buildStorage("SubtensorModule", "LastColdkeyHotkeyStakeBlock");
4229
- const [currentBlock, ...lastStakeBlocks] = await fetchRpcQueryPack(connector, networkId, [currentBlockQuery, ...rootPairs.map(({ address, hotkey }) => {
4230
+ const queries = rootPairs.map(({ address, hotkey }) => {
4230
4231
  let stateKey;
4231
4232
  try {
4232
4233
  stateKey = storageCoder.keys.enc(address, hotkey);
@@ -4252,7 +4253,8 @@ const fetchLastStakeBlocks = async (connector, networkId, builder, rootPairs, at
4252
4253
  };
4253
4254
  }
4254
4255
  };
4255
- })], at);
4256
+ });
4257
+ const [currentBlock, ...lastStakeBlocks] = await fetchRpcQueryPack(connector, networkId, [currentBlockQuery, ...queries], at);
4256
4258
  return {
4257
4259
  currentBlock,
4258
4260
  lastStakeBlocks
@@ -4506,7 +4508,8 @@ const fetchTransferableTokensMap = async (connector, metadata, networkId) => {
4506
4508
  const transferToggleCodec = builder.buildStorage("SubtensorModule", "TransferToggle");
4507
4509
  const transferToggleKeys = await fetchStorageKeysPaged(connector, networkId, getStorageKeyPrefix("SubtensorModule", "TransferToggle"));
4508
4510
  const transferToggleResults = await connector.send(networkId, "state_queryStorageAt", [transferToggleKeys]);
4509
- return fromPairs((transferToggleResults.length ? transferToggleResults[0].changes : []).map(([key, value]) => {
4511
+ const transferToggleEntries = transferToggleResults.length ? transferToggleResults[0].changes : [];
4512
+ return fromPairs(transferToggleEntries.map(([key, value]) => {
4510
4513
  const [netuid] = transferToggleCodec.keys.dec(key);
4511
4514
  return [netuid, transferToggleCodec.value.dec(value)];
4512
4515
  }));
@@ -4561,7 +4564,7 @@ const getData$3 = (metadataRpc) => {
4561
4564
  },
4562
4565
  {
4563
4566
  runtimeApi: "BetaBasketRuntimeApi",
4564
- methods: ["get_root_basket_positions"]
4567
+ methods: ["get_root_basket_claim_previews"]
4565
4568
  }
4566
4569
  ]);
4567
4570
  return encodeMetadata(metadata);
@@ -4649,11 +4652,13 @@ const classifyValue = (previous, next) => {
4649
4652
  if (previousLock?.type !== nextLock?.type || previousLock?.hotkey !== nextLock?.hotkey || previousLock?.lockType !== nextLock?.lockType) return changed("conviction lock meta");
4650
4653
  if (previousMeta?.rootStakeHold?.unlockAtBlock !== nextMeta?.rootStakeHold?.unlockAtBlock) return changed("root stake hold meta");
4651
4654
  let drift = false;
4652
- if (previous.amount !== next.amount) if (previous.label === "Claimable rewards") {
4653
- if (!isWithinDriftTolerance(previous.amount, next.amount, CLAIM_DRIFT_TOLERANCE_BPS)) drift = true;
4654
- } else if (previousLock) drift = true;
4655
- else if (isWithinDriftTolerance(previous.amount, next.amount, STAKE_DRIFT_TOLERANCE_BPS)) drift = true;
4656
- else return changed(`amount ${previous.amount}→${next.amount}`);
4655
+ if (previous.amount !== next.amount) {
4656
+ if (previous.label === "Claimable rewards") {
4657
+ if (!isWithinDriftTolerance(previous.amount, next.amount, CLAIM_DRIFT_TOLERANCE_BPS)) drift = true;
4658
+ } else if (previousLock) drift = true;
4659
+ else if (isWithinDriftTolerance(previous.amount, next.amount, STAKE_DRIFT_TOLERANCE_BPS)) drift = true;
4660
+ else return changed(`amount ${previous.amount}→${next.amount}`);
4661
+ }
4657
4662
  return { equivalence: drift ? "drift" : "equal" };
4658
4663
  };
4659
4664
  const keyOf = (value) => `${value.type}|${value.label}`;
@@ -4859,7 +4864,8 @@ const fetchBalances$4 = async ({ networkId, tokensWithAddresses, connector, mini
4859
4864
  }))
4860
4865
  };
4861
4866
  }
4862
- const balances = await fetchRpcQueryPack(connector, networkId, buildQueries$1(networkId, balanceDefs, miniMetadata));
4867
+ const queries = buildQueries$1(networkId, balanceDefs, miniMetadata);
4868
+ const balances = await fetchRpcQueryPack(connector, networkId, queries);
4863
4869
  return balanceDefs.reduce((acc, def) => {
4864
4870
  const balance = balances.find((b) => b?.address === def.address && b?.tokenId === def.token.id);
4865
4871
  if (balance) acc.success.push(balance);
@@ -5125,7 +5131,7 @@ const fetchBalances$3 = async ({ networkId, tokensWithAddresses, connector, mini
5125
5131
  const addresses = uniq(balanceDefs.map((def) => def.address));
5126
5132
  try {
5127
5133
  const res = await Promise.all(addresses.map((address) => fetchRuntimeCallResult(connector, networkId, miniMetadata.data, "CurrenciesApi", "accounts", [address])));
5128
- const balancesByKey = keyBy(addresses.flatMap((address, index) => {
5134
+ const fetchedBalances = addresses.flatMap((address, index) => {
5129
5135
  return res[index].map(([onChainId, balance]) => ({
5130
5136
  address,
5131
5137
  onChainId,
@@ -5133,7 +5139,8 @@ const fetchBalances$3 = async ({ networkId, tokensWithAddresses, connector, mini
5133
5139
  reserved: balance.reserved.toString(),
5134
5140
  frozen: balance.frozen.toString()
5135
5141
  })).filter((b) => b.onChainId !== void 0);
5136
- }), (b) => `${b.address}:${b.onChainId}`);
5142
+ });
5143
+ const balancesByKey = keyBy(fetchedBalances, (b) => `${b.address}:${b.onChainId}`);
5137
5144
  return {
5138
5145
  success: tokensWithAddresses.reduce((acc, [token, addresses]) => {
5139
5146
  if (token.type === MODULE_TYPE$3) for (const address of addresses) {
@@ -5574,12 +5581,13 @@ const nompoolAccountId = (palletId, poolId, index) => {
5574
5581
  const encIndex = new Uint8Array([index]);
5575
5582
  const encPoolId = u32.enc(typeof poolId === "string" ? parseInt(poolId, 10) : poolId);
5576
5583
  const remainingBytes = 32 - (encModPrefix.length + encPalletId.length + encIndex.length + encPoolId.length);
5584
+ const encEmptyH256 = new Uint8Array(remainingBytes);
5577
5585
  const bytes = mergeUint8([
5578
5586
  encModPrefix,
5579
5587
  encPalletId,
5580
5588
  encIndex,
5581
5589
  encPoolId,
5582
- new Uint8Array(remainingBytes)
5590
+ encEmptyH256
5583
5591
  ]);
5584
5592
  return AccountId().dec(bytes);
5585
5593
  };
@@ -5707,8 +5715,11 @@ const fetchBalances$2 = async ({ networkId, tokensWithAddresses, connector, mini
5707
5715
  }))
5708
5716
  };
5709
5717
  }
5718
+ const baseQueries = buildBaseQueries(networkId, balanceDefs, miniMetadata);
5719
+ const partialBalances = await fetchRpcQueryPack(connector, networkId, baseQueries);
5720
+ const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5710
5721
  return {
5711
- success: await fetchRpcQueryPack(connector, networkId, buildNomPoolQueries(networkId, await fetchRpcQueryPack(connector, networkId, buildBaseQueries(networkId, balanceDefs, miniMetadata)), miniMetadata)),
5722
+ success: await fetchRpcQueryPack(connector, networkId, nomPoolQueries),
5712
5723
  errors: []
5713
5724
  };
5714
5725
  };
@@ -5719,7 +5730,7 @@ const fetchTokens$2 = async ({ networkId, tokens, connector, miniMetadata }) =>
5719
5730
  const { tokenSymbol: symbol, tokenDecimals: decimals } = await getChainProperties(connector, networkId);
5720
5731
  if (!miniMetadata.extra.existentialDeposit) log_default.warn(`Substrate native module: existentialDeposit is undefined for ${networkId}, using 0`);
5721
5732
  const tokenConfig = tokens[0];
5722
- const token = assign({
5733
+ const nativeToken = {
5723
5734
  id: subNativeTokenId(networkId),
5724
5735
  type: "substrate-native",
5725
5736
  platform: "polkadot",
@@ -5729,7 +5740,8 @@ const fetchTokens$2 = async ({ networkId, tokens, connector, miniMetadata }) =>
5729
5740
  name: symbol,
5730
5741
  decimals,
5731
5742
  existentialDeposit: miniMetadata.extra.existentialDeposit ?? "0"
5732
- }, tokenConfig);
5743
+ };
5744
+ const token = assign(nativeToken, tokenConfig);
5733
5745
  const parsed = SubNativeTokenSchema.safeParse(token);
5734
5746
  if (!parsed.success) return [];
5735
5747
  return [parsed.data];
@@ -5895,7 +5907,8 @@ const subscribeBalances$2 = ({ networkId, tokensWithAddresses, connector, miniMe
5895
5907
  await yieldToEventLoop();
5896
5908
  return buildBaseQueries(networkId, balanceDefs, miniMetadata);
5897
5909
  }).pipe(switchMap((baseQueries) => getRpcQueryPack$(connector, networkId, baseQueries)), switchMap((partialBalances) => {
5898
- return getRpcQueryPack$(connector, networkId, buildNomPoolQueries(networkId, partialBalances, miniMetadata));
5910
+ const nomPoolQueries = buildNomPoolQueries(networkId, partialBalances, miniMetadata);
5911
+ return getRpcQueryPack$(connector, networkId, nomPoolQueries);
5899
5912
  }), map((balances) => ({
5900
5913
  success: balances,
5901
5914
  errors: []
@@ -6669,7 +6682,8 @@ const fetchBalances = async ({ networkId, tokensWithAddresses, connector, miniMe
6669
6682
  }))
6670
6683
  };
6671
6684
  }
6672
- const balances = await fetchRpcQueryPack(connector, networkId, buildQueries(networkId, balanceDefs, miniMetadata));
6685
+ const queries = buildQueries(networkId, balanceDefs, miniMetadata);
6686
+ const balances = await fetchRpcQueryPack(connector, networkId, queries);
6673
6687
  return balanceDefs.reduce((acc, def) => {
6674
6688
  const balance = balances.find((b) => b?.address === def.address && b?.tokenId === def.token.id);
6675
6689
  if (balance) acc.success.push(balance);
@@ -7062,7 +7076,9 @@ var BalancesProvider = class {
7062
7076
  return getDetectedTokensIds$(address);
7063
7077
  }
7064
7078
  getNetworkBalances$(networkId, addressesByTokenId) {
7065
- return combineLatest([this.#chaindataProvider.getNetworkById$(networkId), this.#chaindataProvider.getTokensMapById$()]).pipe(map(([network, tokensMapById]) => ({
7079
+ const network$ = this.#chaindataProvider.getNetworkById$(networkId);
7080
+ const tokensMapById$ = this.#chaindataProvider.getTokensMapById$();
7081
+ return combineLatest([network$, tokensMapById$]).pipe(map(([network, tokensMapById]) => ({
7066
7082
  network,
7067
7083
  tokens: keys(addressesByTokenId).map((tokenId) => tokensMapById[tokenId])
7068
7084
  })), distinctUntilChanged((a, b) => a.network === b.network && a.tokens.every((token, i) => token === b.tokens[i])), switchMap(({ network, tokens }) => {
@@ -7437,7 +7453,7 @@ const getStaleVariant = (balance) => {
7437
7453
  }
7438
7454
  return variant;
7439
7455
  };
7440
- const LIVE_SEED_MAX_AGE_MS = 5 * 6e4;
7456
+ const LIVE_SEED_MAX_AGE_MS = 3e5;
7441
7457
  const liveVariants = /* @__PURE__ */ new WeakMap();
7442
7458
  const seededLiveVariants = /* @__PURE__ */ new WeakSet();
7443
7459
  const getLiveVariant = (balance) => {