Skip to content
This repository has been archived by the owner on Dec 3, 2024. It is now read-only.

Commit

Permalink
feat: add genesis hash to injected accounts (#236)
Browse files Browse the repository at this point in the history
DApp will use this to determine which network can the account be used
with. This is especially important in this case, as accounts are always
restricted to one network.
  • Loading branch information
tien authored Jul 3, 2024
1 parent ae02ce9 commit bc73e6c
Show file tree
Hide file tree
Showing 11 changed files with 51 additions and 13 deletions.
7 changes: 5 additions & 2 deletions packages/adapter/src/extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}));
Expand All @@ -42,11 +43,13 @@ function injectPolkadotSnap({
await enablePolkadotSnap(config, snapOrigin, snapInstallationParams)
).getMetamaskSnapApi();

const snapConfiguration = await snap.getConfiguration();

return {
accounts: {
get: async (): Promise<InjectedAccount[]> => {
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
Expand Down
4 changes: 4 additions & 0 deletions packages/adapter/src/methods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ export async function exportAccount(
)) as string;
}

export async function getConfiguration(this: MetamaskPolkadotSnap): Promise<SnapConfig> {
return (await sendSnapMethod({ method: 'getConfiguration' }, this.snapId)) as SnapConfig;
}

export async function setConfiguration(
this: MetamaskPolkadotSnap,
config: SnapConfig
Expand Down
2 changes: 2 additions & 0 deletions packages/adapter/src/snap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
getAddress,
getAllTransactions,
getBalance,
getConfiguration,
getLatestBlock,
getPublicKey,
sendSignedData,
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 2 additions & 0 deletions packages/adapter/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export interface MetamaskSnapApi {

getLatestBlock(): Promise<BlockInfo>;

getConfiguration(): Promise<SnapConfig>;

setConfiguration(configuration: SnapConfig): Promise<void>;

getAllTransactions(): Promise<Transaction[]>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useState } from 'react';

export type CustomNetworkConfigInput = {
networkName?: string;
genesisHash?: `0x${string}`;
rpcUrl?: string;
addressPrefix?: number;
unitDecimals?: number;
Expand Down Expand Up @@ -53,6 +54,10 @@ export const CustonNetworkConfig: FC<ICustonNetworkConfig> = ({ onSubmit }) => {
<InputLabel htmlFor="networkName">Network name</InputLabel>
<Input name="networkName" onChange={onInputChange} />
</FormControl>
<FormControl required>
<InputLabel htmlFor="genesisHash">Network genesis hash</InputLabel>
<Input name="genesisHash" onChange={onInputChange} />
</FormControl>
<FormControl required>
<InputLabel htmlFor="rpcUrl">RPC url</InputLabel>
<Input required placeholder="rpc url" name="rpcUrl" onChange={onInputChange} />
Expand Down
16 changes: 11 additions & 5 deletions packages/example/src/containers/Dashboard/Dashboard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -52,19 +57,20 @@ 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 });
setNetwork(networkName);
};

const onCustomNetworkConnect = async (submitData: CustomNetworkConfigInput): Promise<void> => {
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: {
Expand Down
2 changes: 1 addition & 1 deletion packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions packages/snap/src/configuration/predefined.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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',
Expand All @@ -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',
Expand Down
3 changes: 3 additions & 0 deletions packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
validSignPayloadRawSchema
} from './util/validation';
import { exportAccount } from './rpc/exportAccount';
import { getConfiguration } from './configuration';

const apiDependentMethods = [
'getBlock',
Expand Down Expand Up @@ -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',
Expand Down
1 change: 1 addition & 0 deletions packages/snap/test/unit/rpc/configure.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
};
Expand Down
19 changes: 14 additions & 5 deletions packages/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export interface ExportAccountRequest {
method: 'exportAccount';
params: {
jsonPassphrase?: string;
}
};
}

export interface GetTransactionsRequest {
Expand All @@ -34,6 +34,10 @@ export interface GetBalanceRequest {
method: 'getBalance';
}

export interface GetConfigurationRequest {
method: 'getConfiguration';
}

export interface ConfigureSnapRequest {
method: 'configure';
params: {
Expand Down Expand Up @@ -87,6 +91,7 @@ export type MetamaskPolkadotRpcRequest =
| GetTransactionsRequest
| GetBlockRequest
| GetBalanceRequest
| GetConfigurationRequest
| ConfigureSnapRequest
| AddPolkadotAssetRequest
| GetChainHeadRequest
Expand Down Expand Up @@ -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

Expand Down

0 comments on commit bc73e6c

Please sign in to comment.