Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
chrstph-dvx committed Oct 13, 2023
1 parent b666ef5 commit 0e6156d
Showing 1 changed file with 151 additions and 78 deletions.
229 changes: 151 additions & 78 deletions src/app/tx/[tx]/L2ToL1MsgsDisplay.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
'use client';
import { useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { ChainId, supportedL2Networks } from '@/utils/network';
import { L2ToL1MessageData } from '@/types';
import {
Expand All @@ -9,6 +9,7 @@ import {
} from '@arbitrum/sdk';
import { useNetwork, useSigner } from 'wagmi';
import { JsonRpcProvider } from '@ethersproject/providers';
import { L2ToL1TransactionEvent } from '@arbitrum/sdk/dist/lib/message/L2ToL1Message';

const etaDisplay = (etaSeconds: number) => {
const minutesLeft = Math.round(etaSeconds / 60);
Expand Down Expand Up @@ -44,94 +45,166 @@ type Props = {
l2ToL1Messages: L2ToL1MessageDataLike[];
};

function L2ToL1MsgsDisplay({ l2ToL1Messages }: Props) {
type L2ToL1TransactionEventWithTransactionHash = L2ToL1TransactionEvent & {
transactionHash: string;
};

function ConfirmedMessageDisplay({
l2ToL1Message,
}: {
l2ToL1Message: L2ToL1MessageDataLike;
}) {
const { chain } = useNetwork();
const { data: signer = null } = useSigner({ chainId: chain?.id });
const [isRedeeming, setIsRedeeming] = useState(false);
const l2Provider = new JsonRpcProvider(
supportedL2Networks[l2ToL1Message.l2Network.chainID as ChainId],
);
return (
<div>
<p>L2 to L1 message confirmed, ready to redeem</p>
{chain?.id !== l2ToL1Message.l1Network.chainID ? (
<div>
{`To redeem, connect to chain ${l2ToL1Message.l1Network.chainID} (${l2ToL1Message.l1Network.name})`}
</div>
) : (
<div className="redeem-button-container">
<button
disabled={isRedeeming}
onClick={async () => {
try {
if (!signer) return;
setIsRedeeming(true);
const l2ToL1TxEvents = await L2ToL1Message.getL2ToL1Events(
l2Provider,
{
fromBlock: l2ToL1Message.createdAtL2BlockNumber,
toBlock: l2ToL1Message.createdAtL2BlockNumber + 1,
},
);
const l2ToL1MessageWriter = new L2ToL1MessageWriter(
signer,
l2ToL1TxEvents[l2ToL1TxEvents.length - 1],
);
const res = await l2ToL1MessageWriter.execute(l2Provider);
console.log('ucu');
const rec = await res.wait();
if (rec.status === 1) {
alert(
`L2toL1 message successfully redeemed! ${rec.transactionHash}`,
);
} else {
throw new Error('Failed to redeem');
}
} catch (e: any) {
// Ignore user rejected action
if (e?.code !== 4001 && e?.code !== 'ACTION_REJECTED') {
throw e;
}
} finally {
setIsRedeeming(false);
}
}}
>
Redeem
</button>
</div>
)}
</div>
);
}

const renderMessage = (l2ToL1Message: L2ToL1MessageDataLike) => {
switch (l2ToL1Message.status) {
case L2ToL1MessageStatus.UNCONFIRMED:
return (
<div>
<p>L2 to L1 message not yet confirmed</p>

{l2ToL1Message.confirmationInfo ? (
<p>
{' ETA:'}
{etaDisplay(
l2ToL1Message.confirmationInfo.etaSeconds,
)} <br /> (L1 block deadline:{' '}
{l2ToL1Message.confirmationInfo.deadlineBlock})
</p>
) : null}
</div>
);
case L2ToL1MessageStatus.CONFIRMED:
const l2Provider = new JsonRpcProvider(
supportedL2Networks[l2ToL1Message.l2Network.chainID as ChainId],
);
return (
<div>
<p>L2 to L1 message confirmed, ready to redeem</p>
{chain?.id !== l2ToL1Message.l1Network.chainID ? (
<div>
{`To redeem, connect to chain ${l2ToL1Message.l1Network.chainID} (${l2ToL1Message.l1Network.name})`}
</div>
) : (
<div className="redeem-button-container">
<button
disabled={isRedeeming}
onClick={async () => {
try {
if (!signer) return;
setIsRedeeming(true);
const l2ToL1TxEvents =
await L2ToL1Message.getL2ToL1Events(l2Provider, {
fromBlock: l2ToL1Message.createdAtL2BlockNumber,
toBlock: l2ToL1Message.createdAtL2BlockNumber + 1,
});
const l2ToL1MessageWriter = new L2ToL1MessageWriter(
signer,
l2ToL1TxEvents[l2ToL1TxEvents.length - 1],
);
const res = await l2ToL1MessageWriter.execute(l2Provider);
const rec = await res.wait();
if (rec.status === 1) {
alert(
`L2toL1 message successfully redeemed! ${rec.transactionHash}`,
);
} else {
throw new Error('Failed to redeem');
}
} catch (e: any) {
// Ignore user rejected action
if (e?.code !== 4001 && e?.code !== 'ACTION_REJECTED') {
throw e;
}
} finally {
setIsRedeeming(false);
}
}}
>
Redeem
</button>
</div>
)}
</div>
);
case L2ToL1MessageStatus.EXECUTED:
return <div>Your message has been executed 🎉</div>;
function UnconfirmedMessageDisplay({
confirmationInfo,
}: {
confirmationInfo: L2ToL1MessageDataLike['confirmationInfo'];
}) {
return (
<div>
<p>L2 to L1 message not yet confirmed</p>

{confirmationInfo ? (
<p>
{' ETA:'}
{etaDisplay(confirmationInfo.etaSeconds)} <br /> (L1 block deadline:{' '}
{confirmationInfo.deadlineBlock})
</p>
) : null}
</div>
);
}

function L2ToL1MessageDisplay({
l2ToL1Message,
}: {
l2ToL1Message: L2ToL1MessageDataLike;
}) {
const [events, setEvents] = useState<
L2ToL1TransactionEventWithTransactionHash[]
>([]);
const [isLoading, setIsLoading] = useState(true);
const l2Provider = useMemo(
() =>
new JsonRpcProvider(
supportedL2Networks[l2ToL1Message.l2Network.chainID as ChainId],
),
[l2ToL1Message.l2Network.chainID],
);

useEffect(() => {
async function getEvents() {
setIsLoading(true);
const l2ToL1TxEvents = await L2ToL1Message.getL2ToL1Events(l2Provider, {
fromBlock: l2ToL1Message.createdAtL2BlockNumber,
toBlock: l2ToL1Message.createdAtL2BlockNumber + 1,
});
console.log('getEvents', l2ToL1TxEvents);
setEvents(l2ToL1TxEvents);
setIsLoading(false);
}
};

getEvents();
}, [l2Provider, l2ToL1Message]);

if (isLoading) {
return null;
}

if (events.length === 0) {
return null;
}

return (
<>
<h2>Your transaction status:</h2>
{events.map((event, i) => {
if (l2ToL1Message.status === L2ToL1MessageStatus.UNCONFIRMED) {
return (
<UnconfirmedMessageDisplay
confirmationInfo={l2ToL1Message.confirmationInfo}
key={i}
/>
);
}
if (l2ToL1Message.status === L2ToL1MessageStatus.CONFIRMED) {
console.log(l2ToL1Message, event);
return (
<ConfirmedMessageDisplay l2ToL1Message={l2ToL1Message} key={i} />
);
}
return <div key={i}>Your message has been executed 🎉</div>;
})}
</>
);
}

function L2ToL1MsgsDisplay({ l2ToL1Messages }: Props) {
return (
<>
{l2ToL1Messages.map((l2ToL1Message, i) => {
return (
<div key={i}>
<h2>Your transaction status:</h2>
{renderMessage(l2ToL1Message)}
<L2ToL1MessageDisplay l2ToL1Message={l2ToL1Message} />
</div>
);
})}
Expand Down

0 comments on commit 0e6156d

Please sign in to comment.