refactor(dapp-v2): splits requested methods between required/optional (#196)
This commit is contained in:
parent
dd54b0b6ed
commit
03155d1c23
@ -51,9 +51,12 @@ export const DEFAULT_APP_METADATA = {
|
||||
*/
|
||||
export enum DEFAULT_EIP155_METHODS {
|
||||
ETH_SEND_TRANSACTION = "eth_sendTransaction",
|
||||
PERSONAL_SIGN = "personal_sign",
|
||||
}
|
||||
|
||||
export enum DEFAULT_EIP155_OPTIONAL_METHODS {
|
||||
ETH_SIGN_TRANSACTION = "eth_signTransaction",
|
||||
ETH_SIGN = "eth_sign",
|
||||
PERSONAL_SIGN = "personal_sign",
|
||||
ETH_SIGN_TYPED_DATA = "eth_signTypedData",
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,10 @@ import {
|
||||
DEFAULT_RELAY_URL,
|
||||
} from "../constants";
|
||||
import { AccountBalances, apiGetAccountBalance } from "../helpers";
|
||||
import { getRequiredNamespaces } from "../helpers/namespaces";
|
||||
import {
|
||||
getOptionalNamespaces,
|
||||
getRequiredNamespaces,
|
||||
} from "../helpers/namespaces";
|
||||
import { getPublicKeysFromAccounts } from "../helpers/solana";
|
||||
|
||||
/**
|
||||
@ -144,10 +147,16 @@ export function ClientContextProvider({
|
||||
"requiredNamespaces config for connect:",
|
||||
requiredNamespaces
|
||||
);
|
||||
const optionalNamespaces = getOptionalNamespaces(chains);
|
||||
console.log(
|
||||
"optionalNamespaces config for connect:",
|
||||
optionalNamespaces
|
||||
);
|
||||
|
||||
const { uri, approval } = await client.connect({
|
||||
pairingTopic: pairing?.topic,
|
||||
requiredNamespaces,
|
||||
optionalNamespaces,
|
||||
});
|
||||
|
||||
// Open QRCode modal if a URI was returned (i.e. we're not connecting an existing pairing).
|
||||
|
@ -39,6 +39,7 @@ import {
|
||||
DEFAULT_MULTIVERSX_METHODS,
|
||||
DEFAULT_TRON_METHODS,
|
||||
DEFAULT_TEZOS_METHODS,
|
||||
DEFAULT_EIP155_OPTIONAL_METHODS,
|
||||
} from "../constants";
|
||||
import { useChainData } from "./ChainDataContext";
|
||||
import { rpcProvidersByChainId } from "../../src/helpers/api";
|
||||
@ -261,7 +262,7 @@ export function JsonRpcContextProvider({
|
||||
topic: session!.topic,
|
||||
chainId,
|
||||
request: {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TRANSACTION,
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TRANSACTION,
|
||||
params: [tx],
|
||||
},
|
||||
});
|
||||
@ -284,7 +285,7 @@ export function JsonRpcContextProvider({
|
||||
}
|
||||
|
||||
return {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TRANSACTION,
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TRANSACTION,
|
||||
address,
|
||||
valid,
|
||||
result: signedTx,
|
||||
@ -352,7 +353,7 @@ export function JsonRpcContextProvider({
|
||||
topic: session!.topic,
|
||||
chainId,
|
||||
request: {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN,
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN,
|
||||
params,
|
||||
},
|
||||
});
|
||||
@ -377,7 +378,7 @@ export function JsonRpcContextProvider({
|
||||
|
||||
// format displayed result
|
||||
return {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN + " (standard)",
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN + " (standard)",
|
||||
address,
|
||||
valid,
|
||||
result: signature,
|
||||
@ -396,7 +397,7 @@ export function JsonRpcContextProvider({
|
||||
topic: session!.topic,
|
||||
chainId,
|
||||
request: {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
params,
|
||||
},
|
||||
});
|
||||
@ -420,7 +421,7 @@ export function JsonRpcContextProvider({
|
||||
);
|
||||
|
||||
return {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
address,
|
||||
valid,
|
||||
result: signature,
|
||||
|
@ -16,6 +16,7 @@ import {
|
||||
DEFAULT_TRON_EVENTS,
|
||||
DEFAULT_TEZOS_METHODS,
|
||||
DEFAULT_TEZOS_EVENTS,
|
||||
DEFAULT_EIP155_OPTIONAL_METHODS,
|
||||
} from "../constants";
|
||||
|
||||
export const getNamespacesFromChains = (chains: string[]) => {
|
||||
@ -30,7 +31,7 @@ export const getNamespacesFromChains = (chains: string[]) => {
|
||||
return supportedNamespaces;
|
||||
};
|
||||
|
||||
export const getSupportedMethodsByNamespace = (namespace: string) => {
|
||||
export const getSupportedRequiredMethodsByNamespace = (namespace: string) => {
|
||||
switch (namespace) {
|
||||
case "eip155":
|
||||
return Object.values(DEFAULT_EIP155_METHODS);
|
||||
@ -49,7 +50,28 @@ export const getSupportedMethodsByNamespace = (namespace: string) => {
|
||||
case "tezos":
|
||||
return Object.values(DEFAULT_TEZOS_METHODS);
|
||||
default:
|
||||
throw new Error(`No default methods for namespace: ${namespace}`);
|
||||
throw new Error(
|
||||
`No default required methods for namespace: ${namespace}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export const getSupportedOptionalMethodsByNamespace = (namespace: string) => {
|
||||
switch (namespace) {
|
||||
case "eip155":
|
||||
return Object.values(DEFAULT_EIP155_OPTIONAL_METHODS);
|
||||
case "cosmos":
|
||||
case "solana":
|
||||
case "polkadot":
|
||||
case "near":
|
||||
case "mvx":
|
||||
case "tron":
|
||||
case "tezos":
|
||||
return [];
|
||||
default:
|
||||
throw new Error(
|
||||
`No default optional methods for namespace: ${namespace}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@ -80,16 +102,34 @@ export const getRequiredNamespaces = (
|
||||
chains: string[]
|
||||
): ProposalTypes.RequiredNamespaces => {
|
||||
const selectedNamespaces = getNamespacesFromChains(chains);
|
||||
console.log("selected namespaces:", selectedNamespaces);
|
||||
console.log("selected required namespaces:", selectedNamespaces);
|
||||
|
||||
return Object.fromEntries(
|
||||
selectedNamespaces.map((namespace) => [
|
||||
namespace,
|
||||
{
|
||||
methods: getSupportedMethodsByNamespace(namespace),
|
||||
methods: getSupportedRequiredMethodsByNamespace(namespace),
|
||||
chains: chains.filter((chain) => chain.startsWith(namespace)),
|
||||
events: getSupportedEventsByNamespace(namespace) as any[],
|
||||
},
|
||||
])
|
||||
);
|
||||
};
|
||||
|
||||
export const getOptionalNamespaces = (
|
||||
chains: string[]
|
||||
): ProposalTypes.OptionalNamespaces => {
|
||||
const selectedNamespaces = getNamespacesFromChains(chains);
|
||||
console.log("selected optional namespaces:", selectedNamespaces);
|
||||
|
||||
return Object.fromEntries(
|
||||
selectedNamespaces.map((namespace) => [
|
||||
namespace,
|
||||
{
|
||||
methods: getSupportedOptionalMethodsByNamespace(namespace),
|
||||
chains: chains.filter((chain) => chain.startsWith(namespace)),
|
||||
events: [],
|
||||
},
|
||||
])
|
||||
);
|
||||
};
|
||||
|
@ -18,6 +18,7 @@ import {
|
||||
DEFAULT_NEAR_METHODS,
|
||||
DEFAULT_TRON_METHODS,
|
||||
DEFAULT_TEZOS_METHODS,
|
||||
DEFAULT_EIP155_OPTIONAL_METHODS,
|
||||
} from "../constants";
|
||||
import { AccountAction, setLocaleStorageTestnetFlag } from "../helpers";
|
||||
import Toggle from "../components/Toggle";
|
||||
@ -123,49 +124,55 @@ const Home: NextPage = () => {
|
||||
}
|
||||
|
||||
const getEthereumActions = (): AccountAction[] => {
|
||||
const onSendTransaction = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSendTransaction(chainId, address);
|
||||
};
|
||||
const onSignTransaction = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTransaction(chainId, address);
|
||||
};
|
||||
const onSignPersonalMessage = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignPersonalMessage(chainId, address);
|
||||
};
|
||||
const onEthSign = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testEthSign(chainId, address);
|
||||
};
|
||||
const onSignTypedData = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTypedData(chainId, address);
|
||||
const actions = {
|
||||
[DEFAULT_EIP155_METHODS.ETH_SEND_TRANSACTION]: {
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SEND_TRANSACTION,
|
||||
callback: async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSendTransaction(chainId, address);
|
||||
},
|
||||
},
|
||||
[DEFAULT_EIP155_METHODS.PERSONAL_SIGN]: {
|
||||
method: DEFAULT_EIP155_METHODS.PERSONAL_SIGN,
|
||||
callback: async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignPersonalMessage(chainId, address);
|
||||
},
|
||||
},
|
||||
[DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TRANSACTION]: {
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TRANSACTION,
|
||||
callback: async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTransaction(chainId, address);
|
||||
},
|
||||
},
|
||||
[DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN]: {
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN + " (standard)",
|
||||
callback: async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testEthSign(chainId, address);
|
||||
},
|
||||
},
|
||||
[DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TYPED_DATA]: {
|
||||
method: DEFAULT_EIP155_OPTIONAL_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
callback: async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTypedData(chainId, address);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SEND_TRANSACTION,
|
||||
callback: onSendTransaction,
|
||||
},
|
||||
{
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TRANSACTION,
|
||||
callback: onSignTransaction,
|
||||
},
|
||||
{
|
||||
method: DEFAULT_EIP155_METHODS.PERSONAL_SIGN,
|
||||
callback: onSignPersonalMessage,
|
||||
},
|
||||
{
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN + " (standard)",
|
||||
callback: onEthSign,
|
||||
},
|
||||
{
|
||||
method: DEFAULT_EIP155_METHODS.ETH_SIGN_TYPED_DATA,
|
||||
callback: onSignTypedData,
|
||||
},
|
||||
];
|
||||
let availableActions: AccountAction[] = [];
|
||||
|
||||
session?.namespaces?.["eip155"].methods.forEach((methodName) => {
|
||||
const action: AccountAction | undefined =
|
||||
actions[methodName as keyof typeof actions];
|
||||
if (action) {
|
||||
availableActions.push(action);
|
||||
}
|
||||
});
|
||||
|
||||
return availableActions;
|
||||
};
|
||||
|
||||
const getCosmosActions = (): AccountAction[] => {
|
||||
|
@ -23,7 +23,7 @@ import { solanaAddresses } from '@/utils/SolanaWalletUtil'
|
||||
import { signClient } from '@/utils/WalletConnectUtil'
|
||||
import { Button, Divider, Modal, Text } from '@nextui-org/react'
|
||||
import { SessionTypes } from '@walletconnect/types'
|
||||
import { getSdkError } from '@walletconnect/utils'
|
||||
import { getSdkError, mergeArrays } from '@walletconnect/utils'
|
||||
import { Fragment, useEffect, useState } from 'react'
|
||||
import { nearAddresses } from '@/utils/NearWalletUtil'
|
||||
|
||||
@ -89,18 +89,24 @@ export default function SessionProposalModal() {
|
||||
}
|
||||
if (optionalNamespaces[key] && selectedAccounts[`optional:${key}`]) {
|
||||
optionalNamespaces[key].chains?.map(chain => {
|
||||
selectedAccounts[`optional:${key}`].map(acc => accounts.push(`${chain}:${acc}`))
|
||||
selectedAccounts[`optional:${key}`].forEach(acc => {
|
||||
if (!accounts.includes(`${chain}:${acc}`)) {
|
||||
accounts.push(`${chain}:${acc}`)
|
||||
}
|
||||
})
|
||||
})
|
||||
namespaces[key] = {
|
||||
...namespaces[key],
|
||||
accounts,
|
||||
methods: optionalNamespaces[key].methods,
|
||||
events: optionalNamespaces[key].events,
|
||||
chains: namespaces[key]?.chains?.concat(optionalNamespaces[key].chains || [])
|
||||
methods: mergeArrays(namespaces[key].methods, optionalNamespaces[key].methods),
|
||||
events: mergeArrays(namespaces[key].events, optionalNamespaces[key].events),
|
||||
chains: mergeArrays(namespaces[key].chains, optionalNamespaces[key].chains)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
console.log('approving namespaces:', namespaces)
|
||||
|
||||
await signClient.approve({
|
||||
id,
|
||||
relayProtocol: relays[0].protocol,
|
||||
|
@ -13,6 +13,7 @@
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"downlevelIteration": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
|
Loading…
Reference in New Issue
Block a user