Skip to content
This repository has been archived by the owner on Nov 8, 2023. It is now read-only.

Commit

Permalink
Merge pull request #179 from statechannels/client-l1-txHash
Browse files Browse the repository at this point in the history
Pop L1 txHash after it succeeds - or an error if it doesn't
  • Loading branch information
bitwiseguy authored Oct 20, 2023
2 parents 53ec9d5 + 490328e commit 7587425
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 107 deletions.
5 changes: 4 additions & 1 deletion clients/IntermediaryClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ export class IntermediaryClient extends StateChannelWallet {
if (value > balanceWEI) {
// todo: account for expected gas consumption? ( out of scope for hackathon )
this.coordinator.uiLog("insufficient balance to execute user op");
this.ack("insufficient balance to execute user op");
throw new Error("Transfer amount exceeds owner balance");
}
const ownerSig = userOp.signature;
Expand All @@ -296,7 +297,9 @@ export class IntermediaryClient extends StateChannelWallet {
const tx = await result.wait();
if (tx !== null) {
this.coordinator.uiLog("user op mined: " + tx.hash);
this.ack(tx.hash);
} else {
this.ack("something terrible has happened");
}
this.ack(userOp.signature);
}
}
6 changes: 3 additions & 3 deletions clients/OwnerClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,17 @@ export class OwnerClient extends StateChannelWallet {
signature,
};

