Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: refactored paymaster #88

Merged
merged 2 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 8 additions & 62 deletions frontend/src/components/NewPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@

import Loading from "./Loading";
import { PlayerOutput } from "../sway-api/contracts/FarmContract";
import { Address, BN, type Coin, Provider, bn } from "fuels";
import axios from "axios";
import { Address, BN, Provider } from "fuels";
import { usePaymaster } from "../hooks/usePaymaster";

interface NewPlayerProps {
contract: FarmContract | null;
Expand All @@ -27,13 +27,13 @@
setModal,
}: NewPlayerProps) {
const [status, setStatus] = useState<"error" | "loading" | "retrying" | "none">("none");
const [hasFunds, setHasFunds] = useState<boolean>(false);

Check failure on line 30 in frontend/src/components/NewPlayer.tsx

View workflow job for this annotation

GitHub Actions / Lint

'hasFunds' is assigned a value but never used
const { wallet } = useWallet();

useEffect(() => {
getBalance();
// setStatus("error");
}, [wallet]);

Check warning on line 36 in frontend/src/components/NewPlayer.tsx

View workflow job for this annotation

GitHub Actions / Lint

React Hook useEffect has a missing dependency: 'getBalance'. Either include it or remove the dependency array

async function getBalance() {
const thisWallet = wallet ?? contract?.account;
Expand Down Expand Up @@ -83,43 +83,10 @@
try {
// Try with gas station first
const provider = await Provider.create(FUEL_PROVIDER_URL);
const { data: MetaDataResponse } = await axios.get<{
maxValuePerCoin: string;
}>(`http://167.71.42.88:3000/metadata`);
const { maxValuePerCoin } = MetaDataResponse;
console.log("maxValuePerCoin", maxValuePerCoin);
if (!maxValuePerCoin) {
throw new Error("No maxValuePerCoin found");
}
const { data } = await axios.post<{
coin: {
id: string;
amount: string;
assetId: string;
owner: string;
blockCreated: string;
txCreatedIdx: string;
};
jobId: string;
utxoId: string;
}>(`http://167.71.42.88:3000/allocate-coin`);
if (!data?.coin) {
throw new Error("No coin found");
}

if (!data.jobId) {
throw new Error("No jobId found");
}
const gasCoin: Coin = {
id: data.coin.id,
amount: bn(data.coin.amount),
assetId: data.coin.assetId,
owner: Address.fromAddressOrString(data.coin.owner),
blockCreated: bn(data.coin.blockCreated),
txCreatedIdx: bn(data.coin.txCreatedIdx),
};
console.log("gasCoin", gasCoin);
// const address = Address.fromRandom();

const paymaster = usePaymaster();

Check failure on line 87 in frontend/src/components/NewPlayer.tsx

View workflow job for this annotation

GitHub Actions / Lint

React Hook "usePaymaster" is called in function "handleNewPlayer" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use"
const { maxValuePerCoin } = await paymaster.metadata();
const { coin: gasCoin, jobId } = await paymaster.allocate();

const addressIdentityInput = {
Address: { bits: Address.fromAddressOrString(wallet.address.toString()).toB256() },
Expand All @@ -146,29 +113,8 @@
request.gasLimit = gasUsed;
request.maxFee = maxFee;

// return;
const response = await axios.post(`http://167.71.42.88:3000/sign`, {
request: request.toJSON(),
jobId: data.jobId,
});
if (response.status !== 200) {
throw new Error("Failed to sign transaction");
}

if (!response.data.signature) {
throw new Error("No signature found");
}
console.log("response.data", response.data);
const gasInput = request.inputs.find((coin) => {
return coin.type === 0;
});
if (!gasInput) {
throw new Error("Gas coin not found");
}

const wi = request.getCoinInputWitnessIndexByOwner(gasCoin.owner);
console.log("wi", wi);
request.witnesses[wi as number] = response.data.signature;
const { signature } = await paymaster.fetchSignature(request, jobId);
request.updateWitnessByOwner(gasCoin.owner, signature);

// await wallet.fund(request, txCost);

Expand Down Expand Up @@ -246,7 +192,7 @@
);
}

const styles = {

Check failure on line 195 in frontend/src/components/NewPlayer.tsx

View workflow job for this annotation

GitHub Actions / Lint

'styles' is assigned a value but never used
container: cssObj({
flexDirection: "column",
fontFamily: "pressStart2P",
Expand Down
62 changes: 7 additions & 55 deletions frontend/src/components/modals/BuySeeds.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,22 @@
Address,
bn,
Provider,
type Coin,

Check failure on line 7 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'Coin' is defined but never used
InputType,

Check failure on line 8 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'InputType' is defined but never used
} from "fuels";
import type { Dispatch, SetStateAction } from "react";
import { useState } from "react";
import axios from "axios";

Check failure on line 12 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'axios' is defined but never used
import { FUEL_PROVIDER_URL } from "../../constants";
import { buttonStyle, FoodTypeInput } from "../../constants";
import type { FarmContract } from "../../sway-api/contracts/FarmContract";
import {
useWallet,
useIsConnected,

Check failure on line 18 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'useIsConnected' is defined but never used
useNetwork,

Check failure on line 19 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'useNetwork' is defined but never used
useBalance,

Check failure on line 20 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'useBalance' is defined but never used
} from "@fuels/react";
import { usePaymaster } from "../../hooks/usePaymaster";

interface BuySeedsProps {
contract: FarmContract | null;
Expand All @@ -34,7 +35,7 @@
farmCoinAssetID,
}: BuySeedsProps) {
const [status, setStatus] = useState<"error" | "none" | "loading" | "retrying">("none");
const [retryCount, setRetryCount] = useState(0);

Check failure on line 38 in frontend/src/components/modals/BuySeeds.tsx

View workflow job for this annotation

GitHub Actions / Lint

'retryCount' is assigned a value but never used
const MAX_RETRIES = 3;
const { wallet } = useWallet();

Expand All @@ -43,42 +44,11 @@
throw new Error("No wallet found");
}
const provider = await Provider.create(FUEL_PROVIDER_URL);
const { data: MetaDataResponse } = await axios.get<{
maxValuePerCoin: string;
}>(`http://167.71.42.88:3000/metadata`);
const { maxValuePerCoin } = MetaDataResponse;
console.log("maxValuePerCoin", maxValuePerCoin);
if (!maxValuePerCoin) {
throw new Error("No maxValuePerCoin found");
}
const { data } = await axios.post<{
coin: {
id: string;
amount: string;
assetId: string;
owner: string;
blockCreated: string;
txCreatedIdx: string;
};
jobId: string;
utxoId: string;
}>(`http://167.71.42.88:3000/allocate-coin`);
if (!data?.coin) {
throw new Error("No coin found");
}

if (!data.jobId) {
throw new Error("No jobId found");
}
const gasCoin: Coin = {
id: data.coin.id,
amount: bn(data.coin.amount),
assetId: data.coin.assetId,
owner: Address.fromAddressOrString(data.coin.owner),
blockCreated: bn(data.coin.blockCreated),
txCreatedIdx: bn(data.coin.txCreatedIdx),
};
console.log("gasCoin", gasCoin);
const paymaster = usePaymaster();
const { maxValuePerCoin } = await paymaster.metadata();
const { coin: gasCoin, jobId } = await paymaster.allocate();

const amount = 10;
const realAmount = amount / 1_000_000_000;
const inputAmount = bn.parseUnits(realAmount.toFixed(9).toString());
Expand Down Expand Up @@ -148,26 +118,8 @@
);
request.addChangeOutput(gasCoin.owner, provider.getBaseAssetId());

const response = await axios.post(`http://167.71.42.88:3000/sign`, {
request: request.toJSON(),
jobId: data.jobId,
});
if (response.status !== 200) {
throw new Error("Failed to sign transaction");
}
if (!response.data.signature) {
throw new Error("No signature found");
}
const gasInput = request.inputs.find((coin) => {
return coin.type === 0;
});
if (!gasInput) {
throw new Error("Gas coin not found");
}
console.log("gasInput", gasInput);
const wi = request.getCoinInputWitnessIndexByOwner(gasCoin.owner);
request.witnesses[wi as number] = response.data.signature;
console.log("request manually after coin", request.toJSON());
const {signature} = await paymaster.fetchSignature(request, jobId);
request.updateWitnessByOwner(gasCoin.owner, signature);

const tx = await wallet.sendTransaction(request, {
estimateTxDependencies: false,
Expand Down
64 changes: 10 additions & 54 deletions frontend/src/components/modals/HarvestModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { buttonStyle, FUEL_PROVIDER_URL } from "../../constants";
import type { FarmContract } from "../../sway-api";
import type { Modals } from "../../constants";
import { useWallet } from "@fuels/react";
import { Address, type Coin, Provider, bn } from "fuels";
import axios from "axios";
import { Address, Provider } from "fuels";
import { usePaymaster } from "../../hooks/usePaymaster";
interface HarvestProps {
contract: FarmContract | null;
tileArray: number[];
Expand Down Expand Up @@ -59,42 +59,11 @@ export default function HarvestModal({
try {
// Try with gas station first
const provider = await Provider.create(FUEL_PROVIDER_URL);
const { data: MetaDataResponse } = await axios.get<{
maxValuePerCoin: string;
}>(`http://167.71.42.88:3000/metadata`);
const { maxValuePerCoin } = MetaDataResponse;
console.log("maxValuePerCoin", maxValuePerCoin);
if (!maxValuePerCoin) {
throw new Error("No maxValuePerCoin found");
}
const { data } = await axios.post<{
coin: {
id: string;
amount: string;
assetId: string;
owner: string;
blockCreated: string;
txCreatedIdx: string;
};
jobId: string;
utxoId: string;
}>(`http://167.71.42.88:3000/allocate-coin`);
if (!data?.coin) {
throw new Error("No coin found");
}

if (!data.jobId) {
throw new Error("No jobId found");
}
const gasCoin: Coin = {
id: data.coin.id,
amount: bn(data.coin.amount),
assetId: data.coin.assetId,
owner: Address.fromAddressOrString(data.coin.owner),
blockCreated: bn(data.coin.blockCreated),
txCreatedIdx: bn(data.coin.txCreatedIdx),
};
console.log("gasCoin", gasCoin);
const paymaster = usePaymaster();
const { maxValuePerCoin } = await paymaster.metadata();
const { coin: gasCoin, jobId } = await paymaster.allocate();

const addressIdentityInput = {
Address: {
bits: Address.fromAddressOrString(
Expand Down Expand Up @@ -122,23 +91,10 @@ export default function HarvestModal({
request.gasLimit = gasUsed;
request.maxFee = maxFee;
console.log(`Harvest Cost gasLimit: ${gasUsed}, Maxfee: ${maxFee}`);
const response = await axios.post(`http://167.71.42.88:3000/sign`, {
request: request.toJSON(),
jobId: data.jobId,
});
if (response.status !== 200) {
throw new Error("Failed to sign transaction");
}
if (!response.data.signature) {
throw new Error("No signature found");
}
const gasInput = request.inputs.find((coin) => {
return coin.type === 0;
});
if (!gasInput) {
throw new Error("Gas coin not found");
}
request.witnesses[gasInput.witnessIndex] = response.data.signature;

const { signature } = await paymaster.fetchSignature(request, jobId);
request.updateWitnessByOwner(gasCoin.owner, signature);

console.log("harvest request manually", request.toJSON());
const tx = await wallet.sendTransaction(request);
if (tx) {
Expand Down
60 changes: 7 additions & 53 deletions frontend/src/components/modals/PlantModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import Loading from "../Loading";
import { Address, type Coin, Provider, bn } from "fuels";
import { useWallet } from "@fuels/react";
import axios from "axios";
import { usePaymaster } from "../../hooks/usePaymaster";

interface PlantModalProps {
contract: FarmContract | null;
Expand Down Expand Up @@ -65,42 +66,11 @@ export default function PlantModal({
try {
// Try with gas station first
const provider = await Provider.create(FUEL_PROVIDER_URL);
const { data: MetaDataResponse } = await axios.get<{
maxValuePerCoin: string;
}>(`http://167.71.42.88:3000/metadata`);
const { maxValuePerCoin } = MetaDataResponse;
console.log("maxValuePerCoin", maxValuePerCoin);
if (!maxValuePerCoin) {
throw new Error("No maxValuePerCoin found");
}
const { data } = await axios.post<{
coin: {
id: string;
amount: string;
assetId: string;
owner: string;
blockCreated: string;
txCreatedIdx: string;
};
jobId: string;
utxoId: string;
}>(`http://167.71.42.88:3000/allocate-coin`);
if (!data?.coin) {
throw new Error("No coin found");
}

if (!data.jobId) {
throw new Error("No jobId found");
}
const gasCoin: Coin = {
id: data.coin.id,
amount: bn(data.coin.amount),
assetId: data.coin.assetId,
owner: Address.fromAddressOrString(data.coin.owner),
blockCreated: bn(data.coin.blockCreated),
txCreatedIdx: bn(data.coin.txCreatedIdx),
};
console.log("gasCoin", gasCoin);
const paymaster = usePaymaster();
const { maxValuePerCoin } = await paymaster.metadata();
const { coin: gasCoin, jobId } = await paymaster.allocate();

const addressIdentityInput = {
Address: {
bits: Address.fromAddressOrString(
Expand Down Expand Up @@ -129,26 +99,10 @@ export default function PlantModal({
request.gasLimit = gasUsed;
request.maxFee = maxFee;
console.log(`Plant Cost gasLimit: ${gasUsed}, Maxfee: ${maxFee}`);
const response = await axios.post(`http://167.71.42.88:3000/sign`, {
request: request.toJSON(),
jobId: data.jobId,
});
if (response.status !== 200) {
throw new Error("Failed to sign transaction");
}

if (!response.data.signature) {
throw new Error("No signature found");
}
console.log("response.data", response.data);
const gasInput = request.inputs.find((coin) => {
return coin.type === 0;
});
if (!gasInput) {
throw new Error("Gas coin not found");
}
const { signature } = await paymaster.fetchSignature(request, jobId);
request.updateWitnessByOwner(gasCoin.owner, signature);

request.witnesses[gasInput.witnessIndex] = response.data.signature;
const tx = await wallet.sendTransaction(request);
if (tx) {
console.log("tx", tx);
Expand Down
Loading
Loading