Skip to content

Commit

Permalink
- implement new test lords contract into UI
Browse files Browse the repository at this point in the history
- prefund arcade accounts on deployment with 250 Lords
- approve spending limit of 250 Lords
- implement a mint lords button on arcade intro
  • Loading branch information
starknetdev committed Oct 3, 2023
1 parent 3fba28f commit d5801b6
Show file tree
Hide file tree
Showing 10 changed files with 2,954 additions and 3,394 deletions.
1,025 changes: 0 additions & 1,025 deletions ui/src/app/abi/Adventurer.json

This file was deleted.

733 changes: 0 additions & 733 deletions ui/src/app/abi/Beast.json

This file was deleted.

2,404 changes: 2,404 additions & 0 deletions ui/src/app/abi/Game.json

Large diffs are not rendered by default.

1,157 changes: 0 additions & 1,157 deletions ui/src/app/abi/LootMarketArcade.json

This file was deleted.

415 changes: 415 additions & 0 deletions ui/src/app/abi/Lords.json

Large diffs are not rendered by default.

423 changes: 0 additions & 423 deletions ui/src/app/abi/Lords_ERC20_Mintable.json

This file was deleted.

83 changes: 74 additions & 9 deletions ui/src/app/components/intro/ArcadeIntro.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,68 @@
import { useState } from "react";
import { useAccount, useConnectors } from "@starknet-react/core";
import {
useAccount,
useConnectors,
useContractWrite,
useBalance,
} from "@starknet-react/core";
import { useBurner } from "@/app/lib/burner";
import { Button } from "../buttons/Button";
import useUIStore from "@/app/hooks/useUIStore";
import PixelatedImage from "../animations/PixelatedImage";
import { getWalletConnectors } from "@/app/lib/connectors";
import Lords from "../../../../public/icons/lords.svg";
import { useContracts } from "@/app/hooks/useContracts";
import useTransactionCartStore from "@/app/hooks/useTransactionCartStore";
import { Call } from "@/app/types";

