diff --git a/schemas/request.gql b/schemas/request.gql
index 3504c54..db31168 100644
--- a/schemas/request.gql
+++ b/schemas/request.gql
@@ -69,6 +69,7 @@ query Request($id: ID!) {
}
nbRounds
rounds(orderBy: creationTime) {
+ creationTime
requesterFund {
amount
}
diff --git a/src/app/[pohid]/[chain]/[request]/ActionBar.tsx b/src/app/[pohid]/[chain]/[request]/ActionBar.tsx
index a6a052a..95ef1f0 100644
--- a/src/app/[pohid]/[chain]/[request]/ActionBar.tsx
+++ b/src/app/[pohid]/[chain]/[request]/ActionBar.tsx
@@ -24,6 +24,7 @@ import RemoveVouch from "./RemoveVouch";
import Vouch from "./Vouch";
import { getMyData } from "data/user";
import useSWR from "swr";
+import Appeal from "./Appeal";
enableReactUse();
@@ -425,6 +426,24 @@ export default withClientConnected(function ActionBar({
)}
.
+
+
+
1 && currentChallenge.rounds.at(0)?.challengerFund?.amount}
+ claimerFunds={currentChallenge.rounds.length>1 && currentChallenge.rounds.at(0)?.requesterFund.amount} */
+ chainId={chain.id}
+ />
(function ActionBar({
>
View case #{currentChallenge.disputeId}
+
>
)}
diff --git a/src/app/[pohid]/[chain]/[request]/Appeal.tsx b/src/app/[pohid]/[chain]/[request]/Appeal.tsx
index a9872bf..c84ae67 100644
--- a/src/app/[pohid]/[chain]/[request]/Appeal.tsx
+++ b/src/app/[pohid]/[chain]/[request]/Appeal.tsx
@@ -3,44 +3,231 @@
import Accordion from "components/Accordion";
import Identicon from "components/Identicon";
import Progress from "components/Progress";
-import { formatEth } from "utils/misc";
+import { eth2Wei, formatEth } from "utils/misc";
import usePoHWrite from "contracts/hooks/usePoHWrite";
-import { Address, Hash } from "viem";
+import { Address } from "viem";
+import { useMemo, useRef, useState } from "react";
+import Field from "components/Field";
+import Modal from "components/Modal";
+import { SupportedChainId } from "config/chains";
+import { toast } from "react-toastify";
+import { useEffectOnce } from "@legendapp/state/react";
+import TimeAgo from "components/TimeAgo";
+import { useLoading } from "hooks/useLoading";
+import { APIPoH, ArbitratorFromRequest, CurrentRoundSideFunds, StakeMultipliers } from "contracts/apis/APIPoH";
+import { APIArbitrator, ArbitratorsData, DisputeStatusEnum, SideEnum } from "contracts/apis/APIArbitrator";
-interface AppealProps {
- pohId: Hash;
+
+interface SideFundingProps {
+ side: SideEnum;
+ arbitrator: Address;
+ disputeId: bigint;
+ contributor: Address;
requester: Address;
+ requesterFunds: bigint;
+ appealCost: bigint;
+}
+
+const SideFunding: React.FC = ({
+ side,
+ disputeId,
+ arbitrator,
+ contributor,
+ requester,
+ requesterFunds,
+ appealCost,
+}) => {
+
+ const title = side === SideEnum.claimer? 'Claimer' : 'Challenger';
+ const [requesterInput, setRequesterInput] = useState(0n);
+ const loading = useLoading();
+ const errorRef = useRef(false);
+
+ const value = formatEth(requesterFunds)*100/formatEth(appealCost);
+ const valueProgress = value > 100? 100 : value;
+
+ const [prepareFundAppeal] = usePoHWrite(
+ "fundAppeal",
+ useMemo(
+ () => ({
+ onLoading() {
+ loading.start();
+ },
+ onReady(fire) {
+ fire();
+ },
+ onFail() {
+ !errorRef.current && toast.info("Transaction is not possible! Do you have enough funds?");
+ errorRef.current = true;
+ }
+ }),
+ [loading]
+ )
+ );
+
+ return (
+
+
+
+
+
+ {requester}
+ {title}
+
+
+
+ setRequesterInput(eth2Wei(+v.target.value))}
+ />
+ {
+ prepareFundAppeal({
+ args: [
+ arbitrator as Address,
+ BigInt(disputeId),
+ side,
+ ],
+ value: requesterInput,
+ })
+ }}
+ >
+ Fund
+
+
+
+
+
+ )
+}
+
+interface AppealProps {
+ pohId: Address;
+ requestIndex: number;
+ /* arbitrator: Address;
+ extraData: any, */
+ contributor: Address;
+ claimer: Address;
challenger: Address;
disputeId: bigint;
- requestIndex: bigint;
- challengeIndex: bigint;
- start: number;
- end: number;
- challengerFunds: bigint;
- requesterFunds: bigint;
+ /* challengerFunds: bigint;
+ claimerFunds: bigint; */
+ chainId: SupportedChainId;
}
const Appeal: React.FC = ({
pohId,
requestIndex,
- challengeIndex,
disputeId,
- requester,
+ /* arbitrator,
+ extraData, */
+ contributor,
+ chainId,
+ claimer,
challenger,
- start,
- end,
- challengerFunds,
- requesterFunds,
+ /* claimerFunds,
+ challengerFunds, */
}) => {
- const [fundAppeal] = usePoHWrite("fundAppeal");
+ const [totalClaimerCost, setTotalClaimerCost] = useState(0n);
+ const [totalChallengerCost, setTotalChallengerCost] = useState(0n);
+ const [formatedCurrentRuling, setFormatedCurrentRuling] = useState("");
+ const defaultPeriod = [0n,0n];
+ const [period, setPeriod] = useState(defaultPeriod);
+ const [disputeStatus, setDisputeStatus] = useState(DisputeStatusEnum.Appealable);
+ const [error, setError] = useState(false);
+ const errorRef = useRef(false);
+ const [loading, setLoading] = useState(true);
+ const [arbitrator, setArbitrator] = useState(null);
+ const [claimerFunds, setClaimerFunds] = useState(0n);
+ const [challengerFunds, setChallengerFunds] = useState(0n);
+
+ useEffectOnce(() => {
+ const formatCurrentRuling = (currentRuling: SideEnum) => {
+ var text = "Undecided";
+ switch (currentRuling) {
+ case SideEnum.claimer:
+ text = "Claimer wins";
+ break;
+ case SideEnum.challenger:
+ text = "Challenger wins";
+ break;
+ case SideEnum.shared:
+ text = "Shared";
+ }
+ setFormatedCurrentRuling(text);
+ }
- // const [requesterInput, setRequesterInput] = useState(0);
- // const [challengerInput, setChallengerInput] = useState(0);
+ const calculateTotalCost = (appealCost: bigint, currentRuling: SideEnum, winnerMult: number, loserMult: number, sharedMult: number) => {
+ const getSideTotalCost = (sideMultiplier: number) => {
+ return Number(appealCost) + ((Number(appealCost) * sideMultiplier) / MULTIPLIER_DIVISOR);
+ }
+ const MULTIPLIER_DIVISOR = 10000;
+
+ const claimerMultiplier = currentRuling === SideEnum.shared?sharedMult: currentRuling === SideEnum.claimer? winnerMult : loserMult;
+ const totalClaimerCost = getSideTotalCost(Number(claimerMultiplier));
+ setTotalClaimerCost(BigInt(totalClaimerCost));
+
+ const challengerMultiplier = currentRuling === SideEnum.shared?sharedMult: currentRuling === SideEnum.claimer? loserMult : winnerMult;
+ const totalChallengerCost = getSideTotalCost(Number(challengerMultiplier));
+ setTotalChallengerCost(BigInt(totalChallengerCost));
+ }
+ const getAppealData = async () => {
+ try{
+ const arbitratorFromRequest: ArbitratorFromRequest = await APIPoH.getArbitratorFromRequest(chainId, pohId, requestIndex);
+ const arbitrator = arbitratorFromRequest.arbitrator!;
+ const extraData = arbitratorFromRequest.extraData!;
+ setArbitrator(arbitrator as any);
+
+ const currentRoundSideFunds: CurrentRoundSideFunds = await APIPoH.getCurrentRoundSideFunds(chainId, pohId, requestIndex, arbitrator, disputeId);
+ setClaimerFunds(currentRoundSideFunds.claimerFunds!);
+ setChallengerFunds(currentRoundSideFunds.challengerFunds!);
+
+ const stakeMultipliers: StakeMultipliers = await APIPoH.getStakeMultipliers(chainId);
+ const winnerMult = stakeMultipliers.winnerStakeMultiplier;
+ const loserMult = stakeMultipliers.looserStakeMultiplier;
+ const sharedMult = stakeMultipliers.sharedStakeMultiplier;
+
+ const arbitratorsData: ArbitratorsData = await APIArbitrator.getArbitratorsData(chainId, arbitrator, disputeId, extraData);
+ const status = arbitratorsData.status;
+ const cost = arbitratorsData.cost;
+ const period = arbitratorsData.period;
+ const currentRuling = arbitratorsData.currentRuling;
+
+
+ setPeriod(period as any);
+ setDisputeStatus(Number(status) as DisputeStatusEnum);
+ //setDisputeStatus(1 as DisputeStatusEnum); // -------------------------------- JUST FOR TESTING
+ formatCurrentRuling(Number(currentRuling) as SideEnum);
+ calculateTotalCost(cost as any, Number(currentRuling) as SideEnum, Number(winnerMult), Number(loserMult), Number(sharedMult));
+
+ setLoading(false);
+ } catch (e) {
+ !errorRef.current && toast.info("Unexpected error while reading appelate round info. Come back later");
+ setError(true);
+ errorRef.current = true;
+ console.log(e);
+ }
+ }
+ getAppealData();
+ });
+
return (
-
-
-
Appeal the decision
+ disputeStatus === DisputeStatusEnum.Appealable && !error && !loading?
+
+ Fund Appeal (ends )
+ }
+ >
+
+
Appeal the decision: {formatedCurrentRuling}
In order to appeal the decision, you need to fully fund the
crowdfunding deposit. The dispute will be sent to the jurors when the
@@ -48,85 +235,32 @@ const Appeal: React.FC = ({
its side, the previous round winner should also fully fund its side,
in order not to lose the case.
+
+
+
+
-
-
-
-
- {requester}
- Claimer
-
-
-
- {/* setRequesterInput(+v.target.value)}
- /> */}
- {
- fundAppeal({
- args: [
- pohId,
- requestIndex,
- challengeIndex,
- 1, // requester
- ],
- // value: requesterInput,
- });
- }}
- >
- Fund
-
-
-
-
-
-
-
-
-
- {challenger}
- Challenger
-
-
-
- {/* setChallengerInput(+v.target.value)}
- /> */}
- {
- fundAppeal({
- args: [
- pohId,
- requestIndex,
- challengeIndex,
- 2, // challenger
- ],
- // value: challengerInput,
- });
- }}
- >
- Fund
-
-
-
-
-
+ requester={challenger}
+ requesterFunds={challengerFunds}
+ appealCost={totalChallengerCost}
+ />
-
+
+ : null
);
};
-export default Appeal;
+export default Appeal;
\ No newline at end of file
diff --git a/src/app/[pohid]/[chain]/[request]/Info.tsx b/src/app/[pohid]/[chain]/[request]/Info.tsx
index 4a5eec2..c865922 100644
--- a/src/app/[pohid]/[chain]/[request]/Info.tsx
+++ b/src/app/[pohid]/[chain]/[request]/Info.tsx
@@ -31,7 +31,7 @@ export default function Info({ nbRequests }: InfoProps) {
unique human registered on Proof of Humanity.
- This POH ID had {nbRequests} requests in total
+ This POH ID had {nbRequests} requests claimed in this chain
);
diff --git a/src/components/Attachment.tsx b/src/components/Attachment.tsx
index 870e325..9dd83e9 100644
--- a/src/components/Attachment.tsx
+++ b/src/components/Attachment.tsx
@@ -1,8 +1,8 @@
"use client";
-import Image from "next/image";
import Link from "next/link";
import { ipfs } from "utils/ipfs";
+import AttachmentIcon from "icons/AttachmentMajor.svg";
interface AttachmentProps {
uri: string;
@@ -13,13 +13,7 @@ const Attachment: React.FC = ({ uri }) => {
return (
-
+
);
};
diff --git a/src/config/subgraph.ts b/src/config/subgraph.ts
index e5653e4..738e05d 100644
--- a/src/config/subgraph.ts
+++ b/src/config/subgraph.ts
@@ -34,16 +34,16 @@ export const subgraph_url = {
),
[sepolia.id]: (
(configSetSelection.id === configSets.testOld.id) ?
- "https://api.studio.thegraph.com/query/64099/proof-of-humanity-sepolia-test/v0.0.14" // OLD
- //"https://api.studio.thegraph.com/query/64099/proof-of-humanity-sepolia-test/version/latest" // OLD
+ //"https://api.studio.thegraph.com/query/64099/proof-of-humanity-sepolia-test/v0.0.14" // TESTNETS
+ "https://api.studio.thegraph.com/query/64099/proof-of-humanity-sepolia-test/version/latest" // Development
: (configSetSelection.id === configSets.testNew.id) ?
"https://api.studio.thegraph.com/query/64099/proof-of-humanity-sepolia/version/latest"
: ""
),
[gnosisChiado.id]: (
(configSetSelection.id === configSets.testOld.id) ?
- "https://api.goldsky.com/api/public/project_cluh21be5gq0o01u27olk4rwl/subgraphs/proof-of-humanity-chiado/1.0.2/gn" // OLD
- //"https://api.goldsky.com/api/public/project_cluh21be5gq0o01u27olk4rwl/subgraphs/proof-of-humanity-chiado/1.0.0/gn" // OLD
+ //"https://api.goldsky.com/api/public/project_cluh21be5gq0o01u27olk4rwl/subgraphs/proof-of-humanity-chiado/1.0.2/gn" // TESTNETS
+ "https://api.goldsky.com/api/public/project_cluh21be5gq0o01u27olk4rwl/subgraphs/proof-of-humanity-chiado/1.0.0/gn" // Development
: (configSetSelection.id === configSets.testNew.id) ?
"https://api.goldsky.com/api/public/project_cluh21be5gq0o01u27olk4rwl/subgraphs/proof-of-humanity-chiado/1.0.1/gn"
: ""
diff --git a/src/contracts/apis/APIArbitrator.ts b/src/contracts/apis/APIArbitrator.ts
new file mode 100644
index 0000000..f93e5d0
--- /dev/null
+++ b/src/contracts/apis/APIArbitrator.ts
@@ -0,0 +1,77 @@
+import { SupportedChainId, getChainRpc, supportedChains } from "config/chains";
+import { Address, createPublicClient, http } from "viem";
+import Error from "next/error";
+import klerosLiquid from "contracts/abis/kleros-liquid";
+
+export enum DisputeStatusEnum {
+ Waiting,
+ Appealable,
+ Solved
+};
+
+export enum SideEnum {
+ shared,
+ claimer,
+ challenger
+};
+
+export interface ArbitratorsData {
+ status: DisputeStatusEnum | undefined;
+ cost: bigint | undefined;
+ period: bigint[] | undefined;
+ currentRuling: SideEnum | undefined;
+};
+
+export class APIArbitrator {
+
+ private static apiReader: APIArbitrator; // Singleton
+
+ private publicClient: any;
+ private chainId: SupportedChainId;
+ private address: Address;
+
+ constructor(_chainId: SupportedChainId, _arbitrator: Address) {
+ this.chainId = _chainId;
+ this.address = _arbitrator;
+ this.publicClient = createPublicClient({
+ chain: supportedChains[_chainId],
+ transport: http(getChainRpc(_chainId)),
+ });
+ }
+ private static getApiReader(_chainId: SupportedChainId, _arbitrator: Address) {
+ if (!APIArbitrator.apiReader || APIArbitrator.apiReader.chainId !== _chainId || APIArbitrator.apiReader.address !== _arbitrator)
+ APIArbitrator.apiReader = new APIArbitrator(_chainId, _arbitrator);
+ return APIArbitrator.apiReader;
+ }
+
+ private async get(func: string, args: Array = []) {
+ return await this.publicClient.readContract({
+ address: this.address,
+ abi: klerosLiquid as any,
+ functionName: func,
+ args: args
+ })
+ .catch(() => {
+ throw new Error({statusCode: 521, title: "Error while reading Arbitrator"});
+ });
+ }
+
+ public static async getArbitratorsData(chainId: SupportedChainId, _arbitrator: Address, disputeId: bigint, extraData: bigint) : Promise {
+ const apiReader = APIArbitrator.getApiReader(chainId, _arbitrator);
+ const out: ArbitratorsData = {
+ status: undefined,
+ cost: undefined,
+ currentRuling: undefined,
+ period: undefined
+ };
+ try {
+ out.status = await apiReader.get('disputeStatus', [disputeId]);
+ out.cost = await apiReader.get('appealCost', [disputeId, extraData]);
+ out.period = await apiReader.get('appealPeriod', [disputeId]);
+ out.currentRuling = await apiReader.get('currentRuling', [disputeId]);
+ return out;
+ } catch (error) {
+ throw new Error({statusCode: 521, title: "Error while reading Arbitrator"});
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/contracts/apis/APIPoH.ts b/src/contracts/apis/APIPoH.ts
new file mode 100644
index 0000000..aa6e96c
--- /dev/null
+++ b/src/contracts/apis/APIPoH.ts
@@ -0,0 +1,110 @@
+import { SupportedChainId, getChainRpc, supportedChains } from "config/chains";
+import { Contract } from "contracts";
+import abis from "contracts/abis";
+import { Address, createPublicClient, http } from "viem";
+import Error from "next/error";
+
+export interface ArbitratorFromRequest {
+ arbitrator: Address | undefined;
+ extraData: bigint | undefined;
+}
+
+export interface CurrentRoundSideFunds {
+ claimerFunds: bigint | undefined;
+ challengerFunds: bigint | undefined;
+}
+
+export interface StakeMultipliers {
+ winnerStakeMultiplier: bigint | undefined;
+ looserStakeMultiplier: bigint | undefined;
+ sharedStakeMultiplier: bigint | undefined;
+}
+
+export class APIPoH {
+
+ private static apiReader: APIPoH; // Singleton
+
+ private publicClient: any;
+ private chainId: SupportedChainId;
+ private address: Address;
+
+ constructor(_chainId: SupportedChainId) {
+ this.chainId = _chainId;
+ this.address = Contract.ProofOfHumanity[_chainId] as Address;
+ this.publicClient = createPublicClient({
+ chain: supportedChains[_chainId],
+ transport: http(getChainRpc(_chainId)),
+ });
+ }
+ private static getApiReader(_chainId: SupportedChainId) {
+ if (!APIPoH.apiReader || APIPoH.apiReader.chainId !== _chainId)
+ APIPoH.apiReader = new APIPoH(_chainId);
+ return APIPoH.apiReader;
+ }
+
+ private async get(func: string, args: Array = []) {
+ return await this.publicClient.readContract({
+ address: this.address,
+ abi: abis.ProofOfHumanity as any,
+ functionName: func,
+ args: args
+ })
+ .catch(() => {
+ throw new Error({statusCode: 520, title: "Error while reading ProofOfHumanity"});
+ });
+ }
+
+ public static async getArbitratorFromRequest(_chainId: SupportedChainId, pohId: Address, requestIndex: number): Promise {
+ const apiReader = APIPoH.getApiReader(_chainId);
+ const out: ArbitratorFromRequest = {
+ arbitrator: undefined,
+ extraData: undefined
+ };
+ try {
+ const data = await apiReader.get('getRequestInfo', [pohId, requestIndex]);
+ const arbitratorDataHistory = await apiReader.get('arbitratorDataHistory', [data[2]]);
+ out.arbitrator = arbitratorDataHistory[1];
+ out.extraData = arbitratorDataHistory[2];
+ return out;
+ } catch (error) {
+ throw new Error({statusCode: 520, title: "Error while reading ProofOfHumanity"});
+ }
+ }
+
+ public static async getCurrentRoundSideFunds(_chainId: SupportedChainId, pohId: Address, requestIndex: number, arbitrator: Address, disputeId: bigint): Promise {
+ const apiReader = APIPoH.getApiReader(_chainId);
+ const out: CurrentRoundSideFunds = {
+ claimerFunds: undefined,
+ challengerFunds: undefined
+ };
+ try {
+ const data = await apiReader.get('disputeIdToData', [arbitrator, disputeId]);
+ const challengeId = data[1];
+ const challengeInfo = await apiReader.get('getChallengeInfo', [pohId, requestIndex, challengeId]);
+ const lastRoundId = challengeInfo[0];
+ const funds = await apiReader.get('getRoundInfo', [pohId, requestIndex, challengeId, lastRoundId]);
+ out.claimerFunds = funds[1];
+ out.challengerFunds = funds[2];
+ return out;
+ } catch (error) {
+ throw new Error({statusCode: 520, title: "Error while reading ProofOfHumanity"});
+ }
+ }
+
+ public static async getStakeMultipliers(_chainId: SupportedChainId) : Promise {
+ const apiReader = APIPoH.getApiReader(_chainId);
+ const out: StakeMultipliers = {
+ winnerStakeMultiplier: undefined,
+ looserStakeMultiplier: undefined,
+ sharedStakeMultiplier: undefined
+ };
+ try {
+ out.winnerStakeMultiplier = await apiReader.get('winnerStakeMultiplier');
+ out.looserStakeMultiplier = await apiReader.get('loserStakeMultiplier');
+ out.sharedStakeMultiplier = await apiReader.get('sharedStakeMultiplier');
+ return out;
+ } catch (error) {
+ throw new Error({statusCode: 520, title: "Error while reading ProofOfHumanity"});
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/contracts/index.ts b/src/contracts/index.ts
index 854973a..50da60b 100644
--- a/src/contracts/index.ts
+++ b/src/contracts/index.ts
@@ -31,12 +31,18 @@ export const Contract = {
} : (configSetSelection.id === configSets.main.id)? {
[gnosis.id]: "0xa4AC94C4fa65Bb352eFa30e3408e64F72aC857bc",
[mainnet.id]: "0xbE9834097A4E97689d9B667441acafb456D0480A",
+ [sepolia.id]: "0x",
+ [gnosisChiado.id]: "0x",
} : (configSetSelection.id === configSets.mainPreAudit.id)? {
[gnosis.id]: "0xECd1823b3087acEE3C77928b1959c08d31A8F20e",
[mainnet.id]: "0x87c5c294C9d0ACa6b9b2835A99FE0c9A444Aacc1",
+ [sepolia.id]: "0x",
+ [gnosisChiado.id]: "0x",
} : (configSetSelection.id === configSets.mainOld.id)? {
[gnosis.id]: "0xe6573F65efAbc351b69F9b73ed8e95772698938b",
[mainnet.id]: "0x6cbEdC1920090EA4F28A38C1CD61c8D37b2cc323",
+ [sepolia.id]: "0x",
+ [gnosisChiado.id]: "0x",
} : {
[mainnet.id]: "0x",
[gnosis.id]: "0x",
diff --git a/src/generated/graphql.ts b/src/generated/graphql.ts
index edda89c..3f2ae41 100644
--- a/src/generated/graphql.ts
+++ b/src/generated/graphql.ts
@@ -3397,7 +3397,7 @@ export type RequestQueryVariables = Exact<{
}>;
-export type RequestQuery = { __typename?: 'Query', request?: { __typename?: 'Request', index: any, revocation: boolean, registrationEvidenceRevokedReq: string, requester: any, creationTime: any, lastStatusChange: any, status: { __typename?: 'Status', id: string }, vouches: Array<{ __typename?: 'VouchInProcess', voucher: { __typename?: 'Humanity', id: any } }>, humanity: { __typename?: 'Humanity', id: any, nbRequests: any, nbLegacyRequests: any, registration?: { __typename?: 'Registration', expirationTime: any, claimer: { __typename?: 'Claimer', id: any } } | null, winnerClaim: Array<{ __typename?: 'Request', index: any, resolutionTime: any, evidenceGroup: { __typename?: 'EvidenceGroup', evidence: Array<{ __typename?: 'Evidence', uri: string }> } }> }, claimer: { __typename?: 'Claimer', id: any, name?: string | null, vouchesReceived: Array<{ __typename?: 'Vouch', from: { __typename?: 'Claimer', id: any, registration?: { __typename?: 'Registration', expirationTime: any, humanity: { __typename?: 'Humanity', vouching: boolean } } | null }, humanity: { __typename?: 'Humanity', id: any } }>, vouches: Array<{ __typename?: 'Vouch', for: { __typename?: 'Claimer', id: any, name?: string | null } }> }, evidenceGroup: { __typename?: 'EvidenceGroup', evidence: Array<{ __typename?: 'Evidence', id: any, uri: string, creationTime: any, submitter: any }> }, challenges: Array<{ __typename?: 'Challenge', id: any, disputeId: any, nbRounds: any, reason: { __typename?: 'Reason', id: string }, challenger?: { __typename?: 'Challenger', id: any } | null, rounds: Array<{ __typename?: 'Round', requesterFund: { __typename?: 'RequesterFund', amount: any }, challengerFund?: { __typename?: 'ChallengerFund', amount: any } | null }> }>, arbitratorHistory: { __typename?: 'ArbitratorHistory', updateTime: any, registrationMeta: string } } | null };
+export type RequestQuery = { __typename?: 'Query', request?: { __typename?: 'Request', index: any, revocation: boolean, registrationEvidenceRevokedReq: string, requester: any, creationTime: any, lastStatusChange: any, status: { __typename?: 'Status', id: string }, vouches: Array<{ __typename?: 'VouchInProcess', voucher: { __typename?: 'Humanity', id: any } }>, humanity: { __typename?: 'Humanity', id: any, nbRequests: any, nbLegacyRequests: any, registration?: { __typename?: 'Registration', expirationTime: any, claimer: { __typename?: 'Claimer', id: any } } | null, winnerClaim: Array<{ __typename?: 'Request', index: any, resolutionTime: any, evidenceGroup: { __typename?: 'EvidenceGroup', evidence: Array<{ __typename?: 'Evidence', uri: string }> } }> }, claimer: { __typename?: 'Claimer', id: any, name?: string | null, vouchesReceived: Array<{ __typename?: 'Vouch', from: { __typename?: 'Claimer', id: any, registration?: { __typename?: 'Registration', expirationTime: any, humanity: { __typename?: 'Humanity', vouching: boolean } } | null }, humanity: { __typename?: 'Humanity', id: any } }>, vouches: Array<{ __typename?: 'Vouch', for: { __typename?: 'Claimer', id: any, name?: string | null } }> }, evidenceGroup: { __typename?: 'EvidenceGroup', evidence: Array<{ __typename?: 'Evidence', id: any, uri: string, creationTime: any, submitter: any }> }, challenges: Array<{ __typename?: 'Challenge', id: any, disputeId: any, nbRounds: any, reason: { __typename?: 'Reason', id: string }, challenger?: { __typename?: 'Challenger', id: any } | null, rounds: Array<{ __typename?: 'Round', creationTime: any, requesterFund: { __typename?: 'RequesterFund', amount: any }, challengerFund?: { __typename?: 'ChallengerFund', amount: any } | null }> }>, arbitratorHistory: { __typename?: 'ArbitratorHistory', updateTime: any, registrationMeta: string } } | null };
export type RequestsQueryVariables = Exact<{
skip?: InputMaybe;
@@ -3664,6 +3664,7 @@ export const RequestDocument = gql`
}
nbRounds
rounds(orderBy: creationTime) {
+ creationTime
requesterFund {
amount
}
diff --git a/src/utils/misc.ts b/src/utils/misc.ts
index 987e280..47aa9ed 100644
--- a/src/utils/misc.ts
+++ b/src/utils/misc.ts
@@ -41,6 +41,9 @@ export const randomString = (length: number) =>
export const formatEth = (wei: bigint, precision: number = 4) =>
+parseFloat(formatEther(wei)).toFixed(precision);
+export const eth2Wei = (ethAmount: number): bigint =>
+ BigInt(ethAmount * Math.pow(10, 18));
+
export function romanize(n: number): string {
if (n < 1) return "";
if (n >= 40) return `XL${romanize(n - 40)}`;