Skip to content

Commit

Permalink
chore: refactor paymaster to hook
Browse files Browse the repository at this point in the history
  • Loading branch information
petertonysmith94 committed Dec 16, 2024
1 parent 1803a9a commit 815214c
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 81 deletions.
95 changes: 14 additions & 81 deletions frontend/src/components/NewPlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import type { FarmContract } from "../sway-api";

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 Down Expand Up @@ -55,43 +55,6 @@ export default function NewPlayer({
}
try {
setStatus("loading");
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 addressIdentityInput = {
Address: { bits: Address.fromAddressOrString(wallet.address.toString()).toB256() },
Expand All @@ -102,9 +65,13 @@ export default function NewPlayer({
.txParams({
variableOutputs: 1,
});

const request = await scope.getTransactionRequest();
// const txCost = await wallet.getTransactionCost(request);
// console.log("txCost", txCost);

const paymaster = usePaymaster();

Check failure on line 71 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();

request.addCoinInput(gasCoin);
request.addCoinOutput(
gasCoin.owner,
Expand All @@ -113,48 +80,14 @@ export default function NewPlayer({
);

request.addChangeOutput(gasCoin.owner, provider.getBaseAssetId());
const { gasLimit, maxFee } = await provider.estimateTxGasAndFee({
transactionRequest: request,
});
console.log(`New Player Cost gasLimit: ${gasLimit}, Maxfee: ${maxFee}`);
request.gasLimit = gasLimit;
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;

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

const txCost = await wallet.getTransactionCost(request);
request.gasLimit = txCost.gasUsed;
request.maxFee = txCost.maxFee;

const tx = await (await wallet.sendTransaction(request)).wait();
console.log("tx", tx);
// const tx = await scope.call();
// .txParams({
// variableOutputs: 1,
// })
// .call();
await paymaster.sign(request, gasCoin, jobId);
const tx = await (await provider.sendTransaction(request)).wait();

// setStatus('none');
if (tx) {
// Immediately update player state with initial values
setPlayer({
Expand Down
97 changes: 97 additions & 0 deletions frontend/src/hooks/usePaymaster.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import axios from "axios";
import { Address, BN, type Coin, Provider, TransactionRequest, bn } from "fuels";

type PaymasterMetadata = {
maxValuePerCoin: string;
}

type PaymasterAllocateResponse = {
coin: {
id: string;
amount: string;
assetId: string;
owner: string;
blockCreated: string;
txCreatedIdx: string;
};
jobId: string;
utxoId: string;
}

type PaymasterAllocate = {
coin: Coin;
jobId: string;
utxoId: string;
}

export const usePaymaster = () => {
const baseUrl = 'http://167.71.42.88:3000';
const metadataUrl = `${baseUrl}/metadata`;
const allocateUrl = `${baseUrl}/allocate-coin`;
const signUrl = `${baseUrl}/sign`;


const metadata = async (): Promise<PaymasterMetadata> => {
const { data: MetaDataResponse } = await axios.get<PaymasterMetadata>(metadataUrl);
const { maxValuePerCoin } = MetaDataResponse;
if (!maxValuePerCoin) {
throw new Error("No maxValuePerCoin found");
}
return { maxValuePerCoin};
}


const allocate = async (): Promise<PaymasterAllocate> => {
const { data } = await axios.post<PaymasterAllocateResponse>(allocateUrl);
const { jobId, utxoId, coin } = data;

if (!coin) {
throw new Error("No coin found");
}
if (!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),
};

return { coin: gasCoin, jobId, utxoId }
}

const sign = async (request: TransactionRequest, gasCoin: Coin, jobId: string) => {
// return;
const response = await axios.post(signUrl, {
request: request.toJSON(),
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");
}

request.updateWitnessByOwner(gasCoin.owner, response.data.signature);

return { signature: response.data.signature, gasInput, request }
}

return {
allocate,
metadata,
sign,
}
}

0 comments on commit 815214c

Please sign in to comment.