diff --git a/packages/adapter/src/extension/index.ts b/packages/adapter/src/extension/index.ts index 2b807cd2..d81a17cd 100644 --- a/packages/adapter/src/extension/index.ts +++ b/packages/adapter/src/extension/index.ts @@ -21,9 +21,10 @@ interface IInjectPolkadotSnap extends IEnablePolkadotSnapParams { injectedSnapId?: string; } -function transformAccounts(accounts: string[]): InjectedAccount[] { +function transformAccounts(accounts: string[], config?: SnapConfig): InjectedAccount[] { return accounts.map((address, i) => ({ address, + genesisHash: config?.genesisHash, name: `Polkadot Snap #${i}`, type: 'ed25519' })); @@ -42,11 +43,13 @@ function injectPolkadotSnap({ await enablePolkadotSnap(config, snapOrigin, snapInstallationParams) ).getMetamaskSnapApi(); + const snapConfiguration = await snap.getConfiguration(); + return { accounts: { get: async (): Promise => { const response = await snap.getAddress(); - return transformAccounts([response]); + return transformAccounts([response], snapConfiguration); }, // Currently there is only available only one account, in that case this method will never return anything // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/packages/adapter/src/methods.ts b/packages/adapter/src/methods.ts index 82d39ad8..16f7ea79 100644 --- a/packages/adapter/src/methods.ts +++ b/packages/adapter/src/methods.ts @@ -80,6 +80,10 @@ export async function exportAccount( )) as string; } +export async function getConfiguration(this: MetamaskPolkadotSnap): Promise { + return (await sendSnapMethod({ method: 'getConfiguration' }, this.snapId)) as SnapConfig; +} + export async function setConfiguration( this: MetamaskPolkadotSnap, config: SnapConfig diff --git a/packages/adapter/src/snap.ts b/packages/adapter/src/snap.ts index 10087cb9..1ff98d4e 100644 --- a/packages/adapter/src/snap.ts +++ b/packages/adapter/src/snap.ts @@ -6,6 +6,7 @@ import { getAddress, getAllTransactions, getBalance, + getConfiguration, getLatestBlock, getPublicKey, sendSignedData, @@ -39,6 +40,7 @@ export class MetamaskPolkadotSnap { getLatestBlock: getLatestBlock.bind(this), getPublicKey: getPublicKey.bind(this), send: sendSignedData.bind(this), + getConfiguration: getConfiguration.bind(this), setConfiguration: setConfiguration.bind(this), signPayloadJSON: signPayloadJSON.bind(this), signPayloadRaw: signPayloadRaw.bind(this) diff --git a/packages/adapter/src/types.ts b/packages/adapter/src/types.ts index 81d42e8c..1f293382 100644 --- a/packages/adapter/src/types.ts +++ b/packages/adapter/src/types.ts @@ -22,6 +22,8 @@ export interface MetamaskSnapApi { getLatestBlock(): Promise; + getConfiguration(): Promise; + setConfiguration(configuration: SnapConfig): Promise; getAllTransactions(): Promise; diff --git a/packages/example/src/components/CustomNetworkConfig/CustomNetworkConfig.tsx b/packages/example/src/components/CustomNetworkConfig/CustomNetworkConfig.tsx index 6524b604..609a66d8 100644 --- a/packages/example/src/components/CustomNetworkConfig/CustomNetworkConfig.tsx +++ b/packages/example/src/components/CustomNetworkConfig/CustomNetworkConfig.tsx @@ -4,6 +4,7 @@ import { useState } from 'react'; export type CustomNetworkConfigInput = { networkName?: string; + genesisHash?: `0x${string}`; rpcUrl?: string; addressPrefix?: number; unitDecimals?: number; @@ -53,6 +54,10 @@ export const CustonNetworkConfig: FC = ({ onSubmit }) => { Network name + + Network genesis hash + + RPC url diff --git a/packages/example/src/containers/Dashboard/Dashboard.tsx b/packages/example/src/containers/Dashboard/Dashboard.tsx index 1fcc7329..03ffbec6 100644 --- a/packages/example/src/containers/Dashboard/Dashboard.tsx +++ b/packages/example/src/containers/Dashboard/Dashboard.tsx @@ -11,7 +11,12 @@ import { Select, Typography } from '@material-ui/core'; -import type { BlockInfo, SnapNetworks, Transaction } from '@chainsafe/metamask-polkadot-types'; +import type { + BlockInfo, + SnapNetworks, + Transaction, + SupportedSnapNetworks +} from '@chainsafe/metamask-polkadot-types'; import type { MetamaskSnapApi } from '@chainsafe/metamask-polkadot-adapter/src/types'; import { Transfer } from '../../components/Transfer/Transfer'; import { SignMessage } from '../../components/SignMessage/SignMessage'; @@ -52,7 +57,7 @@ export const Dashboard = (): React.JSX.Element => { return; } else setCustomNetworkInputs(false); - const networkName = event.target.value as SnapNetworks; + const networkName = event.target.value as SupportedSnapNetworks; if (networkName === network) return; if (!api) return; await api.setConfiguration({ networkName: networkName }); @@ -60,11 +65,12 @@ export const Dashboard = (): React.JSX.Element => { }; const onCustomNetworkConnect = async (submitData: CustomNetworkConfigInput): Promise => { - const { networkName, rpcUrl, addressPrefix } = submitData; + const { networkName, genesisHash, rpcUrl, addressPrefix } = submitData; - if (!api || !networkName || !rpcUrl || !addressPrefix) return; + if (!api || !networkName || !genesisHash || !rpcUrl || !addressPrefix) return; const configuration = { - networkName: networkName, + networkName, + genesisHash, wsRpcUrl: rpcUrl, addressPrefix: addressPrefix, unit: { diff --git a/packages/snap/snap.manifest.json b/packages/snap/snap.manifest.json index d06d5c46..292476fb 100644 --- a/packages/snap/snap.manifest.json +++ b/packages/snap/snap.manifest.json @@ -7,7 +7,7 @@ "url": "git+https://github.com/chainsafe/metamask-snap-polkadot.git" }, "source": { - "shasum": "o2JYBxUWDxVyQEX+K7O58mlhetpKywdog+dHPGXj98U=", + "shasum": "Rox1dBkfYddPGejHC+G8uQ/MZeUf+T36mtTFB5qnTy8=", "location": { "npm": { "filePath": "dist/bundle.js", diff --git a/packages/snap/src/configuration/predefined.ts b/packages/snap/src/configuration/predefined.ts index 71dd2fe7..f3f08792 100644 --- a/packages/snap/src/configuration/predefined.ts +++ b/packages/snap/src/configuration/predefined.ts @@ -3,6 +3,7 @@ import type { SnapConfig } from '@chainsafe/metamask-polkadot-types'; export const kusamaConfiguration: SnapConfig = { addressPrefix: 2, networkName: 'kusama', + genesisHash: '0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe', unit: { decimals: 12, image: 'https://svgshare.com/i/L3o.svg', @@ -14,6 +15,7 @@ export const kusamaConfiguration: SnapConfig = { export const westendConfiguration: SnapConfig = { addressPrefix: 42, networkName: 'westend', + genesisHash: '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e', unit: { decimals: 12, image: 'https://svgshare.com/i/L2d.svg', @@ -25,6 +27,7 @@ export const westendConfiguration: SnapConfig = { export const polkadotConfiguration: SnapConfig = { addressPrefix: 0, networkName: 'polkadot', + genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3', unit: { decimals: 12, image: 'https://polkadot.js.org/apps/static/polkadot-circle.1eea41b2..svg', diff --git a/packages/snap/src/index.ts b/packages/snap/src/index.ts index c5ca25d6..e41e8315 100644 --- a/packages/snap/src/index.ts +++ b/packages/snap/src/index.ts @@ -24,6 +24,7 @@ import { validSignPayloadRawSchema } from './util/validation'; import { exportAccount } from './rpc/exportAccount'; +import { getConfiguration } from './configuration'; const apiDependentMethods = [ 'getBlock', @@ -78,6 +79,8 @@ export const onRpcRequest: OnRpcRequestHandler = async ({ request }) => { case 'getBalance': { return await getBalance(api); } + case 'getConfiguration': + return await getConfiguration(); case 'configure': { const state = (await snap.request({ method: 'snap_manageState', diff --git a/packages/snap/test/unit/rpc/configure.test.ts b/packages/snap/test/unit/rpc/configure.test.ts index 27a5c532..81c32654 100644 --- a/packages/snap/test/unit/rpc/configure.test.ts +++ b/packages/snap/test/unit/rpc/configure.test.ts @@ -38,6 +38,7 @@ describe('Test rpc handler function: configure', function () { const customConfiguration: SnapConfig = { addressPrefix: 1, networkName: 'westend', + genesisHash: '0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e', unit: { customViewUrl: 'custom-view-url', decimals: 1, image: 'image', symbol: 'TST' }, wsRpcUrl: 'ws-rpc-url' }; diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts index d1dd8fa4..f94aeb83 100644 --- a/packages/types/index.d.ts +++ b/packages/types/index.d.ts @@ -16,7 +16,7 @@ export interface ExportAccountRequest { method: 'exportAccount'; params: { jsonPassphrase?: string; - } + }; } export interface GetTransactionsRequest { @@ -34,6 +34,10 @@ export interface GetBalanceRequest { method: 'getBalance'; } +export interface GetConfigurationRequest { + method: 'getConfiguration'; +} + export interface ConfigureSnapRequest { method: 'configure'; params: { @@ -87,6 +91,7 @@ export type MetamaskPolkadotRpcRequest = | GetTransactionsRequest | GetBlockRequest | GetBalanceRequest + | GetConfigurationRequest | ConfigureSnapRequest | AddPolkadotAssetRequest | GetChainHeadRequest @@ -132,14 +137,18 @@ export interface UnitConfiguration { customViewUrl?: string; } -export type SnapNetworks = 'polkadot' | 'kusama' | 'westend' | string; +export type SupportedSnapNetworks = 'polkadot' | 'kusama' | 'westend'; -export interface SnapConfig { - networkName: SnapNetworks; +export type SnapNetworks = SupportedSnapNetworks | string; + +export type SnapConfig = { wsRpcUrl?: string; addressPrefix?: number; unit?: UnitConfiguration; -} +} & ( + | { networkName: SupportedSnapNetworks; genesisHash?: `0x${string}` } + | { networkName: SnapNetworks; genesisHash: `0x${string}` } +); // Polkadot types