PolkaGate / snap

Polkagate Snap: Polkadot with Metamask
https://polkagate.xyz
Apache License 2.0
0 stars 4 forks source link

not support for substrate chain #24

Closed BurnWW closed 2 months ago

BurnWW commented 4 months ago

During usage, we have found that the current Snap does not support substrate chains other than parachains. Are there considerations to provide support for more chains in the future? Given the increasing popularity of Coretime, a greater number of chains will be joining the ecosystem. Currently, the process of obtaining the WS_URL through { selectableNetworks } from '@polkadot/apps-config'; is hindering the adoption and use of a large number of substrate chains.

Nick-1979 commented 4 months ago

@BurnWW do you have any suggestions how to get RPC urls to support more chains?

BurnWW commented 4 months ago

@Nick-1979 I took the time to validate the feasibility of my idea, and I hope that instead of connecting to blockchain networks within Snap, we can directly use metadata for signing. This is the code that I have successfully verified.

packages/snap/src/rpc/signJSON.ts

import { SignerPayloadJSON } from '@polkadot/types/types';
import type { SignerResult } from '@polkadot/api/types';
import { getApi } from '../util/getApi';
import { getKeyPair, getKeyPairFromMetadata } from '../util/getKeyPair';
import { checkAndUpdateMetaData, getSavedMeta, showConfirmTx } from '.';
import { metadataExpand } from '@polkadot/extension-chains';

export const signJSON = async (
  origin: string,
  payload: SignerPayloadJSON,
): Promise<SignerResult | undefined> => {
  try {
    const def = await getSavedMeta(payload.genesisHash);
    if (def) {
      const chain = metadataExpand(def!, false)
      chain.registry.signedExtensions

      const registry = chain.registry;
      registry.setSignedExtensions(payload.signedExtensions, chain.definition.userExtensions);
      const keyPair = await getKeyPairFromMetadata(chain);

      const { signature } = registry
        .createType('ExtrinsicPayload', payload, { version: payload.version })
        .sign(keyPair);

      return { id: 1, signature };
    }

    ......
  } catch (e) {
    console.info('Error while signing JSON:', e);
    return undefined;
  }
};
export const getKeyPairFromMetadata = async (
  chain: Chain
): Promise<KeyringPair> => {
  const prefix = chain.ss58Format

  const BIP44CoinNode = (await snap.request({
    method: 'snap_getBip44Entropy',
    params: {
      coinType: DEFAULT_COIN_TYPE,
    },
  })) as JsonBIP44CoinTypeNode;

  const seed = BIP44CoinNode?.privateKey?.slice(0, 32);
  const keyring = new Keyring({ ss58Format: prefix });
  const keyPair = keyring.addFromSeed(stringToU8a(seed));

  return keyPair;
};