Skip to content

Commit

Permalink
feat: Auto update metadata while fetching accounts balances (#1517)
Browse files Browse the repository at this point in the history
Co-authored-by: Nick <ekbatanifard@gmail.com>
  • Loading branch information
AMIRKHANEF and Nick-1979 authored Sep 21, 2024
1 parent 4c9e2ff commit 17367eb
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 9 deletions.
12 changes: 12 additions & 0 deletions packages/extension-base/src/background/handlers/Extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,15 @@ export default class Extension {
return true;
}

// added for PolkaGate
private metadataUpdate(metadata: MetadataDef): boolean {
assert(metadata, 'Unable to update metadata');

this.#state.saveMetadata(metadata);

return true;
}

private jsonRestore ({ file, password }: RequestJsonRestore): void {
try {
const pair = keyring.restoreAccount(file, password);
Expand Down Expand Up @@ -631,6 +640,9 @@ export default class Extension {
case 'pri(metadata.requests)':
return this.metadataSubscribe(id, port);

case 'pri(metadata.update)': // added for polkagate
return this.metadataUpdate(request as MetadataDef);

case 'pri(derivation.create)':
return this.derivationCreate(request as RequestDeriveCreate);

Expand Down
1 change: 1 addition & 0 deletions packages/extension-base/src/background/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ export interface RequestSignatures {
'pri(accounts.updateMeta)': [RequestUpdateMeta, boolean]; // added for polkagate
'pri(extension.lock)': [null, boolean]; // added for polkagate
'pri(authorize.ignore)': [string, void]; // added for polkagate
'pri(metadata.update)': [MetadataDef, boolean]; // added for polkagate

'pri(accounts.export)': [RequestAccountExport, ResponseAccountExport];
'pri(accounts.batchExport)': [RequestAccountBatchExport, ResponseAccountsExport]
Expand Down
27 changes: 27 additions & 0 deletions packages/extension-polkagate/src/hooks/useAssetsBalances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import type { Asset } from '@polkagate/apps-config/assets/types';
import type { AccountJson } from '@polkadot/extension-base/background/types';
import type { MetadataDef } from '@polkadot/extension-inject/types';
import type { AlertType } from '../util/types';

import { createAssets } from '@polkagate/apps-config/assets';
Expand All @@ -14,6 +15,7 @@ import { BN, isObject } from '@polkadot/util';

import { getStorage, setStorage, watchStorage } from '../components/Loading';
import { toCamelCase } from '../fullscreen/governance/utils/util';
import { updateMetadata } from '../messaging';
import allChains from '../util/chains';
import { ASSET_HUBS, RELAY_CHAINS_GENESISHASH, TEST_NETS } from '../util/constants';
import getChainName from '../util/getChainName';
Expand Down Expand Up @@ -313,6 +315,14 @@ export default function useAssetsBalances (accounts: AccountJson[] | null, setAl

const parsedMessage = JSON.parse(message) as WorkerMessage;

if ('metadata' in parsedMessage) {
const metadata = parsedMessage['metadata'];

updateMetadata(metadata as unknown as MetadataDef).catch(console.error);

return;
}

Object.keys(parsedMessage).forEach((address) => {
/** We use index 0 because we consider each relay chain has only one asset */
_assets[address] = [
Expand Down Expand Up @@ -358,6 +368,14 @@ export default function useAssetsBalances (accounts: AccountJson[] | null, setAl

const parsedMessage = JSON.parse(message) as WorkerMessage;

if ('metadata' in parsedMessage) {
const metadata = parsedMessage['metadata'];

updateMetadata(metadata as unknown as MetadataDef).catch(console.error);

return;
}

Object.keys(parsedMessage).forEach((address) => {
_assets[address] = parsedMessage[address]
.map((message) => {
Expand Down Expand Up @@ -402,6 +420,15 @@ export default function useAssetsBalances (accounts: AccountJson[] | null, setAl
}

const parsedMessage = JSON.parse(message) as WorkerMessage;

if ('metadata' in parsedMessage) {
const metadata = parsedMessage['metadata'];

updateMetadata(metadata as unknown as MetadataDef).catch(console.error);

return;
}

const _assets: Assets = {};

Object.keys(parsedMessage).forEach((address) => {
Expand Down
5 changes: 5 additions & 0 deletions packages/extension-polkagate/src/messaging.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ export async function subscribeMetadataRequests (cb: (accounts: MetadataRequest[
return sendMessage('pri(metadata.requests)', null, cb);
}

// added for polkagate
export async function updateMetadata (metadata: MetadataDef): Promise<boolean> {
return sendMessage('pri(metadata.update)', metadata);
}

export async function subscribeSigningRequests (cb: (accounts: SigningRequest[]) => void): Promise<boolean> {
return sendMessage('pri(signing.requests)', null, cb);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/extension-polkagate/src/popup/home/news.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ export interface News {
}

export const news: News[] = [
{
version: '0.10.1',
notes: [
'Auto Metadata Update: Metadata will be automatically updated in the background on supported chains, so manual updates are no longer necessary.'
]
},
{
version: '0.10.0',
notes: [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
import { BN_ZERO } from '@polkadot/util';

// eslint-disable-next-line import/extensions
import { closeWebsockets, fastestEndpoint, getChainEndpoints, toGetNativeToken } from './utils';
import { closeWebsockets, fastestEndpoint, getChainEndpoints, metadataFromApi, toGetNativeToken } from './utils';

// @ts-ignore
async function getAssetOnAssetHub(addresses, assetsToBeFetched, chainName) {
async function getAssetOnAssetHub (addresses, assetsToBeFetched, chainName) {
const endpoints = getChainEndpoints(chainName);
const { api, connections } = await fastestEndpoint(endpoints, false);

const result = metadataFromApi(api);

postMessage(JSON.stringify(result));

const results = await toGetNativeToken(addresses, api, chainName);

// @ts-ignore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ import { createAssets } from '@polkagate/apps-config/assets';

import { getSubstrateAddress } from '../utils';
// eslint-disable-next-line import/extensions
import { balancifyAsset, closeWebsockets, fastestEndpoint, getChainEndpoints, toGetNativeToken } from './utils';
import { balancifyAsset, closeWebsockets, fastestEndpoint, getChainEndpoints, metadataFromApi, toGetNativeToken } from './utils';

async function getAssets (addresses, assetsToBeFetched, chainName) {
const endpoints = getChainEndpoints(chainName);
const { api, connections } = await fastestEndpoint(endpoints, false);

const result = metadataFromApi(api);

postMessage(JSON.stringify(result));

const results = await toGetNativeToken(addresses, api, chainName);

const maybeTheAssetOfAddresses = addresses.map((address) => api.query.tokens.accounts.entries(address));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@

import { BN, BN_ONE, BN_ZERO } from '@polkadot/util';

import { NATIVE_TOKEN_ASSET_ID,TEST_NETS } from '../constants';
import { NATIVE_TOKEN_ASSET_ID, TEST_NETS } from '../constants';
import getPoolAccounts from '../getPoolAccounts';
import { getPriceIdByChainName } from '../utils';
import { balancify, closeWebsockets, fastestEndpoint, getChainEndpoints } from './utils';
import { balancify, closeWebsockets, fastestEndpoint, getChainEndpoints, metadataFromApi } from './utils';

async function getPooledBalance (api, address) {
const response = await api.query['nominationPools']['poolMembers'](address);
Expand Down Expand Up @@ -54,6 +54,10 @@ async function getBalances (chainName, addresses) {
const { api, connections } = await fastestEndpoint(chainEndpoints, false);

if (api.isConnected && api.derive.balances) {
const result = metadataFromApi(api);

postMessage(JSON.stringify(result));

const requests = addresses.map(async (address) => {
const balances = await api.derive.balances.all(address);
const systemBalance = await api.query.system.account(address);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0
// @ts-nocheck

// @ts-nocheck

export * from './balancify.js';
export * from './closeWebsockets.js';
export * from './fastestEndpoint.js';
export * from './getChainEndpoints.js';
export * from './balancify.js';
export * from './metadataFromApi';
export * from './toGetNativeToken.js';
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright 2019-2024 @polkadot/extension-polkagate authors & contributors
// SPDX-License-Identifier: Apache-2.0

import type { ApiPromise } from '@polkadot/api';
import type { MetadataDef } from '@polkadot/extension-inject/types';

import { createWsEndpoints } from '@polkagate/apps-config';

import { getSpecTypes } from '@polkadot/types-known';
import { formatBalance, isNumber } from '@polkadot/util';
import { base64Encode } from '@polkadot/util-crypto';

const endpoints = createWsEndpoints();

export function metadataFromApi (api: ApiPromise): {metadata: MetadataDef} {
const DEFAULT_DECIMALS = api.registry.createType('u32', 12);
const DEFAULT_SS58 = api.registry.createType('u32', 42);
const chainName = api.runtimeChain.toHuman();
const apiGenesisHash = api.genesisHash.toHex();
const color = endpoints.find(({ genesisHash, ui }) => genesisHash === apiGenesisHash && ui.color)?.ui?.color;

const metadata = {
chain: chainName,
chainType: 'substrate' as 'ethereum' | 'substrate',
color,
genesisHash: apiGenesisHash,
icon: 'substrate',
metaCalls: base64Encode(api.runtimeMetadata.asCallsOnly.toU8a()),
specVersion: api.runtimeVersion.specVersion.toNumber(),
ss58Format: isNumber(api.registry.chainSS58)
? api.registry.chainSS58
: DEFAULT_SS58.toNumber(),
tokenDecimals: (api.registry.chainDecimals || [DEFAULT_DECIMALS.toNumber()])[0],
tokenSymbol: (api.registry.chainTokens || formatBalance.getDefaults().unit)[0],
types: getSpecTypes(api.registry, chainName, api.runtimeVersion.specName, api.runtimeVersion.specVersion) as Record<string, string | Record<string, string>>
};

return { metadata };
}

0 comments on commit 17367eb

Please sign in to comment.