refactor: abstracts common rpc handling into createJsonRpcRequestHandler
This commit is contained in:
parent
55fff706cf
commit
575f21e814
@ -53,6 +53,13 @@ import {
|
|||||||
SToggleContainer,
|
SToggleContainer,
|
||||||
} from "./components/app";
|
} from "./components/app";
|
||||||
|
|
||||||
|
interface FormattedRpcResponse {
|
||||||
|
method: string;
|
||||||
|
address: string;
|
||||||
|
valid: boolean;
|
||||||
|
result: string;
|
||||||
|
}
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [pending, setPending] = useState(false);
|
const [pending, setPending] = useState(false);
|
||||||
@ -317,204 +324,174 @@ export default function App() {
|
|||||||
setChainData(chainData);
|
setChainData(chainData);
|
||||||
};
|
};
|
||||||
|
|
||||||
const testSendTransaction = async (chainId: string) => {
|
// ----- EVM RPC -----
|
||||||
if (typeof client === "undefined") {
|
|
||||||
throw new Error("WalletConnect is not initialized");
|
|
||||||
}
|
|
||||||
if (typeof session === "undefined") {
|
|
||||||
throw new Error("Session is not connected");
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
const createJsonRpcRequestHandler =
|
||||||
setPending(true);
|
(rpcRequest: (...requestArgs: [any]) => Promise<FormattedRpcResponse>) =>
|
||||||
// get ethereum address
|
async (chainId: string) => {
|
||||||
const account = accounts.find(account => account.startsWith(chainId));
|
if (typeof client === "undefined") {
|
||||||
if (account === undefined) throw new Error("Account is not found");
|
throw new Error("WalletConnect is not initialized");
|
||||||
const address = account.split(":").pop();
|
}
|
||||||
if (address === undefined) throw new Error("Address is invalid");
|
if (typeof session === "undefined") {
|
||||||
|
throw new Error("Session is not connected");
|
||||||
// open modal
|
|
||||||
openRequestModal();
|
|
||||||
|
|
||||||
const tx = await formatTestTransaction(account);
|
|
||||||
|
|
||||||
const balance = BigNumber.from(balances[account][0].balance || "0");
|
|
||||||
if (balance.lt(BigNumber.from(tx.gasPrice).mul(tx.gasLimit))) {
|
|
||||||
const formattedResult = {
|
|
||||||
method: "eth_sendTransaction",
|
|
||||||
address,
|
|
||||||
valid: false,
|
|
||||||
result: "Insufficient funds for intrinsic transaction cost",
|
|
||||||
};
|
|
||||||
setResult(formattedResult);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = await client.request({
|
try {
|
||||||
topic: session.topic,
|
setPending(true);
|
||||||
chainId,
|
const result = await rpcRequest(chainId);
|
||||||
request: {
|
setResult(result);
|
||||||
method: "eth_sendTransaction",
|
} catch (err) {
|
||||||
params: [tx],
|
console.error(err);
|
||||||
},
|
setResult(null);
|
||||||
});
|
} finally {
|
||||||
|
setPending(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// format displayed result
|
const testSendTransaction = createJsonRpcRequestHandler(async (chainId: string) => {
|
||||||
const formattedResult = {
|
// 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");
|
||||||
|
|
||||||
|
// open modal
|
||||||
|
openRequestModal();
|
||||||
|
|
||||||
|
const tx = await formatTestTransaction(account);
|
||||||
|
|
||||||
|
const balance = BigNumber.from(balances[account][0].balance || "0");
|
||||||
|
if (balance.lt(BigNumber.from(tx.gasPrice).mul(tx.gasLimit))) {
|
||||||
|
return {
|
||||||
method: "eth_sendTransaction",
|
method: "eth_sendTransaction",
|
||||||
address,
|
address,
|
||||||
valid: true,
|
valid: false,
|
||||||
result,
|
result: "Insufficient funds for intrinsic transaction cost",
|
||||||
};
|
};
|
||||||
|
|
||||||
// display result
|
|
||||||
setResult(formattedResult);
|
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
setResult(null);
|
|
||||||
} finally {
|
|
||||||
setPending(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const testSignPersonalMessage = async (chainId: string) => {
|
|
||||||
if (typeof client === "undefined") {
|
|
||||||
throw new Error("WalletConnect is not initialized");
|
|
||||||
}
|
|
||||||
if (typeof session === "undefined") {
|
|
||||||
throw new Error("Session is not connected");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
const result: string = await client!.request({
|
||||||
setPending(true);
|
topic: session!.topic,
|
||||||
// test message
|
chainId,
|
||||||
const message = `My email is john@doe.com - ${Date.now()}`;
|
request: {
|
||||||
|
method: "eth_sendTransaction",
|
||||||
|
params: [tx],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
// encode message (hex)
|
// format displayed result
|
||||||
const hexMsg = encoding.utf8ToHex(message, true);
|
return {
|
||||||
|
method: "eth_sendTransaction",
|
||||||
|
address,
|
||||||
|
valid: true,
|
||||||
|
result,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// get ethereum address
|
const testSignPersonalMessage = createJsonRpcRequestHandler(async (chainId: string) => {
|
||||||
const account = accounts.find(account => account.startsWith(chainId));
|
// test message
|
||||||
if (account === undefined) throw new Error("Account is not found");
|
const message = `My email is john@doe.com - ${Date.now()}`;
|
||||||
const address = account.split(":").pop();
|
|
||||||
if (address === undefined) throw new Error("Address is invalid");
|
|
||||||
|
|
||||||
// personal_sign params
|
// encode message (hex)
|
||||||
const params = [hexMsg, address];
|
const hexMsg = encoding.utf8ToHex(message, true);
|
||||||
|
|
||||||
// open modal
|
// get ethereum address
|
||||||
openRequestModal();
|
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");
|
||||||
|
|
||||||
// send message
|
// personal_sign params
|
||||||
const result = await client.request({
|
const params = [hexMsg, address];
|
||||||
topic: session.topic,
|
|
||||||
chainId,
|
|
||||||
request: {
|
|
||||||
method: "personal_sign",
|
|
||||||
params,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// split chainId
|
// open modal
|
||||||
const [namespace, reference] = chainId.split(":");
|
openRequestModal();
|
||||||
|
|
||||||
const targetChainData = chainData[namespace][reference];
|
// send message
|
||||||
|
const result: string = await client!.request({
|
||||||
if (typeof targetChainData === "undefined") {
|
topic: session!.topic,
|
||||||
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
chainId,
|
||||||
}
|
request: {
|
||||||
|
|
||||||
const rpcUrl = targetChainData.rpc[0];
|
|
||||||
|
|
||||||
// verify signature
|
|
||||||
const hash = hashPersonalMessage(message);
|
|
||||||
const valid = await verifySignature(address, result, hash, rpcUrl);
|
|
||||||
|
|
||||||
// format displayed result
|
|
||||||
const formattedResult = {
|
|
||||||
method: "personal_sign",
|
method: "personal_sign",
|
||||||
address,
|
params,
|
||||||
valid,
|
},
|
||||||
result,
|
});
|
||||||
};
|
|
||||||
|
|
||||||
// display result
|
// split chainId
|
||||||
setResult(formattedResult);
|
const [namespace, reference] = chainId.split(":");
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
const targetChainData = chainData[namespace][reference];
|
||||||
setResult(null);
|
|
||||||
} finally {
|
if (typeof targetChainData === "undefined") {
|
||||||
setPending(false);
|
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const testSignTypedData = async (chainId: string) => {
|
const rpcUrl = targetChainData.rpc[0];
|
||||||
if (typeof client === "undefined") {
|
|
||||||
throw new Error("WalletConnect is not initialized");
|
|
||||||
}
|
|
||||||
if (typeof session === "undefined") {
|
|
||||||
throw new Error("Session is not connected");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
setPending(true);
|
|
||||||
|
|
||||||
// test message
|
// verify signature
|
||||||
const message = JSON.stringify(eip712.example);
|
const hash = hashPersonalMessage(message);
|
||||||
|
const valid = await verifySignature(address, result, hash, rpcUrl);
|
||||||
|
|
||||||
// get ethereum address
|
// format displayed result
|
||||||
const account = accounts.find(account => account.startsWith(chainId));
|
return {
|
||||||
if (account === undefined) throw new Error("Account is not found");
|
method: "personal_sign",
|
||||||
const address = account.split(":").pop();
|
address,
|
||||||
if (address === undefined) throw new Error("Address is invalid");
|
valid,
|
||||||
|
result,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
// eth_signTypedData params
|
const testSignTypedData = createJsonRpcRequestHandler(async (chainId: string) => {
|
||||||
const params = [address, message];
|
// test message
|
||||||
|
const message = JSON.stringify(eip712.example);
|
||||||
|
|
||||||
// open modal
|
// get ethereum address
|
||||||
openRequestModal();
|
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");
|
||||||
|
|
||||||
// send message
|
// eth_signTypedData params
|
||||||
const result = await client.request({
|
const params = [address, message];
|
||||||
topic: session.topic,
|
|
||||||
chainId,
|
|
||||||
request: {
|
|
||||||
method: "eth_signTypedData",
|
|
||||||
params,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// split chainId
|
// open modal
|
||||||
const [namespace, reference] = chainId.split(":");
|
openRequestModal();
|
||||||
|
|
||||||
const targetChainData = chainData[namespace][reference];
|
// send message
|
||||||
|
const result = await client!.request({
|
||||||
if (typeof targetChainData === "undefined") {
|
topic: session!.topic,
|
||||||
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
chainId,
|
||||||
}
|
request: {
|
||||||
|
|
||||||
const rpcUrl = targetChainData.rpc[0];
|
|
||||||
|
|
||||||
// verify signature
|
|
||||||
const hash = hashTypedDataMessage(message);
|
|
||||||
const valid = await verifySignature(address, result, hash, rpcUrl);
|
|
||||||
|
|
||||||
// format displayed result
|
|
||||||
const formattedResult = {
|
|
||||||
method: "eth_signTypedData",
|
method: "eth_signTypedData",
|
||||||
address,
|
params,
|
||||||
valid,
|
},
|
||||||
result,
|
});
|
||||||
};
|
|
||||||
|
|
||||||
// display result
|
// split chainId
|
||||||
setResult(formattedResult);
|
const [namespace, reference] = chainId.split(":");
|
||||||
} catch (e) {
|
|
||||||
console.error(e);
|
const targetChainData = chainData[namespace][reference];
|
||||||
setResult(null);
|
|
||||||
} finally {
|
if (typeof targetChainData === "undefined") {
|
||||||
setPending(false);
|
throw new Error(`Missing chain data for chainId: ${chainId}`);
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
const rpcUrl = targetChainData.rpc[0];
|
||||||
|
|
||||||
|
// verify signature
|
||||||
|
const hash = hashTypedDataMessage(message);
|
||||||
|
const valid = await verifySignature(address, result, hash, rpcUrl);
|
||||||
|
|
||||||
|
// format displayed result
|
||||||
|
return {
|
||||||
|
method: "eth_signTypedData",
|
||||||
|
address,
|
||||||
|
valid,
|
||||||
|
result,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
// ------ COSMOS RPC ------
|
||||||
|
|
||||||
const testSignDirect = async (chainId: string) => {
|
const testSignDirect = async (chainId: string) => {
|
||||||
if (typeof client === "undefined") {
|
if (typeof client === "undefined") {
|
||||||
|
Loading…
Reference in New Issue
Block a user