Skip to content

Commit

Permalink
docs: add more comments around the create-fuels template app
Browse files Browse the repository at this point in the history
  • Loading branch information
Dhaiwat10 committed Jul 15, 2024
1 parent 2ded63e commit e5d8029
Show file tree
Hide file tree
Showing 15 changed files with 47 additions and 4 deletions.
5 changes: 3 additions & 2 deletions templates/nextjs/fuels.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@ dotenv.config({
path: ['.env.local', '.env'],
});

// If your node is running on a port other than 4000, you can set it here
const fuelCorePort = +(process.env.NEXT_PUBLIC_FUEL_NODE_PORT as string) || 4000;

export default createConfig({
workspace: './sway-programs',
output: './src/sway-api',
workspace: './sway-programs', // Path to your Sway workspace
output: './src/sway-api', // Where your generated types will be saved
fuelCorePort,
providerUrl: NODE_URL,
forcPath: 'fuels-forc',
Expand Down
3 changes: 2 additions & 1 deletion templates/nextjs/src/app/faucet/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { useEffect, useState } from "react";
import toast from "react-hot-toast";

export default function Faucet() {
const { faucetWallet } = useFaucet();
const { faucetWallet } = useFaucet(); // Get the faucet wallet instance from the useFaucet hook
const { wallet, refreshWalletBalance } = useActiveWallet();

const [receiverAddress, setReceiverAddress] = useState<string>("");
Expand All @@ -34,6 +34,7 @@ export default function Faucet() {
return toast.error("Amount cannot be empty");
}

// Transfer the specified amount of ETH to the receiver address
const tx = await faucetWallet.transfer(
receiverAddress,
bn.parseUnits(amountToSend.toString()),
Expand Down
5 changes: 4 additions & 1 deletion templates/nextjs/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
import { NODE_URL } from "@/lib";
import { ActiveWalletProvider } from "@/hooks/useActiveWallet";

// react-query is a peer dependency of @fuels/react, so we set it up here. See https://docs.fuel.network/docs/wallet/dev/getting-started/#installation-1
const queryClient = new QueryClient();

interface RootLayoutProps {
Expand All @@ -25,12 +26,13 @@ interface RootLayoutProps {

export default function RootLayout({ children }: RootLayoutProps) {
const [isMounted, setIsMounted] = useState(false);
const providerToUse = useMemo(() => Provider.create(NODE_URL), [NODE_URL]);
const providerToUse = useMemo(() => Provider.create(NODE_URL), [NODE_URL]); // Create a Provider instance. We memoize it to avoid creating a new instance on every render.

useEffect(() => {
setIsMounted(true);
}, []);

// Only render the component if the page has been mounted, and `window` is defined.
if (!isMounted) return null;

return (
Expand All @@ -40,6 +42,7 @@ export default function RootLayout({ children }: RootLayoutProps) {
<QueryClientProvider client={queryClient}>
<FuelProvider
fuelConfig={{
// The list of wallet connectors. You can add or remove connectors from here based on your needs.
connectors: [
new FuelWalletConnector(),
new BurnerWalletConnector({
Expand Down
5 changes: 5 additions & 0 deletions templates/nextjs/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,11 @@ export default function Home() {
*/
useAsync(async () => {
if (wallet) {
// Create a new instance of the contract
const testContract = TestContractAbi__factory.connect(contractId, wallet);
setContract(testContract);

// Read the current value of the counter
const { value } = await testContract.functions.get_count().get();
setCounter(value.toNumber());
}
Expand All @@ -48,10 +51,12 @@ export default function Home() {
);
}

// Call the increment_counter function on the contract
const { waitForResult } = await contract.functions
.increment_counter(bn(1))
.call();

// Wait for the transaction to be mined, and then read the value returned by the contract call
const { value } = await waitForResult();

setCounter(value.toNumber());
Expand Down
7 changes: 7 additions & 0 deletions templates/nextjs/src/app/predicate/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default function PredicateExample() {
useAsync(async () => {
if (wallet) {
baseAssetId = wallet.provider.getBaseAssetId();
// Initialize a new predicate instance
const predicate = TestPredicateAbi__factory.createInstance(
wallet.provider,
);
Expand Down Expand Up @@ -63,6 +64,7 @@ export default function PredicateExample() {
return toast.error("Wallet not loaded");
}

// Initialize a new predicate instance with the entered pin
const reInitializePredicate = TestPredicateAbi__factory.createInstance(
wallet.provider,
[bn(pin)],
Expand All @@ -72,6 +74,11 @@ export default function PredicateExample() {
return toast.error("Failed to initialize predicate");
}

/*
Try to 'unlock' the predicate and transfer the funds back to the wallet.
If the pin is correct, this transfer transaction will succeed.
If the pin is incorrect, this transaction will fail.
*/
const tx = await reInitializePredicate.transfer(
wallet.address,
amount,
Expand Down
2 changes: 2 additions & 0 deletions templates/nextjs/src/app/script/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default function ScriptExample() {

useAsync(async () => {
if (wallet) {
// Initialize script instance
const script = TestScriptAbi__factory.createInstance(wallet);
setScript(script);
}
Expand All @@ -31,6 +32,7 @@ export default function ScriptExample() {
return toast.error("Script not loaded");
}

// Call the script with the input value
const { waitForResult } = await script.functions.main(bn(input)).call();
const { value } = await waitForResult();

Expand Down
2 changes: 2 additions & 0 deletions templates/nextjs/src/components/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const Layout = ({ children }: { children: React.ReactNode }) => {
return console.error("Unable to topup wallet because wallet is not set.");
}

// If the current environment is local, transfer 5 ETH to the wallet from the local faucet wallet
if (CURRENT_ENVIRONMENT === "local") {
if (!faucetWallet) {
return toast.error("Faucet wallet not found.");
Expand All @@ -45,6 +46,7 @@ export const Layout = ({ children }: { children: React.ReactNode }) => {
return await refreshWalletBalance?.();
}

// If the current environment is testnet, open the testnet faucet link in a new tab
if (CURRENT_ENVIRONMENT === "testnet") {
return window.open(
`${TESTNET_FAUCET_LINK}?address=${wallet.address.toAddress()}`,
Expand Down
3 changes: 3 additions & 0 deletions templates/nextjs/src/hooks/useActiveWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { AppWallet } from "@/lib";
/**
* burner -> a burner wallet embedded inside of the template app and stored in local storage
* browser -> a wallet connected via a browser extension like the Fuel Wallet
*
* Whenever a browser wallet is connected, this hook will return an instance of the browser wallet.
* Otherwise, it will return an instance of a local burner wallet.
*/
type WalletTypes = "burner" | "browser";

Expand Down
3 changes: 3 additions & 0 deletions templates/nextjs/src/hooks/useBrowserWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ interface BrowserWallet extends AppWallet {
network: any;
}

/**
* This hook returns an instance of the browser wallet connected via any of the supported connectors.
**/
export const useBrowserWallet: () => BrowserWallet = () => {
const { wallet } = useWallet();
const [browserWalletBalance, setBrowserWalletBalance] = useState<BN>();
Expand Down
3 changes: 3 additions & 0 deletions templates/nextjs/src/hooks/useBurnerWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import useAsync from "react-use/lib/useAsync";

const BURNER_WALLET_LOCAL_STORAGE_KEY = "create-fuels-burner-wallet-pk";

/**
* This hook returns an instance of a burner wallet that lives in local storage.
*/
export const useBurnerWallet: () => AppWallet = () => {
const [burnerWallet, setBurnerWallet] = useState<WalletUnlocked>();
const [burnerWalletBalance, setBurnerWalletBalance] = useState<BN>();
Expand Down
4 changes: 4 additions & 0 deletions templates/nextjs/src/hooks/useFaucet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ import { Provider, Wallet, WalletUnlocked } from "fuels";
import { useState } from "react";
import useAsync from "react-use/lib/useAsync";

/**
* This hook returns an instance of a faucet wallet.
* The value of `FAUCET_PRIVATE_KEY` depends on your chain config.
*/
export const useFaucet = () => {
const [faucetWallet, setFaucetWallet] = useState<WalletUnlocked>();

Expand Down
3 changes: 3 additions & 0 deletions templates/nextjs/src/lib.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import { Account, BN, TESTNET_NETWORK_URL } from 'fuels';

// The two environments for the dapp are local and testnet.
export const Environments = {
LOCAL: 'local',
TESTNET: 'testnet',
} as const;
type Environment = (typeof Environments)[keyof typeof Environments];

// The current environment is determined by the `NEXT_PUBLIC_DAPP_ENVIRONMENT` environment variable. If it's not set, the default is `local`.
export const CURRENT_ENVIRONMENT: Environment =
(process.env.NEXT_PUBLIC_DAPP_ENVIRONMENT as Environment) || Environments.LOCAL;

// The node URL is determined by the current environment too.
export const NODE_URL =
CURRENT_ENVIRONMENT === Environments.LOCAL
? `http://127.0.0.1:${process.env.NEXT_PUBLIC_FUEL_NODE_PORT || 4000}/v1/graphql`
Expand Down
4 changes: 4 additions & 0 deletions templates/nextjs/sway-programs/contract/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
contract;

// The abi defines the blueprint for the contract.
abi Counter {
#[storage(read)]
fn get_count() -> u64;
Expand All @@ -8,16 +9,19 @@ abi Counter {
fn increment_counter(amount: u64) -> u64;
}

// The storage variables for the contract. In this case, there is only one variable called `counter` which is initialized to 0.
storage {
counter: u64 = 0,
}

impl Counter for Contract {
// The `get_count` function returns the current value of the counter.
#[storage(read)]
fn get_count() -> u64 {
storage.counter.read()
}

// The `increment_counter` function increments the counter by the given amount.
#[storage(write, read)]
fn increment_counter(amount: u64) -> u64 {
let current = storage.counter.read();
Expand Down
1 change: 1 addition & 0 deletions templates/nextjs/sway-programs/predicate/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
predicate;

// This predicate checks if the given password is 1337. If it is, the predicate is 'unlocked' and the transaction is allowed to proceed. Otherwise, it is reverted.
fn main(password: u64) -> bool {
return password == 1337;
}
1 change: 1 addition & 0 deletions templates/nextjs/sway-programs/script/src/main.sw
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
script;

// This script simply returns the input value.
fn main(input: u64) -> u64 {
return input;
}

0 comments on commit e5d8029

Please sign in to comment.