import { Code } from "@phosphor-icons/react/dist/ssr/Code";
import { Question } from "@phosphor-icons/react/dist/ssr/Question";
import { Warning } from "@phosphor-icons/react/dist/ssr/Warning";
import { Button } from "@pythnetwork/component-library/Button";
import { CopyButton } from "@pythnetwork/component-library/CopyButton";
import { InfoBox } from "@pythnetwork/component-library/InfoBox";
import { Meter } from "@pythnetwork/component-library/Meter";
import { StatCard } from "@pythnetwork/component-library/StatCard";
import { Table } from "@pythnetwork/component-library/Table";
import { Term } from "@pythnetwork/component-library/Term";
import type { OpenDrawerArgs } from "@pythnetwork/component-library/useDrawer";
import type { ComponentProps } from "react";
import { useNumberFormatter } from "react-aria";
import TimeAgo from "react-timeago";
import styles from "./request-drawer.module.scss";
import { getErrorDetails } from "../../errors";
import type {
Request,
CallbackErrorRequest,
FailedRequest,
} from "../../requests";
import { Status } from "../../requests";
import { truncate } from "../../truncate";
import { Account, Transaction } from "../Address";
import { Status as StatusComponent } from "../Status";
import { Timestamp } from "../Timestamp";
import { ChainTag } from "./chain-tag";
export const mkRequestDrawer = (
request: Request,
now: Date,
): OpenDrawerArgs => ({
title: `Request ${truncate(request.requestTxHash)}`,
headingExtra: ,
bodyClassName: styles.requestDrawer ?? "",
fill: true,
contents: ,
});
const RequestDrawerBody = ({
request,
now,
}: {
request: Request;
now: Date;
}) => {
const gasFormatter = useNumberFormatter({ maximumFractionDigits: 3 });
return (
<>
{truncate(request.randomNumber)}
) : (
)
}
/>
{request.status === Status.CallbackError && (
)}
{request.status === Status.Failed && (
)}
,
},
{
id: "requestTimestamp",
field: "Request Timestamp",
value: ,
},
...("callbackTimestamp" in request
? [
{
id: "callbackTimestamp",
field: "Callback Timestamp",
value: (
),
},
{
id: "duration",
field: (
The amount of time between the request transaction and the
callback transaction.
),
value: (
request.callbackTimestamp.getTime()}
date={request.requestTimestamp}
live={false}
formatter={(value, unit) =>
`${value.toString()} ${unit}${value === 1 ? "" : "s"}`
}
/>
),
},
]
: []),
{
id: "requestTx",
field: (
The transaction that requests a new random number from the
Entropy protocol.
),
value: (
),
},
{
id: "sender",
field: "Sender",
value: ,
},
...(request.status === Status.Complete
? [
{
id: "callbackTx",
field: (
Entropy’s response transaction that returns the random
number to the requester.
),
value: (
),
},
]
: []),
{
id: "provider",
field: "Provider",
value: ,
},
{
id: "userContribution",
field: (
User-submitted randomness included in the request.
),
value: (
{truncate(request.userContribution)}
),
},
...("providerContribution" in request
? [
{
id: "providerContribution",
field: (
Provider-submitted randomness used to calculate the random
number.
),
value: (
{truncate(request.providerContribution)}
),
},
]
: []),
{
id: "gas",
field: "Gas",
value:
"gasUsed" in request ? (
request.gasLimit ? "error" : "default"
}
/>
) : (
`${gasFormatter.format(request.gasLimit)} max`
),
},
].map((data) => ({
id: data.id,
data: {
field: {data.field},
value: data.value,
},
}))}
/>
>
);
};
const CallbackErrorInfo = ({ request }: { request: CallbackErrorRequest }) => {
const retryCommand = `cast send ${request.chain.address} 'revealWithCallback(address, uint64, bytes32, bytes32)' ${request.provider} ${request.sequenceNumber.toString()} ${request.userContribution} ${request.providerContribution} -r ${request.chain.rpc} --private-key `;
return (
<>
}
className={styles.message}
variant="info"
>
{`If you'd like to execute your callback, you can run the command in your
terminal or connect your wallet to run it here.`}
Copy Cast Command
}
rounded
hideText
href="https://docs.pyth.network/entropy/debug-callback-failures"
target="_blank"
className={styles.helpButton ?? ""}
>
Help
>
);
};
const FailureInfo = ({
request,
...props
}: ComponentProps & {
request: CallbackErrorRequest | FailedRequest;
}) => (
}
className={styles.message}
variant="warning"
{...props}
>
}
rounded
size="sm"
variant="ghost"
className={styles.helpButton ?? ""}
href={getHelpLink(request)}
target="_blank"
>
Help
);
const getHelpLink = (request: CallbackErrorRequest | FailedRequest) => {
const details = getErrorDetails(request.reason);
if (details === undefined) {
return isGasLimitExceeded(request)
? "https://docs.pyth.network/entropy/best-practices#limit-gas-usage-on-the-callback"
: "https://docs.pyth.network/entropy/best-practices#handling-callback-failures";
} else {
return details[2];
}
};
const FailureMessage = ({
request,
}: {
request: CallbackErrorRequest | FailedRequest;
}) => {
const details = getErrorDetails(request.reason);
if (details) {
return (
<>
The callback encountered the following error:
{details[0]} ({request.reason}): {details[1]}
>
);
} else if (isGasLimitExceeded(request)) {
return "The callback used more gas than the set gas limit";
} else {
return (
<>
Error response: {request.reason}
>
);
}
};
const isGasLimitExceeded = (request: CallbackErrorRequest | FailedRequest) =>
request.status === Status.CallbackError &&
request.reason === "0x" &&
request.gasUsed > request.gasLimit;