refactor(dapp): support signing from different addresses on same network
This commit is contained in:
parent
d4c670bdf3
commit
3c2684f851
@ -77,25 +77,25 @@ export default function App() {
|
||||
};
|
||||
|
||||
const getEthereumActions = (): AccountAction[] => {
|
||||
const onSendTransaction = async (chainId: string) => {
|
||||
const onSendTransaction = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSendTransaction(chainId);
|
||||
await ethereumRpc.testSendTransaction(chainId, address);
|
||||
};
|
||||
const onSignTransaction = async (chainId: string) => {
|
||||
const onSignTransaction = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTransaction(chainId);
|
||||
await ethereumRpc.testSignTransaction(chainId, address);
|
||||
};
|
||||
const onSignPersonalMessage = async (chainId: string) => {
|
||||
const onSignPersonalMessage = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignPersonalMessage(chainId);
|
||||
await ethereumRpc.testSignPersonalMessage(chainId, address);
|
||||
};
|
||||
const onEthSign = async (chainId: string) => {
|
||||
const onEthSign = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testEthSign(chainId);
|
||||
await ethereumRpc.testEthSign(chainId, address);
|
||||
};
|
||||
const onSignTypedData = async (chainId: string) => {
|
||||
const onSignTypedData = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await ethereumRpc.testSignTypedData(chainId);
|
||||
await ethereumRpc.testSignTypedData(chainId, address);
|
||||
};
|
||||
|
||||
return [
|
||||
@ -108,13 +108,13 @@ export default function App() {
|
||||
};
|
||||
|
||||
const getCosmosActions = (): AccountAction[] => {
|
||||
const onSignDirect = async (chainId: string) => {
|
||||
const onSignDirect = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await cosmosRpc.testSignDirect(chainId);
|
||||
await cosmosRpc.testSignDirect(chainId, address);
|
||||
};
|
||||
const onSignAmino = async (chainId: string) => {
|
||||
const onSignAmino = async (chainId: string, address: string) => {
|
||||
openRequestModal();
|
||||
await cosmosRpc.testSignAmino(chainId);
|
||||
await cosmosRpc.testSignAmino(chainId, address);
|
||||
};
|
||||
return [
|
||||
{ method: "cosmos_signDirect", callback: onSignDirect },
|
||||
|
@ -155,7 +155,7 @@ const Blockchain: FC<PropsWithChildren<BlockchainProps>> = (
|
||||
</Column>
|
||||
</SFullWidthContainer>
|
||||
) : null}
|
||||
{!!actions && actions.length ? (
|
||||
{address && !!actions && actions.length ? (
|
||||
<SFullWidthContainer>
|
||||
<h6>Methods</h6>
|
||||
{actions.map(action => (
|
||||
@ -163,7 +163,7 @@ const Blockchain: FC<PropsWithChildren<BlockchainProps>> = (
|
||||
key={action.method}
|
||||
left
|
||||
rgb={chain.meta.rgb}
|
||||
onClick={() => action.callback(chainId)}
|
||||
onClick={() => action.callback(chainId, address)}
|
||||
>
|
||||
{action.method}
|
||||
</SAction>
|
||||
|
@ -28,18 +28,20 @@ interface IRpcResult {
|
||||
valid: boolean;
|
||||
}
|
||||
|
||||
type TRpcRequestCallback = (chainId: string, address: string) => Promise<void>;
|
||||
|
||||
interface IContext {
|
||||
ping: () => Promise<void>;
|
||||
ethereumRpc: {
|
||||
testSendTransaction: (chainId: string) => Promise<void>;
|
||||
testSignTransaction: (chainId: string) => Promise<void>;
|
||||
testEthSign: (chainId: string) => Promise<void>;
|
||||
testSignPersonalMessage: (chainId: string) => Promise<void>;
|
||||
testSignTypedData: (chainId: string) => Promise<void>;
|
||||
testSendTransaction: TRpcRequestCallback;
|
||||
testSignTransaction: TRpcRequestCallback;
|
||||
testEthSign: TRpcRequestCallback;
|
||||
testSignPersonalMessage: TRpcRequestCallback;
|
||||
testSignTypedData: TRpcRequestCallback;
|
||||
};
|
||||
cosmosRpc: {
|
||||
testSignDirect: (chainId: string) => Promise<void>;
|
||||
testSignAmino: (chainId: string) => Promise<void>;
|
||||
testSignDirect: TRpcRequestCallback;
|
||||
testSignAmino: TRpcRequestCallback;
|
||||
};
|
||||
chainData: ChainNamespaces;
|
||||
rpcResult?: IRpcResult | null;
|
||||
@ -84,18 +86,9 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
setChainData(chainData);
|
||||
};
|
||||
|
||||
const getAddressByChainId = (chainId: string) => {
|
||||
const account = accounts.find(account => account.startsWith(chainId));
|
||||
if (account === undefined) throw new Error(`Account for chainId ${chainId} not found.`);
|
||||
const address = account.split(":").pop();
|
||||
if (address === undefined) throw new Error(`Address for account ${account} is invalid`);
|
||||
|
||||
return address;
|
||||
};
|
||||
|
||||
const _createJsonRpcRequestHandler =
|
||||
(rpcRequest: (...requestArgs: [any]) => Promise<IFormattedRpcResponse>) =>
|
||||
async (chainId: string) => {
|
||||
(rpcRequest: (chainId: string, address: string) => Promise<IFormattedRpcResponse>) =>
|
||||
async (chainId: string, address: string) => {
|
||||
if (typeof client === "undefined") {
|
||||
throw new Error("WalletConnect is not initialized");
|
||||
}
|
||||
@ -105,7 +98,7 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
|
||||
try {
|
||||
setPending(true);
|
||||
const result = await rpcRequest(chainId);
|
||||
const result = await rpcRequest(chainId, address);
|
||||
setResult(result);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
@ -151,12 +144,10 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
// -------- ETHEREUM/EIP155 RPC METHODS --------
|
||||
|
||||
const ethereumRpc = {
|
||||
testSendTransaction: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
// get ethereum address
|
||||
const account = accounts.find(account => account.startsWith(chainId));
|
||||
if (account === undefined) throw new Error("Account is not found");
|
||||
const address = account.split(":").pop();
|
||||
if (address === undefined) throw new Error("Address is invalid");
|
||||
testSendTransaction: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
const caipAccountAddress = `${chainId}:${address}`;
|
||||
const account = accounts.find(account => account === caipAccountAddress);
|
||||
if (account === undefined) throw new Error(`Account for ${caipAccountAddress} not found`);
|
||||
|
||||
const tx = await formatTestTransaction(account);
|
||||
|
||||
@ -185,8 +176,6 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
console.log(result);
|
||||
|
||||
// format displayed result
|
||||
return {
|
||||
method: "eth_sendTransaction",
|
||||
@ -195,12 +184,10 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
result,
|
||||
};
|
||||
}),
|
||||
testSignTransaction: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
// get ethereum address
|
||||
const account = accounts.find(account => account.startsWith(chainId));
|
||||
if (account === undefined) throw new Error("Account is not found");
|
||||
const address = account.split(":").pop();
|
||||
if (address === undefined) throw new Error("Address is invalid");
|
||||
testSignTransaction: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
const caipAccountAddress = `${chainId}:${address}`;
|
||||
const account = accounts.find(account => account === caipAccountAddress);
|
||||
if (account === undefined) throw new Error(`Account for ${caipAccountAddress} not found`);
|
||||
|
||||
const tx = await formatTestTransaction(account);
|
||||
|
||||
@ -220,54 +207,52 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
result,
|
||||
};
|
||||
}),
|
||||
testSignPersonalMessage: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
// test message
|
||||
const message = `My email is john@doe.com - ${Date.now()}`;
|
||||
testSignPersonalMessage: _createJsonRpcRequestHandler(
|
||||
async (chainId: string, address: string) => {
|
||||
// test message
|
||||
const message = `My email is john@doe.com - ${Date.now()}`;
|
||||
|
||||
// encode message (hex)
|
||||
const hexMsg = encoding.utf8ToHex(message, true);
|
||||
// encode message (hex)
|
||||
const hexMsg = encoding.utf8ToHex(message, true);
|
||||
|
||||
const address = getAddressByChainId(chainId);
|
||||
// personal_sign params
|
||||
const params = [hexMsg, address];
|
||||
|
||||
// personal_sign params
|
||||
const params = [hexMsg, address];
|
||||
// send message
|
||||
const result: string = await client!.request({
|
||||
topic: session!.topic,
|
||||
chainId,
|
||||
request: {
|
||||
method: "personal_sign",
|
||||
params,
|
||||
},
|
||||
});
|
||||
|
||||
// send message
|
||||
const result: string = await client!.request({
|
||||
topic: session!.topic,
|
||||
chainId,
|
||||
request: {
|
||||
// split chainId
|
||||
const [namespace, reference] = chainId.split(":");
|
||||
|
||||
const targetChainData = chainData[namespace][reference];
|
||||
|
||||
if (typeof targetChainData === "undefined") {
|
||||
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
||||
}
|
||||
|
||||
const rpcUrl = targetChainData.rpc[0];
|
||||
|
||||
// verify signature
|
||||
const hash = hashPersonalMessage(message);
|
||||
const valid = await verifySignature(address, result, hash, rpcUrl);
|
||||
|
||||
// format displayed result
|
||||
return {
|
||||
method: "personal_sign",
|
||||
params,
|
||||
},
|
||||
});
|
||||
|
||||
// split chainId
|
||||
const [namespace, reference] = chainId.split(":");
|
||||
|
||||
const targetChainData = chainData[namespace][reference];
|
||||
|
||||
if (typeof targetChainData === "undefined") {
|
||||
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
||||
}
|
||||
|
||||
const rpcUrl = targetChainData.rpc[0];
|
||||
|
||||
// verify signature
|
||||
const hash = hashPersonalMessage(message);
|
||||
const valid = await verifySignature(address, result, hash, rpcUrl);
|
||||
|
||||
// format displayed result
|
||||
return {
|
||||
method: "personal_sign",
|
||||
address,
|
||||
valid,
|
||||
result,
|
||||
};
|
||||
}),
|
||||
testEthSign: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
const address = getAddressByChainId(chainId);
|
||||
|
||||
address,
|
||||
valid,
|
||||
result,
|
||||
};
|
||||
},
|
||||
),
|
||||
testEthSign: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
// test message
|
||||
const message = `My email is john@doe.com - ${Date.now()}`;
|
||||
// encode message (hex)
|
||||
@ -308,7 +293,7 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
result,
|
||||
};
|
||||
}),
|
||||
testSignTypedData: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
testSignTypedData: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
const typedData = {
|
||||
types: {
|
||||
Person: [
|
||||
@ -341,7 +326,6 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
},
|
||||
};
|
||||
|
||||
const address = getAddressByChainId(chainId);
|
||||
const message = JSON.stringify(typedData);
|
||||
|
||||
// eth_signTypedData params
|
||||
@ -372,7 +356,7 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
// -------- COSMOS RPC METHODS --------
|
||||
|
||||
const cosmosRpc = {
|
||||
testSignDirect: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
testSignDirect: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
// test direct sign doc inputs
|
||||
const inputs = {
|
||||
fee: [{ amount: "2000", denom: "ucosm" }],
|
||||
@ -400,8 +384,6 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
reference,
|
||||
);
|
||||
|
||||
const address = getAddressByChainId(chainId);
|
||||
|
||||
// cosmos_signDirect params
|
||||
const params = {
|
||||
signerAddress: address,
|
||||
@ -435,7 +417,7 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
result: result.signature.signature,
|
||||
};
|
||||
}),
|
||||
testSignAmino: _createJsonRpcRequestHandler(async (chainId: string) => {
|
||||
testSignAmino: _createJsonRpcRequestHandler(async (chainId: string, address: string) => {
|
||||
// split chainId
|
||||
const [namespace, reference] = chainId.split(":");
|
||||
|
||||
@ -449,8 +431,6 @@ export function JsonRpcContextProvider({ children }: { children: ReactNode | Rea
|
||||
sequence: "54",
|
||||
};
|
||||
|
||||
const address = getAddressByChainId(chainId);
|
||||
|
||||
// cosmos_signAmino params
|
||||
const params = { signerAddress: address, signDoc };
|
||||
|
||||
|
@ -151,7 +151,7 @@ export interface ChainNamespaces {
|
||||
|
||||
export interface AccountAction {
|
||||
method: string;
|
||||
callback: (chainId: string) => Promise<void>;
|
||||
callback: (chainId: string, address: string) => Promise<void>;
|
||||
}
|
||||
|
||||
export interface AccountBalances {
|
||||
|
Loading…
Reference in New Issue
Block a user