Add Polkadot RPCs to the Dapp examples and wallet (#44)

Co-authored-by: Ben Kremer <contact@bkrem.dev>
This commit is contained in:
hamidra
2022-08-11 11:43:12 +02:00
committed by GitHub
co-authored by Ben Kremer
parent 6a77191dd3
commit 1406ce3999
26 changed files with 821 additions and 8 deletions
+23 -2
View File
@@ -1,12 +1,29 @@
import { JsonRpcRequest } from "@walletconnect/jsonrpc-utils";
import { ChainsMap } from "caip-api";
import { BLOCKCHAIN_LOGO_BASE_URL } from "../constants";
import { JsonRpcRequest } from "@walletconnect/jsonrpc-utils";
import {
NamespaceMetadata,
ChainMetadata,
ChainRequestRender,
} from "../helpers";
export const PolkadotChainData: ChainsMap = {
["91b171bb158e2d3848fa23a9f1c25182"]: {
id: "polkadot:91b171bb158e2d3848fa23a9f1c25182",
name: "Polkadot Mainnet",
rpc: ["wss://rpc.polkadot.io"],
slip44: 0,
testnet: false,
},
["e143f23803ac50e8f6f8e62695d1ce9e"]: {
id: "polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
name: "Polkadot Testnet (Westend)",
rpc: ["wss://westend-rpc.polkadot.io"],
slip44: 0,
testnet: false,
},
};
export const PolkadotMetadata: NamespaceMetadata = {
// eslint-disable-next-line no-useless-computed-key
["91b171bb158e2d3848fa23a9f1c25182"]: {
@@ -15,6 +32,10 @@ export const PolkadotMetadata: NamespaceMetadata = {
"polkadot:91b171bb158e2d3848fa23a9f1c25182.png",
rgb: "230, 1, 122",
},
["e143f23803ac50e8f6f8e62695d1ce9e"]: {
logo: "/assets/westend-logo.svg",
rgb: "218, 104, 167",
},
};
export function getChainMetadata(chainId: string): ChainMetadata {
@@ -8,6 +8,7 @@ export const DEFAULT_MAIN_CHAINS = [
"eip155:42220",
"cosmos:cosmoshub-4",
"solana:4sGjMW1sUnHzSxGspuhpqLDx6wiyjNtZ",
"polkadot:91b171bb158e2d3848fa23a9f1c25182",
];
export const DEFAULT_TEST_CHAINS = [
@@ -18,6 +19,7 @@ export const DEFAULT_TEST_CHAINS = [
"eip155:421611",
"eip155:44787",
"solana:8E9rvCKLFQia2Y35HXjjpWzj8weVo44K",
"polkadot:e143f23803ac50e8f6f8e62695d1ce9e",
];
export const DEFAULT_CHAINS = [...DEFAULT_MAIN_CHAINS, ...DEFAULT_TEST_CHAINS];
@@ -71,5 +73,15 @@ export enum DEFAULT_SOLANA_METHODS {
export enum DEFAULT_SOLANA_EVENTS {}
/**
* POLKADOT
*/
export enum DEFAULT_POLKADOT_METHODS {
POLKADOT_SIGN_TRANSACTION = "polkadot_signTransaction",
POLKADOT_SIGN_MESSAGE = "polkadot_signMessage",
}
export enum DEFAULT_POLKADOT_EVENTS {}
export const DEFAULT_GITHUB_REPO_URL =
"https://github.com/WalletConnect/web-examples/tree/main/dapps/react-dapp-v2";
@@ -7,6 +7,7 @@ import {
useState,
} from "react";
import { SolanaChainData } from "../chains/solana";
import { PolkadotChainData } from "../chains/polkadot";
import { ChainNamespaces, getAllChainNamespaces } from "../helpers";
@@ -41,6 +42,8 @@ export function ChainDataContextProvider({
try {
if (namespace === "solana") {
chains = SolanaChainData;
} else if (namespace === "polkadot") {
chains = PolkadotChainData;
} else {
chains = await apiGetChainNamespace(namespace);
}
@@ -29,8 +29,10 @@ import {
DEFAULT_COSMOS_METHODS,
DEFAULT_EIP155_METHODS,
DEFAULT_SOLANA_METHODS,
DEFAULT_POLKADOT_METHODS,
} from "../constants";
import { useChainData } from "./ChainDataContext";
import { signatureVerify, cryptoWaitReady } from "@polkadot/util-crypto";
/**
* Types
@@ -61,6 +63,10 @@ interface IContext {
testSignMessage: TRpcRequestCallback;
testSignTransaction: TRpcRequestCallback;
};
polkadotRpc: {
testSignMessage: TRpcRequestCallback;
testSignTransaction: TRpcRequestCallback;
};
rpcResult?: IFormattedRpcResponse | null;
isRpcRequestPending: boolean;
isTestnet: boolean;
@@ -613,7 +619,77 @@ export function JsonRpcContextProvider({
}
),
};
// -------- POLKADOT RPC METHODS --------
const polkadotRpc = {
testSignTransaction: _createJsonRpcRequestHandler(
async (chainId: string, address: string): Promise<IFormattedRpcResponse> => {
// Below example is a scale encoded payload for system.remark("this is a test wallet-connect remark") transaction.
// decode url: https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Frpc.polkadot.io#/extrinsics/decode/0x00019074686973206973206120746573742077616c6c65742d636f6e6e6563742072656d61726b
const transactionPayload =
"0x00019074686973206973206120746573742077616c6c65742d636f6e6e6563742072656d61726b05010000222400000d00000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3dc1f37ce7899cf20f63f5ea343f33e9e7b229c7e245049c2a7afc236861fc8b4";
try {
const result = await client!.request<{ payload: string; signature: string }>({
chainId,
topic: session!.topic,
request: {
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION,
params: {
address,
transactionPayload,
},
},
});
// sr25519 signatures need to wait for WASM to load
await cryptoWaitReady();
const { isValid: valid } = signatureVerify(transactionPayload, result.signature, address);
return {
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION,
address,
valid,
result: result.signature,
};
} catch (error: any) {
throw new Error(error);
}
},
),
testSignMessage: _createJsonRpcRequestHandler(
async (chainId: string, address: string): Promise<IFormattedRpcResponse> => {
const message = `This is an example message to be signed - ${Date.now()}`;
try {
const result = await client!.request<{ signature: string }>({
chainId,
topic: session!.topic,
request: {
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE,
params: {
address,
message,
},
},
});
// sr25519 signatures need to wait for WASM to load
await cryptoWaitReady();
const { isValid: valid } = signatureVerify(message, result.signature, address);
return {
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE,
address,
valid,
result: result.signature,
};
} catch (error: any) {
throw new Error(error);
}
},
),
};
return (
<JsonRpcContext.Provider
value={{
@@ -621,6 +697,7 @@ export function JsonRpcContextProvider({
ethereumRpc,
cosmosRpc,
solanaRpc,
polkadotRpc,
rpcResult: result,
isRpcRequestPending: pending,
isTestnet,
@@ -6,6 +6,8 @@ import {
DEFAULT_EIP_155_EVENTS,
DEFAULT_SOLANA_EVENTS,
DEFAULT_SOLANA_METHODS,
DEFAULT_POLKADOT_EVENTS,
DEFAULT_POLKADOT_METHODS,
} from "../constants";
export const getNamespacesFromChains = (chains: string[]) => {
@@ -28,6 +30,8 @@ export const getSupportedMethodsByNamespace = (namespace: string) => {
return Object.values(DEFAULT_COSMOS_METHODS);
case "solana":
return Object.values(DEFAULT_SOLANA_METHODS);
case "polkadot":
return Object.values(DEFAULT_POLKADOT_METHODS);
default:
throw new Error(`No default methods for namespace: ${namespace}`);
}
@@ -41,6 +45,8 @@ export const getSupportedEventsByNamespace = (namespace: string) => {
return Object.values(DEFAULT_COSMOS_EVENTS);
case "solana":
return Object.values(DEFAULT_SOLANA_EVENTS);
case "polkadot":
return Object.values(DEFAULT_POLKADOT_EVENTS);
default:
throw new Error(`No default events for namespace: ${namespace}`);
}
+24
View File
@@ -11,6 +11,7 @@ import {
DEFAULT_EIP155_METHODS,
DEFAULT_MAIN_CHAINS,
DEFAULT_SOLANA_METHODS,
DEFAULT_POLKADOT_METHODS,
DEFAULT_TEST_CHAINS,
} from "../constants";
import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers";
@@ -64,6 +65,7 @@ const Home: NextPage = () => {
ethereumRpc,
cosmosRpc,
solanaRpc,
polkadotRpc,
isRpcRequestPending,
rpcResult,
isTestnet,
@@ -185,6 +187,26 @@ const Home: NextPage = () => {
];
};
const getPolkadotActions = (): AccountAction[] => {
const onSignTransaction = async (chainId: string, address: string) => {
openRequestModal();
await polkadotRpc.testSignTransaction(chainId, address);
};
const onSignMessage = async (chainId: string, address: string) => {
openRequestModal();
await polkadotRpc.testSignMessage(chainId, address);
};
return [
{
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_TRANSACTION,
callback: onSignTransaction,
},
{
method: DEFAULT_POLKADOT_METHODS.POLKADOT_SIGN_MESSAGE,
callback: onSignMessage,
},
];
};
const getBlockchainActions = (chainId: string) => {
const [namespace] = chainId.split(":");
switch (namespace) {
@@ -194,6 +216,8 @@ const Home: NextPage = () => {
return getCosmosActions();
case "solana":
return getSolanaActions();
case "polkadot":
return getPolkadotActions();
default:
break;
}