void this.sendPeerMessage({
const l1Hash = await this.sendPeerMessage({
type: MessageType.UserOperation,
...signedUserOp,
});

console.log(
`Initiated transfer of ${ethers.formatEther(
amount,
)} ETH to ${payee} (userOpHash: ${hash})`,
)} ETH to ${payee} (userOpHash: ${hash}). Mined at ${l1Hash.signature}.`,
);

return hash;
return l1Hash.signature; // todo: not a signature, but reusing existing ack pipe type
}
}
5 changes: 4 additions & 1 deletion src/AddressIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ export const AddressIcon: FunctionComponent<{
}> = (props: { address: `0x${string}`; chain?: ChainData }) => {
return props.chain !== undefined ? (
<Tooltip title={props.address}>
<a href={props.chain.explorer + "/" + props.address} target="_blank">
<a
href={props.chain.explorer + "address/" + props.address}
target="_blank"
>
<Avatar
{...props}
src={blo(props.address)}
Expand Down
72 changes: 47 additions & 25 deletions src/Wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import React, { useState } from "react";
import BoltIcon from "@mui/icons-material/Bolt";
import AccessTimeIcon from "@mui/icons-material/AccessTime";
import EjectIcon from "@mui/icons-material/Eject";
import CircularProgress from "@mui/material/CircularProgress";
import {
Avatar,
Button,
Expand All @@ -11,6 +12,7 @@ import {
Container,
Divider,
InputAdornment,
Snackbar,
Stack,
TextField,
ThemeProvider,
Expand All @@ -26,7 +28,6 @@ import { AddressIcon, AddressIconSmall } from "./AddressIcon";
import "./Wallet.css";
import { type Role } from "./WalletContainer";
import logo from "./assets/logo.png";
import L1PaymentModal from "./modals/L1Payment";
import { useBalances } from "./useBalances";
import EjectModal from "./modals/Eject";
import { chains, type ChainData } from "./chains";
Expand All @@ -40,6 +41,8 @@ let myPeerSCWAddress: string;
let myChainUrl: string;
let myChain: ChainData;

let txHash: string = "";

const startingIntermediaryBalance = BigInt(
// @ts-expect-error
parseInt(import.meta.env.VITE_INTERMEDIARY_BALANCE, 10),
Expand Down Expand Up @@ -99,27 +102,23 @@ const Wallet: React.FunctionComponent<{ role: Role }> = (props: {
const defaultPaymentSize = // @ts-expect-error
BigInt(parseInt(import.meta.env.VITE_SCW_DEPOSIT, 10) / 100);

const [snackBarOpen, setSnackBarOpen] = useState(false);
const [chainPayProcessing, setChainPayProcessing] = useState(false);
const [recipient, setRecipient] = useState(myPeerSCWAddress);
const [isModalL1PayOpen, setModalL1PayOpen] = useState<boolean>(false);
const [isModalEjectOpen, setModalEjectOpen] = useState<boolean>(false);
const [userOpHash, setUserOpHash] = useState<string | null>(null);
const [payAmount, setPayAmount] = useState<string>(
ethers.formatEther(defaultPaymentSize),
);
const [errorL1Pay, setErrorL1Pay] = useState<string | null>(null);

const handleL1Pay = async (payee: string, amount: bigint): Promise<void> => {
setChainPayProcessing(true);
try {
const resultHash = await wallet.payL1(payee, amount);
setUserOpHash(resultHash);
setErrorL1Pay(null); // Clear any previous error
setModalL1PayOpen(true);
txHash = await wallet.payL1(payee, amount);
setSnackBarOpen(true);
} catch (e: any) {
console.error(e);
// setErrorL1Pay("Error initiating L1 payment");
setErrorL1Pay("Error: " + e.message);
console.error(e.message);
} finally {
setModalL1PayOpen(true);
setChainPayProcessing(false);
}
};

Expand Down Expand Up @@ -256,12 +255,17 @@ const Wallet: React.FunctionComponent<{ role: Role }> = (props: {
<ButtonGroup variant="outlined" aria-label="outlined button group">
<Button
size="medium"
disabled={recipient === ""}
disabled={recipient === "" || chainPayProcessing}
onClick={() => {
void handleL1Pay(recipient, ethers.parseEther(payAmount));
}}
>
<AccessTimeIcon style={{ marginRight: "5px" }} /> Chain Pay
{chainPayProcessing ? (
<CircularProgress size={24} style={{ marginRight: "5px" }} />
) : (
<AccessTimeIcon style={{ marginRight: "5px" }} />
)}
Chain Pay
</Button>
<Button
size="medium"
Expand All @@ -279,17 +283,6 @@ const Wallet: React.FunctionComponent<{ role: Role }> = (props: {
<BoltIcon /> Bridge Pay
</Button>
</ButtonGroup>

<L1PaymentModal
isOpen={isModalL1PayOpen}
onClose={() => {
setModalL1PayOpen(false);
}}
errorMessage={errorL1Pay}
userOpHash={userOpHash}
amount={Number(payAmount)}
payee={recipient}
/>
</Stack>
<Divider />
<Stack
Expand Down Expand Up @@ -324,6 +317,35 @@ const Wallet: React.FunctionComponent<{ role: Role }> = (props: {
</Stack>
</Stack>
</Card>
<Snackbar
open={snackBarOpen}
autoHideDuration={4000}
onClose={() => {
setSnackBarOpen(false);
}}
message={
txHash.startsWith("0x") ? ( // received a good tx Hash
myChain.explorer !== "" ? (
<>
Transaction mined at
<a
href={`${myChain.explorer}tx/${txHash}`}
target="_blank"
rel="noopener noreferrer"
style={{ color: "inherit", textDecoration: "underline" }}
>
{" "}
{txHash}
</a>
</>
) : (
`Transaction mined at ${txHash}`
)
) : (
`Error submitting Tx: ${txHash}`
)
}
></Snackbar>
</ThemeProvider>
);
};
Expand Down
4 changes: 2 additions & 2 deletions src/chains.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const chains: ChainData[] = [
url: "https://rpc.public.zkevm-test.net",
chainID: 1442n,
exchangeRate: 1,
explorer: "https://testnet-zkevm.polygonscan.com/address/",
explorer: "https://testnet-zkevm.polygonscan.com/",
},
{
url: "http://localhost:8545",
Expand All @@ -63,8 +63,8 @@ export const chains: ChainData[] = [
chainID: 534351n,
url: "https://sepolia-rpc.scroll.io",
name: "scroll",
explorer: "https://sepolia.scrollscan.com/",
symbol: "scrETH",
explorer: "https://sepolia.scrollscan.com/address/",
exchangeRate: 1,
},
];
75 changes: 0 additions & 75 deletions src/modals/L1Payment.tsx

This file was deleted.

0 comments on commit 7587425

Please sign in to comment.