Add Polkadot RPCs to the Dapp examples and wallet (#44)
Co-authored-by: Ben Kremer <contact@bkrem.dev>
This commit is contained in:
@@ -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}`);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user