Skip to content

Commit

Permalink
add export account
Browse files Browse the repository at this point in the history
exported json
  • Loading branch information
Nick-1979 committed Jun 21, 2024
1 parent eb09096 commit 6107210
Show file tree
Hide file tree
Showing 17 changed files with 275 additions and 120 deletions.
File renamed without changes.
2 changes: 1 addition & 1 deletion packages/snap/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@polkagate/snap",
"version": "0.2.3",
"version": "0.3.0",
"description": "A MetaMask Snap to interact with Polkadot ecosystem, a platform for cross-chain communication and scalability. Use your MetaMask wallet to access Polkadot dApps and tokens. No extra extension needed.",
"repository": {
"type": "git",
Expand Down
8 changes: 6 additions & 2 deletions packages/snap/snap.manifest.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"version": "0.2.3",
"version": "0.3.0",
"description": "Explore Polkadot decentralized applications and manage your tokens using your MetaMask wallet. Start your journey at apps.polkagate.xyz.",
"proposedName": "PolkaGate",
"repository": {
"type": "git",
"url": "https://github.com/polkagate/snap.git"
},
"source": {
"shasum": "QJbEjZQBTNNCpfJ/dXrflv8lBho8Z1ZteFOIhJOD5js=",
"shasum": "MCRX17YL353EhPXMmobvxgBNDRStBIA0ATAin1JvPxM=",
"location": {
"npm": {
"filePath": "dist/bundle.js",
Expand All @@ -17,6 +17,10 @@
}
}
},
"initialConnections": {
"https://apps.polkagate.xyz": {},
"https://staking.polkadot.network": {}
},
"initialPermissions": {
"endowment:network-access": {},
"endowment:page-home": {},
Expand Down
67 changes: 44 additions & 23 deletions packages/snap/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,25 @@ import type {

import { getGenesisHash } from './chains';
import { DEFAULT_CHAIN_NAME } from './defaults';
import { getAddress, signJSON, signRaw } from './rpc';
import { getMetadataList, setMetadata, updateState } from './rpc/metadata';
import { accountDemo } from './ui/accountDemo';
import { accountInfo } from './ui/accountInfo';
import { showDappList } from './ui/dappList';
import { showSpinner, showTransferInputs, transfer } from './ui/transfer';
import { getBalances2 } from './util/getBalance';
import { getCurrentChain } from './util/getCurrentChain';
import { getKeyPair } from './util/getKeyPair';
import {
getMetadataList,
setMetadata,
updateState,
getAddress,
signJSON,
signRaw,
} from './rpc';
import {
showSpinner,
accountDemo,
accountInfo,
showDappList,
transferReview,
exportAccount,
showJsonContent,
getNextChain,
} from './ui';
import { getBalances2, getCurrentChain, getKeyPair } from './util';

export const onRpcRequest: OnRpcRequestHandler = async ({
origin,
Expand Down Expand Up @@ -81,7 +91,7 @@ export const onInstall: OnInstallHandler = async () => {
heading('🏠 Your account is now created 🚀'),
divider(),
text(
"To access your account's information, navigate to Menu → Snaps and click on the Polkagate icon.",
"To access your account's information, navigate to **Menu → Snaps** and click on the Polkagate icon.",
),
text(
'To manage your account, please visit: **[https://apps.polkagate.xyz](https://apps.polkagate.xyz)**',
Expand All @@ -94,38 +104,49 @@ export const onInstall: OnInstallHandler = async () => {
export const onUserInput: OnUserInputHandler = async ({ id, event }) => {
if (event.type === UserInputEventType.ButtonClickEvent) {
switch (event.name) {
case 'switchChain':
case 'switchChain': {
await showSpinner(id, 'Switching chain ...');
await accountInfo(id);
break;

case 'transfer':
await showTransferInputs(id);
const nextChainName = await getNextChain();
await accountInfo(id, nextChainName);
break;
}

case 'dapp':
await showDappList(id);
break;

case 'showExportAccount':
await exportAccount(id);
break;

case 'backToHome':
await showSpinner(id, 'Loading ...');
await accountInfo(id);
break;

default:
break;
}
}

if (event.type === UserInputEventType.FormSubmitEvent) {
const chainName = await getCurrentChain();

const value = { ...(event?.value || {}), chainName } as unknown as Record<
string,
string
>;
const { value } = event;

switch (event.name) {
case 'transferInput':
if (!event?.value?.amount) {
break;
}
await showSpinner(id);
await transfer(id, value);
await transferReview(id, value);
break;

case 'saveExportedAccount': {
await showSpinner(id, 'Exporting the account ...');

await showJsonContent(id, value?.password);
break;
}
default:
break;
}
Expand Down
7 changes: 4 additions & 3 deletions packages/snap/src/rpc/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { divider, heading, panel, text } from '@metamask/snaps-sdk';
import type { ApiPromise } from '@polkadot/api';
import type {
InjectedMetadataKnown,
MetadataDef,
} from '@polkadot/extension-inject/types';
import { divider, heading, panel, text } from '@metamask/snaps-sdk';
import type { ApiPromise } from '@polkadot/api';

import getChainInfo from '../util/getChainInfo';
import { rand } from '../util/rand';

Expand Down Expand Up @@ -112,6 +113,6 @@ export const checkAndUpdateMetaData = async (api: ApiPromise) => {
const metaData = await getChainInfo(api);
if (metaData) {
selfOrigin = `Polkagate-${rand()}`;
setMetadata(selfOrigin, metaData);
await setMetadata(selfOrigin, metaData);
}
};
17 changes: 11 additions & 6 deletions packages/snap/src/ui/accountDemo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,25 @@ export const accountDemo = (
row('Transferable', text(`**${transferable.toHuman()}**`)),
row('Locked', text(`**${locked.toHuman()}**`)),
divider(),
// button({
// value: 'Transfer fund',
// name: 'transfer',
// }),
button({
value: 'Transfer fund',
name: 'transfer',
}),
button({
variant: 'secondary',
value: 'View App list',
variant: 'primary',
value: 'View dApp list',
name: 'dapp',
}),
button({
variant: 'secondary',
value: 'Click to switch chain',
name: 'switchChain',
}),
button({
variant: 'secondary',
value: 'Export account',
name: 'showExportAccount',
}),
]),
]);
};
27 changes: 17 additions & 10 deletions packages/snap/src/ui/accountInfo.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
/* eslint-disable no-case-declarations */
/* eslint-disable jsdoc/require-jsdoc */

import { accountDemo } from './accountDemo';
import { getGenesisHash } from '../chains';
import { getKeyPair } from '../util/getKeyPair';
import { getBalances2 } from '../util/getBalance';
import { getState, updateState } from '../rpc';
import { DEFAULT_CHAIN_NAME, CHAIN_NAMES } from '../defaults';
import { accountDemo } from './accountDemo';
import { getState, updateState } from '../rpc';
import { getCurrentChain } from '../util';
import { getBalances2 } from '../util/getBalance';
import { getKeyPair } from '../util/getKeyPair';

/**
* Returns the next chain in a circular way.
*/
export async function getNextChain() {
const state = await getState();
console.log('state in getNextChain', state);

const currentChainName = (state?.currentChain ||
const currentChainName = (state?.currentChain ??
DEFAULT_CHAIN_NAME) as string;
const index = CHAIN_NAMES.findIndex((name) => name === currentChainName);

Expand All @@ -25,16 +26,22 @@ export async function getNextChain() {
}

// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
(state || {}).currentChain = nextChainName;
(state ?? {}).currentChain = nextChainName;
console.log('update state in getNextChain', state);

await updateState(state);

return nextChainName;
}

/**
* Show account info on the current chain.
*
* @param id - The id of current UI interface.
* @param chainName - Current chain name.
*/
export async function accountInfo(id: string, chainName?: string) {
const _chainName = chainName || (await getNextChain());
const _chainName = chainName ?? (await getCurrentChain());

const { address } = await getKeyPair(_chainName);

Expand Down
12 changes: 9 additions & 3 deletions packages/snap/src/ui/dappList.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { heading, panel, text, divider } from '@metamask/snaps-sdk';
import { button, heading, panel, text, divider } from '@metamask/snaps-sdk';

/**
* This shows a dapp list to users.
Expand All @@ -11,16 +11,22 @@ export async function showDappList(id: string) {
params: {
id,
ui: panel([
heading('App List'),
heading('dApp List'),
divider(),
text(
'Explore these Apps to streamline your daily tasks and engage with the Polkadot ecosystem',
'Explore these dApps to streamline your daily tasks and engage with the Polkadot ecosystem.',
),
text('General : **[apps.polkagate.xyz](https://apps.polkagate.xyz)**'),
text(
'Staking : **[staking.polkadot.network](https://staking.polkadot.network/)**',
),
text('Governance : **Coming Soon ...**'),
divider(),
button({
variant: 'primary',
value: 'Back',
name: 'backToHome',
}),
]),
},
});
Expand Down
86 changes: 86 additions & 0 deletions packages/snap/src/ui/exportAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {
button,
heading,
panel,
text,
divider,
input,
form,
copyable,
} from '@metamask/snaps-sdk';

import { getJsonKeyPair } from '../util';

/**
* This will show the alert to get password to export account as JSON file.
*
* @param id - The id of UI interface to be updated.
*/
export async function exportAccount(id: string) {
await snap.request({
method: 'snap_updateInterface',
params: {
id,
ui: panel([
heading('Export Account'),
divider(),
text(
'Here, you can export your account as a JSON file, which can be used to import your account in another extension or wallet.'),
form({
name: 'saveExportedAccount',
children: [
input({
inputType: 'password',
label: 'Enter a password to encrypt your export data:',
name: 'password',
placeholder: 'password ...',
}),
button({
variant: 'primary',
value: 'Export',
name: 'exportAccountBtn',
}),
button({
variant: 'secondary',
value: 'Back',
name: 'backToHome',
}),
],
}),
]),
},
});
}

/**
* This will show the exported account content that can be copied in a file.
*
* @param id - The id of UI interface to be updated.
* @param password - The password to encode the content.
*/
export async function showJsonContent(id: string, password: string | null) {
if (!password) {
return;
}
const json = await getJsonKeyPair(password);

await snap.request({
method: 'snap_updateInterface',
params: {
id,
ui: panel([
heading('Export Account'),
divider(),
text(
'Copy and save the following content in a (.json) file. This file can be imported later in extensions and wallets.',
),
copyable(json),
button({
variant: 'secondary',
value: 'Back',
name: 'backToHome',
}),
]),
},
});
}
6 changes: 6 additions & 0 deletions packages/snap/src/ui/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export * from './accountDemo';
export * from './accountInfo';
export * from './dappList';
export * from './exportAccount';
export * from './showConfirmTx';
export * from './transfer';
Loading

0 comments on commit 6107210

Please sign in to comment.