From 850cad7e1e42621210053dfe166a8e17798abac1 Mon Sep 17 00:00:00 2001 From: Aidan Starke <52016903+aidan-starke@users.noreply.github.com> Date: Fri, 22 Apr 2022 07:57:23 +1200 Subject: [PATCH] Spike/use proofs endpoint (#171) * use proofs endpoint WIP * map _id to eventId * add options for _id & eventId * remove `sendHistoricalWithdrawEthereumRequest` * use for fresh & historic withdrawEthereum requests * use `sendWithdrawEthereumRequest` * auto expand advanced if some unclaimed withdrawals --- components/BridgeWithdrawAdvanced.tsx | 15 +++++++-- hooks/useHistoricalWithdrawRequest.ts | 14 ++------ types/index.d.ts | 11 +++++++ utils/fetchUnclaimedEventProof.ts | 14 ++++++++ utils/fetchUnclaimedWithdrawals.ts | 11 ++++++- utils/index.ts | 1 + utils/sendWithdrawEthereumRequest.ts | 46 +++++++++++++++------------ 7 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 utils/fetchUnclaimedEventProof.ts diff --git a/components/BridgeWithdrawAdvanced.tsx b/components/BridgeWithdrawAdvanced.tsx index dcb37771..f6361971 100644 --- a/components/BridgeWithdrawAdvanced.tsx +++ b/components/BridgeWithdrawAdvanced.tsx @@ -1,4 +1,4 @@ -import { useEffect, VFC } from "react"; +import { useEffect, useState, VFC } from "react"; import { IntrinsicElements } from "@/types"; import { css } from "@emotion/react"; import { @@ -21,12 +21,21 @@ const BridgeWithdrawAdvanced: VFC< advancedExpanded: expanded, setAdvancedExpanded: setExpanded, advancedMounted, + unclaimedWithdrawals, updateUnclaimedWithdrawals, }: any = useBridge(); + const [firstRender, setFirstRender] = useState(true); useEffect(() => { - if (expanded) void updateUnclaimedWithdrawals(); - }, [updateUnclaimedWithdrawals, expanded]); + if (expanded || firstRender) updateUnclaimedWithdrawals(); + }, [expanded, firstRender, updateUnclaimedWithdrawals]); + + useEffect(() => { + if (!unclaimedWithdrawals || !firstRender) return; + + setExpanded(true); + setFirstRender(false); + }, [unclaimedWithdrawals, firstRender, setExpanded]); return (
diff --git a/hooks/useHistoricalWithdrawRequest.ts b/hooks/useHistoricalWithdrawRequest.ts index c0d7a2ed..e2123eb3 100644 --- a/hooks/useHistoricalWithdrawRequest.ts +++ b/hooks/useHistoricalWithdrawRequest.ts @@ -9,8 +9,6 @@ import { ensureEthereumChain, sendWithdrawEthereumRequest, } from "@/utils"; -import { EthEventProof } from "@cennznet/api/derives/ethBridge/types"; -import { EthyEventId } from "@cennznet/types"; import { useCallback } from "react"; export default function useHistoricalWithdrawRequest(): ( @@ -19,7 +17,6 @@ export default function useHistoricalWithdrawRequest(): ( const { transferInput, transferSelect, - transferMetaMaskAddress, setTxIdle, setTxPending, setTxSuccess, @@ -44,11 +41,6 @@ export default function useHistoricalWithdrawRequest(): ( setTxPending(); await ensureEthereumChain(extension); await ensureBridgeWithdrawActive(api, metaMaskWallet); - const eventProof: EthEventProof = await api.derive.ethBridge.eventProof( - unclaimed.eventProofId as unknown as EthyEventId - ); - - console.log({ eventProof }); setTxPending({ relayerStatus: "EthereumConfirming", @@ -56,12 +48,11 @@ export default function useHistoricalWithdrawRequest(): ( sendWithdrawEthereumRequest( api, - eventProof, + unclaimed.eventProof, unclaimed.transferAmount, unclaimed.transferAsset, unclaimed.beneficiary, - metaMaskWallet.getSigner(), - eventProof.blockHash + metaMaskWallet.getSigner() ) .then((withdrawTx) => { withdrawTx.on("txHashed", () => { @@ -111,7 +102,6 @@ export default function useHistoricalWithdrawRequest(): ( extension, api, metaMaskWallet, - transferMetaMaskAddress, updateMetaMaskBalances, updateCENNZBalances, setTxSuccess, diff --git a/types/index.d.ts b/types/index.d.ts index b3323887..276ef483 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -96,4 +96,15 @@ export interface WithdrawClaim { transferAsset: BridgedEthereumToken; transferAmount: Balance; beneficiary: string; + eventProof: HistoricalEventProof; +} + +export interface HistoricalEventProof { + _id?: string; + eventId?: string; + validatorSetId: string; + validators: []; + r: string[]; + s: string[]; + v: number[]; } diff --git a/utils/fetchUnclaimedEventProof.ts b/utils/fetchUnclaimedEventProof.ts new file mode 100644 index 00000000..82dd04fd --- /dev/null +++ b/utils/fetchUnclaimedEventProof.ts @@ -0,0 +1,14 @@ +import { BRIDGE_RELAYER_URL } from "@/constants"; +import { HistoricalEventProof } from "@/types"; + +export default async function fetchUnclaimedEventProof( + eventProofId: number +): Promise { + return await fetch(`${BRIDGE_RELAYER_URL}/proofs/${eventProofId}`) + .then((response) => { + if (!response.ok) throw new Error("No event proof found"); + + return response.json(); + }) + .catch((err) => console.log(err.message)); +} diff --git a/utils/fetchUnclaimedWithdrawals.ts b/utils/fetchUnclaimedWithdrawals.ts index e3166a9c..88cecbcf 100644 --- a/utils/fetchUnclaimedWithdrawals.ts +++ b/utils/fetchUnclaimedWithdrawals.ts @@ -1,7 +1,12 @@ import { Api } from "@cennznet/api"; import { BridgedEthereumToken, WithdrawClaim } from "@/types"; import { BRIDGE_RELAYER_URL } from "@/constants"; -import { Balance, fetchBridgeTokens, getDaysHoursMinutes } from "@/utils"; +import { + Balance, + fetchBridgeTokens, + fetchUnclaimedEventProof, + getDaysHoursMinutes, +} from "@/utils"; /** * Fetch unclaimed withdraws for the selected account @@ -39,6 +44,9 @@ export default async function fetchUnclaimedWithdrawals( withdrawal.amount.trim(), transferAsset ); + const eventProof = await fetchUnclaimedEventProof( + Number(withdrawal.proofId) + ); return { assetId: Number(withdrawal.assetId), @@ -48,6 +56,7 @@ export default async function fetchUnclaimedWithdrawals( transferAsset: transferAsset as BridgedEthereumToken, transferAmount, beneficiary: withdrawal.beneficiary, + eventProof: { ...eventProof, eventId: eventProof._id }, }; }) ); diff --git a/utils/index.ts b/utils/index.ts index d23844b7..12ba09bc 100644 --- a/utils/index.ts +++ b/utils/index.ts @@ -39,6 +39,7 @@ export { default as trackPageView } from "@/utils/trackPageView"; export { default as getSellAssetExtrinsic } from "@/utils/getSellAssetExtrinsic"; export { default as selectMap } from "@/utils/selectMap"; export { default as fetchUnclaimedWithdrawals } from "@/utils/fetchUnclaimedWithdrawals"; +export { default as fetchUnclaimedEventProof } from "@/utils/fetchUnclaimedEventProof"; export { default as CENNZTransaction } from "@/utils/CENNZTransaction"; export { default as EthereumTransaction } from "@/utils/EthereumTransaction"; export { default as waitForEventProof } from "@/utils/waitForEventProof"; diff --git a/utils/sendWithdrawEthereumRequest.ts b/utils/sendWithdrawEthereumRequest.ts index 070681e7..49b6dbe9 100644 --- a/utils/sendWithdrawEthereumRequest.ts +++ b/utils/sendWithdrawEthereumRequest.ts @@ -1,6 +1,10 @@ -import { BridgedEthereumToken } from "@/types"; -import { Balance, EthereumTransaction, getBridgeContract } from "@/utils"; -import getERC20PegContract from "@/utils/getERC20PegContract"; +import { BridgedEthereumToken, HistoricalEventProof } from "@/types"; +import { + Balance, + EthereumTransaction, + getERC20PegContract, + getBridgeContract, +} from "@/utils"; import { Api } from "@cennznet/api"; import { EthEventProof } from "@cennznet/api/derives/ethBridge/types"; import { BigNumber, ethers } from "ethers"; @@ -8,28 +12,28 @@ import { TransactionResponse } from "@ethersproject/abstract-provider"; export default async function sendWithdrawEthereumRequest( api: Api, - eventProof: EthEventProof, + eventProof: EthEventProof | HistoricalEventProof, transferAmount: Balance, transferAsset: BridgedEthereumToken, ethereumAddress: string, - signer: ethers.Signer, - blockHash?: string + signer: ethers.Signer ): Promise { - const notaryKeys = !!blockHash - ? (( - await api.query.ethBridge.notaryKeys.at(blockHash) - ).toJSON() as string[]) - : ((await api.query.ethBridge.notaryKeys()).toJSON() as string[]); + let validators: string[]; + if (!eventProof.validators) { + const notaryKeys = ( + await api.query.ethBridge.notaryKeys() + ).toJSON() as string[]; - const validators = notaryKeys.map((validator) => { - if ( - validator === - "0x000000000000000000000000000000000000000000000000000000000000000000" - ) - return ethers.constants.AddressZero; + validators = notaryKeys.map((validator) => { + if ( + validator === + "0x000000000000000000000000000000000000000000000000000000000000000000" + ) + return ethers.constants.AddressZero; - return ethers.utils.computeAddress(validator); - }); + return ethers.utils.computeAddress(validator); + }); + } const bridgeContract = getBridgeContract<"OnBehalf">(signer); const pegContract = getERC20PegContract<"OnBehalf">(signer); @@ -38,7 +42,7 @@ export default async function sendWithdrawEthereumRequest( transferAsset.address, transferAmount.toBigNumber(), ethereumAddress, - { ...eventProof, validators }, + { ...eventProof, validators: eventProof.validators ?? validators }, { value: verificationFee } ); const tx = new EthereumTransaction(); @@ -47,7 +51,7 @@ export default async function sendWithdrawEthereumRequest( transferAsset.address, transferAmount.toBigNumber(), ethereumAddress, - { ...eventProof, validators }, + { ...eventProof, validators: eventProof.validators ?? validators }, { value: verificationFee, gasLimit: (gasFee.toNumber() * 1.02).toFixed() } ) .then((pegTx: TransactionResponse) => {