Skip to content

Commit

Permalink
uopdated the voucher code made it reuasable and added ERC1155 to the …
Browse files Browse the repository at this point in the history
…tabs in balance component
  • Loading branch information
gconnect committed May 29, 2024
1 parent 950f043 commit c6f4dde
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 247 deletions.
12 changes: 0 additions & 12 deletions apps/frontend/next-app/app/cartesi/Inspect.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,3 @@
// Copyright 2022 Cartesi Pte. Ltd.

// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the license at http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

import React from "react";
import { ethers } from "ethers";
import { useInspectCall } from "../cartesi/hooks/useInspectCall";
Expand Down
21 changes: 4 additions & 17 deletions apps/frontend/next-app/app/cartesi/Notices.tsx
Original file line number Diff line number Diff line change
@@ -1,28 +1,15 @@
"use client"
// Copyright 2022 Cartesi Pte. Ltd.

// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the license at http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

import { ethers } from "ethers";
import React, {useEffect} from "react";
import { useNotices } from "./hooks/useNotices";
import { useRollups } from "./hooks/useRollups";
import { DAPP_ADDRESS } from "../utils/constants";


export const Notices: React.FC = () => {
const {loading, error, data, notices, refetch } = useNotices()

useEffect(() => {
refetch({ requestPolicy: 'network-only' });
}, []);
}, [refetch]);