export const ArcadeIntro = () => {
const { address } = useAccount();
const { account, address } = useAccount();
const { connect, available } = useConnectors();
const isWrongNetwork = useUIStore((state) => state.isWrongNetwork);
const { getMasterAccount, create, isDeploying, isSettingPermissions } =
useBurner();
const walletConnectors = getWalletConnectors(available);
const { lordsContract } = useContracts();
const calls = useTransactionCartStore((state) => state.calls);
const addToCalls = useTransactionCartStore((state) => state.addToCalls);
const handleSubmitCalls = useTransactionCartStore(
(state) => state.handleSubmitCalls
);
const { writeAsync } = useContractWrite({ calls });
const { data: lordsBalance, refetch: refetchLordsBalance } = useBalance({
token: lordsContract?.address,
address,
});
const lords = parseInt(lordsBalance?.formatted ?? "0");
const [isMintingLords, setIsMintingLords] = useState(false);

const mintLords = async () => {
try {
setIsMintingLords(true);
// Mint 250 LORDS
const mintLords: Call = {
contractAddress: lordsContract?.address ?? "",
entrypoint: "mint",
calldata: [address ?? "0x0", (250 * 10 ** 18).toString(), "0"],
};
addToCalls(mintLords);
const tx = await handleSubmitCalls(writeAsync);
const result = await account?.waitForTransaction(tx?.transaction_hash, {
retryInterval: 2000,
});

if (!result) {
throw new Error("Lords Mint did not complete successfully.");
}

setIsMintingLords(false);
refetchLordsBalance();
} catch (e) {
setIsMintingLords(false);
console.log(e);
}
};

return (
<>
<div className="fixed inset-0 opacity-80 bg-terminal-black z-40" />
Expand All @@ -25,13 +75,14 @@ export const ArcadeIntro = () => {
unleashing a 10x surge in your gameplay speed.
</p>
<p className="text-sm xl:text-xl 2xl:text-2xl">
Fear not, for they're guarded by a labyrinth of security features,
fit for even the wiliest of adventurers!
Stored in the browser but fear not, for they're guarded by a
labyrinth of security features, fit for even the wiliest of
adventurers!
</p>
<p className=" text-sm xl:text-xl 2xl:text-2xl">
<p className="text-sm xl:text-xl 2xl:text-2xl">
Connect using a wallet provider.
</p>
<div className="flex flex-col w-1/4">
<div className="flex flex-col gap-2 w-1/4">
{walletConnectors.map((connector, index) => (
<Button
disabled={address !== undefined}
Expand All @@ -44,12 +95,26 @@ export const ArcadeIntro = () => {
</Button>
))}
</div>
<p className=" text-sm xl:text-xl 2xl:text-2xl">
Create Arcade Account (Fund, deploy & initiate security permissions)
<p className="text-sm xl:text-xl 2xl:text-2xl">Mint Some Lords</p>
<Button
onClick={() => mintLords()}
disabled={isWrongNetwork || isMintingLords || lords !== 0}
className="flex flex-row w-1/4"
>
<Lords className="sm:w-5 sm:h-5 h-3 w-3 fill-current mr-1" />{" "}
{isMintingLords ? (
<p className="loading-ellipsis">Minting Lords</p>
) : (
"Mint"
)}
</Button>
<p className="text-sm xl:text-xl 2xl:text-2xl">
Create Arcade Account (Fund ETH + LORDS, deploy, set permissions and
approvals)
</p>
<Button
onClick={() => create()}
disabled={isWrongNetwork}
disabled={isWrongNetwork || lords === 0}
className="w-1/4"
>
CREATE
Expand Down
12 changes: 6 additions & 6 deletions ui/src/app/hooks/useContracts.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useContract, useAccount } from "@starknet-react/core";
import Adventurer from "../abi/Adventurer.json";
import Lords_ERC20_Mintable from "../abi/Lords_ERC20_Mintable.json";
import Game from "../abi/Game.json";
import Lords from "../abi/Lords.json";
import { contracts, mainnet_addr } from "../lib/constants";

const ethBalanceABIFragment = [
Expand Down Expand Up @@ -73,15 +73,15 @@ export const useContracts = () => {
(account as any)?.baseUrl == mainnet_addr
? contracts.mainnet.game
: contracts.goerli.game,
abi: Adventurer,
abi: Game,
});
const { contract: lordsContract } = useContract({
address:
(account as any)?.provider?.baseUrl == mainnet_addr ||
(account as any)?.baseUrl == mainnet_addr
? contracts.mainnet.lords_erc20_mintable
: contracts.goerli.lords_erc20_mintable,
abi: Lords_ERC20_Mintable,
? contracts.mainnet.lords
: contracts.goerli.lords,
abi: Lords,
});

const { contract: ethContract } = useContract({
Expand Down
90 changes: 53 additions & 37 deletions ui/src/app/lib/burner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { ArcadeConnector } from "./arcade";
import { useContracts } from "../hooks/useContracts";
import { BurnerStorage } from "../types";

export const PREFUND_AMOUNT = "0x38D7EA4C68000"; // 0.001ETH
export const ETH_PREFUND_AMOUNT = "0x38D7EA4C68000"; // 0.001ETH
export const LORDS_PREFUND_AMOUNT = "0x0d8d726b7177a80000"; // 250LORDS

const provider = new Provider({
sequencer: {
Expand Down Expand Up @@ -124,6 +125,40 @@ export const useBurner = () => {
[walletAccount]
);

const prefundAccount = async (address: string, account: AccountInterface) => {
try {
const transferEthTx = {
contractAddress: process.env.NEXT_PUBLIC_ETH_CONTRACT_ADDRESS!,
entrypoint: "transfer",
calldata: CallData.compile([address, ETH_PREFUND_AMOUNT, "0x0"]),
};

const transferLordsTx = {
contractAddress: lordsContract?.address ?? "0x0",
entrypoint: "transfer",
calldata: CallData.compile([address, LORDS_PREFUND_AMOUNT, "0x0"]),
};

const { transaction_hash } = await account.execute([
transferEthTx,
transferLordsTx,
]);

const result = await account.waitForTransaction(transaction_hash, {
retryInterval: 2000,
});

if (!result) {
throw new Error("Transaction did not complete successfully.");
}

return result;
} catch (error) {
console.error(error);
throw error;
}
};

const create = useCallback(async () => {
setIsDeploying(true);
const privateKey = stark.randomAddress();
Expand Down Expand Up @@ -168,12 +203,12 @@ export const useBurner = () => {

setIsSettingPermissions(true);

const setPermissionsTx = await setPermissions(
const setPermissionsAndApprovalTx = await setPermissionsAndApproval(
accountAAFinalAdress,
walletAccount
);

await provider.waitForTransaction(setPermissionsTx);
await provider.waitForTransaction(setPermissionsAndApprovalTx);

// save burner
let storage = Storage.get("burners") || {};
Expand All @@ -185,7 +220,7 @@ export const useBurner = () => {
privateKey,
publicKey,
deployTx,
setPermissionsTx,
setPermissionsAndApprovalTx,
masterAccount: walletAccount.address,
gameContract: gameContract?.address,
active: true,
Expand All @@ -200,7 +235,7 @@ export const useBurner = () => {
return burner;
}, [walletAccount]);

const setPermissions = useCallback(
const setPermissionsAndApproval = useCallback(
async (accountAAFinalAdress: any, walletAccount: any) => {
const permissions: Call[] = [
{
Expand All @@ -226,9 +261,16 @@ export const useBurner = () => {
},
];

const { transaction_hash: permissionsTx } = await walletAccount.execute(
permissions
);
// Approve 250 LORDS
const approveLordsSpendingTx = {
contractAddress: lordsContract?.address ?? "",
entrypoint: "approve",
calldata: [gameContract?.address ?? "", LORDS_PREFUND_AMOUNT, "0"],
};
const { transaction_hash: permissionsTx } = await walletAccount.execute([
...permissions,
approveLordsSpendingTx,
]);

return permissionsTx;
},
Expand All @@ -241,12 +283,11 @@ export const useBurner = () => {
const { transaction_hash } = await account.execute({
contractAddress: process.env.NEXT_PUBLIC_ETH_CONTRACT_ADDRESS!,
entrypoint: "transfer",
calldata: CallData.compile([address, PREFUND_AMOUNT, "0x0"]),
calldata: CallData.compile([address, ETH_PREFUND_AMOUNT, "0x0"]),
});

const result = await account.waitForTransaction(transaction_hash, {
retryInterval: 1000,
successStates: [TransactionFinalityStatus.ACCEPTED_ON_L2],
retryInterval: 2000,
});

if (!result) {
Expand Down Expand Up @@ -308,8 +349,7 @@ export const useBurner = () => {
});

const result = await account.waitForTransaction(transaction_hash, {
retryInterval: 1000,
successStates: [TransactionFinalityStatus.ACCEPTED_ON_L2],
retryInterval: 2000,
});

if (!result) {
Expand Down Expand Up @@ -409,27 +449,3 @@ export const useBurner = () => {
listConnectors,
};
};

const prefundAccount = async (address: string, account: AccountInterface) => {
try {
const { transaction_hash } = await account.execute({
contractAddress: process.env.NEXT_PUBLIC_ETH_CONTRACT_ADDRESS!,
entrypoint: "transfer",
calldata: CallData.compile([address, PREFUND_AMOUNT, "0x0"]),
});

const result = await account.waitForTransaction(transaction_hash, {
retryInterval: 1000,
successStates: [TransactionFinalityStatus.ACCEPTED_ON_L2],
});

if (!result) {
throw new Error("Transaction did not complete successfully.");
}

return result;
} catch (error) {
console.error(error);
throw error;
}
};
6 changes: 2 additions & 4 deletions ui/src/app/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,11 @@ export function getGraphQLUrl() {
export const contracts = {
mainnet: {
game: "0x0",
lords_erc20_mintable:
"0x067e87cea28bfd9314a1d3c41fb26a58ca1346ff0ea2452e59b9eeb2828692dc",
lords: "0x067e87cea28bfd9314a1d3c41fb26a58ca1346ff0ea2452e59b9eeb2828692dc",
},
goerli: {
game: "0x01263ecbc05e28d1e99f531894838db10b90cfcdd39d020642da1747a733a37a",
lords_erc20_mintable:
"0x059dac5df32cbce17b081399e97d90be5fba726f97f00638f838613d088e5a47",
lords: "0x02a4174abc7c953030401679bde67e560b9e2724d5d71ffbaa488965dd36137a",
},
};

Expand Down

0 comments on commit d5801b6

Please sign in to comment.