if (loading) return <p>Loading...</p>;
if (error) return <p className="text-slate-400">Oh no... {error.message}</p>;
Expand All @@ -31,8 +18,8 @@ export const Notices: React.FC = () => {

return (
<div>
<button className="text-slate-400" onClick={() => refetch({ requestPolicy: 'network-only' })}>
Reload
<button className="text-slate-400 mb-4" onClick={() => refetch({ requestPolicy: 'network-only' })}>
Reload 🔃
</button>
<table className="text-slate-400 border">
<thead>
Expand Down
26 changes: 26 additions & 0 deletions apps/frontend/next-app/app/cartesi/Portals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,29 @@ export const transferErc1155BatchToPortal = async (
}
};

export const executeVoucher = async (
rollups: RollupsContracts | undefined,
signer: JsonRpcSigner | undefined,
setVoucherToExecute: Function,
voucher: any
) => {
if (rollups && !!voucher.proof) {

const newVoucherToExecute = {...voucher};
try {
const tx = await rollups.dappContract.executeVoucher( voucher.destination,voucher.payload,voucher.proof);
const trans = await signer?.sendTransaction(tx)
const receipt = await trans?.wait(1);
newVoucherToExecute.msg = `voucher executed! (tx="${receipt?.hash}")`;
const event = (await rollups.dappContract.queryFilter(rollups.dappContract.filters.VoucherExecuted(), receipt?.blockHash)).pop();
if (event) {
newVoucherToExecute.msg = `${newVoucherToExecute.msg} - resulting events: ${JSON.stringify(receipt?.hash)}`;
newVoucherToExecute.executed = await rollups.dappContract.wasVoucherExecuted(toBigInt(voucher.input.index),toBigInt(voucher.index));
}
} catch (e) {
newVoucherToExecute.msg = `COULD NOT EXECUTE VOUCHER: ${JSON.stringify(e)}`;
console.log(`COULD NOT EXECUTE VOUCHER: ${JSON.stringify(e)}`);
}
setVoucherToExecute(newVoucherToExecute);
}
}
4 changes: 2 additions & 2 deletions apps/frontend/next-app/app/cartesi/Reports.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ export const Reports: React.FC = () => {
</Tr>
</Thead>
<Tbody>
{reports.length === 0 && (
{reports && reports.length === 0 && (
<Tr>
<Td colSpan={4}>-</Td>
</Tr>
)}
{reports.map((n: any) => (
{reports && reports.map((n: any) => (
<Tr key={`${n.input.index}-${n.index}`}>
{/* <Td>{n.input.index}</Td>
<Td>{n.index}</Td> */}
Expand Down
199 changes: 32 additions & 167 deletions apps/frontend/next-app/app/cartesi/Vouchers.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
"use client"
// Copyright 2022 Cartesi Pte. Ltd.

// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
// of the license at http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

import { ethers } from "ethers";
import { ethers, toBigInt } from "ethers";
import React, { useEffect } from "react";
import { useVouchersQuery, useVoucherQuery } from "./generated/graphql";
import { useRollups } from "./hooks/useRollups";
import {
Table,
Expand All @@ -26,176 +14,50 @@ import {
Text
} from '@chakra-ui/react'
import { useEthersSigner } from "../utils/useEtherSigner";

type Voucher = {
id: string;
index: number;
destination: string;
input: any, //{index: number; epoch: {index: number; }
payload: string;
proof: any;
executed: any;
};

interface IVoucherPropos {
import { Voucher, useVouchers } from "./hooks/useVouchers";
import { executeVoucher } from "./Portals";
interface IVoucherProps {
dappAddress: string
}

export const Vouchers: React.FC<IVoucherPropos> = (propos) => {
const [result,reexecuteQuery] = useVouchersQuery();
export const Vouchers: React.FC<IVoucherProps> = (props) => {
const {loading, error, data, vouchers, voucherResult, refetch } = useVouchers()

const [voucherToFetch, setVoucherToFetch] = React.useState([0,0]);
const [voucherResult,reexecuteVoucherQuery] = useVoucherQuery({
variables: { voucherIndex: voucherToFetch[0], inputIndex: voucherToFetch[1] }//, pause: !!voucherIdToFetch
});

const [voucherToExecute, setVoucherToExecute] = React.useState<any>();
const { data, fetching, error } = result;
const rollups = useRollups(propos.dappAddress);
const rollups = useRollups(props.dappAddress);
const signer = useEthersSigner()
const provider = signer?.provider

const getProof = async (voucher: Voucher) => {
setVoucherToFetch([voucher.index,voucher.input.index]);
reexecuteVoucherQuery({ requestPolicy: 'network-only' });
setVoucherToFetch([voucher.index, voucher.input.index]);
refetch({ requestPolicy: 'network-only' });
};

const executeVoucher = async (voucher: any) => {
if (rollups && !!voucher.proof) {

const newVoucherToExecute = {...voucher};
try {
const tx = await rollups.dappContract.executeVoucher( voucher.destination,voucher.payload,voucher.proof);
const trans = await signer?.sendTransaction(tx)
const receipt = await trans?.wait(1);
newVoucherToExecute.msg = `voucher executed! (tx="${receipt?.hash}")`;
if (receipt.events) {
newVoucherToExecute.msg = `${newVoucherToExecute.msg} - resulting events: ${JSON.stringify(receipt.events)}`;
newVoucherToExecute.executed = await rollups.dappContract.wasVoucherExecuted(BigNumber.from(voucher.input.index),BigNumber.from(voucher.index));
}
} catch (e) {
newVoucherToExecute.msg = `COULD NOT EXECUTE VOUCHER: ${JSON.stringify(e)}`;
console.log(`COULD NOT EXECUTE VOUCHER: ${JSON.stringify(e)}`);
}
setVoucherToExecute(newVoucherToExecute);
}
}

useEffect( () => {
const setVoucher = async (voucher: any) => {
const setVoucher = async (voucher: Voucher) => {
if (rollups) {
voucher.executed = await rollups.dappContract.wasVoucherExecuted(BigNumber.from(voucher.input.index),BigNumber.from(voucher.index));
voucher.executed = await rollups.dappContract.wasVoucherExecuted(toBigInt(voucher.input.index),toBigInt(voucher.index));
}
console.log( voucher.executed)
setVoucherToExecute(voucher);
}

if (!voucherResult.fetching && voucherResult.data){
setVoucher(voucherResult.data.voucher);
if (!voucherResult?.executed && voucherResult){
setVoucher(voucherResult);
}
},[voucherResult, rollups]);

if (fetching) return <p>Loading...</p>;
if (error) return <p>Oh no... {error.message}</p>;
},[voucherResult, voucherToFetch, rollups]);


if (!data || !data.vouchers) return <p>No vouchers</p>;
if (loading) return <p className="text-slate-400">Loading...</p>;
if (error) return <p className="text-slate-400">Oh no... {error.message}</p>;

const vouchers: Voucher[] = data.vouchers.edges.map((node: any) => {
const n = node.node;
let payload = n?.payload;
let inputPayload = n?.input.payload;
if (inputPayload) {
try {
inputPayload = ethers.toUtf8String(inputPayload);
} catch (e) {
inputPayload = inputPayload + " (hex)";
}
} else {
inputPayload = "(empty)";
}
if (payload) {
const decoder = new ethers.AbiCoder();
const selector = decoder.decode(["bytes4"], payload)[0];
payload = ethers.dataSlice(payload,4);
try {
switch(selector) {
case '0xa9059cbb': {
// erc20 transfer;
const decode = decoder.decode(["address","uint256"], payload);
payload = `Erc20 Transfer - Amount: ${ethers.formatEther(decode[1])} - Address: ${decode[0]}`;
break;
}
case '0x42842e0e': {
//erc721 safe transfer;
const decode = decoder.decode(["address","address","uint256"], payload);
payload = `Erc721 Transfer - Id: ${decode[2]} - Address: ${decode[1]}`;
break;
}
case '0x522f6815': {
//ether transfer;
const decode2 = decoder.decode(["address", "uint256"], payload)
payload = `Ether Transfer - Amount: ${ethers.formatEther(decode2[1])} (Native eth) - Address: ${decode2[0]}`;
break;
}
case '0xf242432a': {
//erc155 single safe transfer;
const decode = decoder.decode(["address","address","uint256","uint256"], payload);
payload = `Erc1155 Single Transfer - Id: ${decode[2]} Amount: ${decode[3]} - Address: ${decode[1]}`;
break;
}
case '0x2eb2c2d6': {
//erc155 Batch safe transfer;
const decode = decoder.decode(["address","address","uint256[]","uint256[]"], payload);
payload = `Erc1155 Batch Transfer - Ids: ${decode[2]} Amounts: ${decode[3]} - Address: ${decode[1]}`;
break;
}
case '0xd0def521': {
//erc721 mint;
const decode = decoder.decode(["address","string"], payload);
payload = `Mint Erc721 - String: ${decode[1]} - Address: ${decode[0]}`;
break;
}
case '0x755edd17': {
//erc721 mintTo;
const decode = decoder.decode(["address"], payload);
payload = `Mint Erc721 - Address: ${decode[0]}`;
break;
}
case '0x6a627842': {
//erc721 mint;
const decode = decoder.decode(["address"], payload);
payload = `Mint Erc721 - Address: ${decode[0]}`;
break;
}
default: {
break;
}
}
} catch (e) {
console.log(e);
}
} else {
payload = "(empty)";
}
return {
id: `${n?.id}`,
index: parseInt(n?.index),
destination: `${n?.destination ?? ""}`,
payload: `${payload}`,
input: n ? {index:n.input.index,payload: inputPayload} : {},
proof: null,
executed: null,
};
}).sort((b: any, a: any) => {
if (a.input.index === b.input.index) {
return b.index - a.index;
} else {
return b.input.index - a.input.index;
}
});
if (!data || !data.vouchers) return <p className="text-slate-400">No vouchers</p>;

// const forceUpdate = useForceUpdate();
return (
<div>
<div className="text-slate-400">
<p></p>
<Button marginTop={'15px'} float={'right'} size='sm' onClick={() => reexecuteQuery({ requestPolicy: 'network-only' })}>
<Button marginTop={'15px'} float={'right'} size='sm' onClick={() => refetch({ requestPolicy: 'network-only' })}>
Reload 🔃
</Button>
{voucherToExecute ?
Expand All @@ -213,13 +75,16 @@ export const Vouchers: React.FC<IVoucherPropos> = (propos) => {
</Tr>
</Thead>
<Tbody>
<Tr key={`${voucherToExecute.input.index}-${voucherToExecute.index}`}>
<Td>{voucherToExecute.input.index}</Td>
<Tr key={`${voucherToExecute && voucherToExecute.input.index}-${voucherToExecute && voucherToExecute.index}`}>
<Td>{voucherToExecute && voucherToExecute.input.index}</Td>
{/*<Td>{voucherToExecute.destination}</Td> */}
<Td>
<Button size='sm' isDisabled={!voucherToExecute.proof || voucherToExecute.executed} onClick={() => executeVoucher(voucherToExecute)}>{voucherToExecute.proof ? (voucherToExecute.executed ? "Voucher executed" : "Execute voucher") : "No proof yet"}</Button>
<Button size='sm' isDisabled={voucherToExecute && !voucherToExecute.proof || voucherToExecute && voucherToExecute.executed}
onClick={() => executeVoucher(rollups, signer, setVoucherToExecute, voucherToExecute)}>{voucherToExecute && voucherToExecute.proof ?
(voucherToExecute.executed ? "Voucher executed" : "Execute voucher") : "No proof yet"}
</Button>
</Td>
<Td>{voucherToExecute.index}</Td>
<Td>{voucherToExecute && voucherToExecute.index}</Td>
{/* <td>{voucherToExecute.payload}</td> */}
{/* <td>{voucherToExecute.proof}</td> */}
{/* <Td>{voucherToExecute.input.payload}</Td> */}
Expand All @@ -241,12 +106,12 @@ export const Vouchers: React.FC<IVoucherPropos> = (propos) => {
</Tr>
</Thead>
<Tbody>
{vouchers.length === 0 && (
{vouchers && vouchers.length === 0 && (
<Tr>
<Td textAlign={'center'} colSpan={4}>-</Td>
</Tr>
)}
{vouchers.map((n: any) => (
{vouchers && vouchers.map((n: any) => (
<Tr key={`${n.input.index}-${n.index}`}>
{/*<Td>{n.input.index}</Td>
<Td>{n.index}</Td>
Expand Down
Loading

0 comments on commit c6f4dde

Please sign in to comment.