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

docs: add more thorough examples for predicates #2345

Merged
merged 85 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
8d43a08
docs: add predicate methods to docs
maschad May 20, 2024
94c1fd3
docs: linting fix
maschad May 20, 2024
73459ec
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad May 20, 2024
4b6e6cf
docs: fix issue with tests
maschad May 20, 2024
48f0942
docs: updated next steps for fuel docs
maschad May 20, 2024
97d309e
docs: update spellcheck
maschad May 20, 2024
ddefaef
Merge branch 'master' into mc/docs/improve-predicate-docs
Torres-ssf May 21, 2024
2d3ba71
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad May 21, 2024
c188d58
docs: updated to include account methods as well
maschad May 21, 2024
c665dfe
docs: fix typo
maschad May 21, 2024
0a3e7d0
Merge branch 'master' into mc/docs/improve-predicate-docs
Torres-ssf May 22, 2024
b739c10
docs: add suggestion around classifications
maschad May 23, 2024
2de2c3e
fix: `typegen` enum using specified generic (#2370)
nedsalk May 22, 2024
2985732
docs: add suggestion about resources
maschad May 23, 2024
abcc3e8
docs: update grammatical issue
maschad May 23, 2024
8de13ff
docs: update grammar issue
maschad May 23, 2024
c7f29cb
docs: update language
maschad May 23, 2024
ee69754
docs: updated with better explanations
maschad May 23, 2024
cb106eb
Merge branch 'master' into mc/docs/improve-predicate-docs
danielbate May 23, 2024
93e26ed
docs: updated headings
maschad May 23, 2024
1b85722
docs: update headings
maschad May 23, 2024
acac4a6
docs: add next steps demo for configurable predicate
maschad May 24, 2024
4dec544
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad May 24, 2024
967beb6
chore: linting fixes
maschad May 24, 2024
3ae84ed
chore: missing links + linting fixes
maschad May 24, 2024
8a4fba7
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad May 27, 2024
3ab9c17
docs: updated predicate demo file
maschad May 27, 2024
99dc76b
docs: update file name
maschad May 27, 2024
954b76f
docs: remove deadlink
maschad May 28, 2024
4eeb7ad
fix: remove unused code snippet
maschad May 28, 2024
19ef567
test: increase test wallet amount
maschad May 28, 2024
c863a34
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 10, 2024
50c9877
test: increase amounts
maschad Jun 10, 2024
fb99ee9
test: increase predicate amounts:
maschad Jun 10, 2024
f0f7867
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 11, 2024
8e7b7a4
docs: address feedback
maschad Jun 11, 2024
a091aec
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 11, 2024
dc5dca5
increase amounts for predicate tests
maschad Jun 11, 2024
1c0b851
reduce the amount to populate a transaction
maschad Jun 11, 2024
a137ca6
Empty commit for triggering a build
maschad Jun 11, 2024
2f601cb
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 12, 2024
5b6bd39
fix: use getTransactionCost instead
maschad Jun 12, 2024
5834d1f
docs: update typo in `transfer` doc
maschad Jun 17, 2024
c0aff95
chore: increase test timeout (#2506)
Torres-ssf Jun 13, 2024
de592fe
chore: add test to validate mint transactions serialization (#2505)
Torres-ssf Jun 13, 2024
c928b25
chore!: rename Provider `call` to `dryRun` (#2502)
Torres-ssf Jun 13, 2024
bc87c70
docs: add reference for `getMintedAssetId` (#2507)
Torres-ssf Jun 13, 2024
0c104ee
feat: support mixed native and non-native enums (#2501)
danielbate Jun 13, 2024
a256505
feat: pre-fill address and amount in `create-fuels` faucet (#2434)
Dhaiwat10 Jun 13, 2024
fbe55da
chore!: upgrade fuel core to `0.28.0` (#2491)
petertonysmith94 Jun 14, 2024
a8870cf
fix: stop overring user input `maxFee` at `deployContract` method (#2…
Torres-ssf Jun 17, 2024
b868f50
fix: `create-fuels` balance refresh (#2516)
petertonysmith94 Jun 17, 2024
80b13c2
docs: PR feedback changes
maschad Jun 17, 2024
64c5d5e
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 17, 2024
6a6e3f7
docs: update `getBalances` methods description
maschad Jun 18, 2024
e82362d
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 18, 2024
5c8100b
docs: remove populate predicate data info
maschad Jun 19, 2024
390b13d
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 19, 2024
ac6a992
lint: remove unused variable
maschad Jun 19, 2024
92000bd
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 20, 2024
ea06342
chore: add return statement to predicate toast
maschad Jun 20, 2024
25f76d0
chore: add return statement to predicate toast
maschad Jun 20, 2024
53b9bd9
docs: fix typo in instructions
maschad Jun 20, 2024
bca6e02
docs: update language for instructions
maschad Jun 20, 2024
2928f3f
docs: add update for removed options
maschad Jun 20, 2024
a25550b
docs: update language for instructions
maschad Jun 20, 2024
68356ae
Merge branch 'master' into mc/docs/improve-predicate-docs
arboleya Jun 20, 2024
2caffa7
docs: update language for `simulateTransaction`
maschad Jun 21, 2024
ccc6b76
docs: remove unnecessary link to dApp guide
maschad Jun 21, 2024
e4e78bb
docs: remove unnecessary lines
maschad Jun 21, 2024
b45bd9f
docs: PR feedback updates
maschad Jun 21, 2024
4dde2c6
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 21, 2024
598e106
Merge branch 'master' into mc/docs/improve-predicate-docs
Torres-ssf Jun 21, 2024
204a3af
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 21, 2024
29fa2f6
docs: adjust indentation
maschad Jun 21, 2024
e665246
docs: adjust indentation
maschad Jun 21, 2024
2a8de44
docs: update interacting with predicates examples
maschad Jun 21, 2024
80af938
docs: update createTransfer docs
maschad Jun 21, 2024
261aa20
docs: remove unnecessary test
maschad Jun 21, 2024
06e5e94
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 23, 2024
33a7d24
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 24, 2024
7aefdc2
Merge branch 'master' into mc/docs/improve-predicate-docs
petertonysmith94 Jun 24, 2024
255de4a
Merge branch 'master' into mc/docs/improve-predicate-docs
Torres-ssf Jun 24, 2024
5ccc948
Merge branch 'master' into mc/docs/improve-predicate-docs
arboleya Jun 24, 2024
5daa4c5
Merge branch 'master' into mc/docs/improve-predicate-docs
maschad Jun 24, 2024
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
4 changes: 4 additions & 0 deletions .changeset/large-kings-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
---

docs: add more thorough examples for predicates
1 change: 1 addition & 0 deletions .knip.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"templates/**"
],
"ignoreDependencies": [
"@/sway-api/*",
"@fuel-ts/*",
"@internal/fuel-core",
"@internal/forc",
Expand Down
183 changes: 183 additions & 0 deletions apps/create-fuels-counter-guide/src/pages/predicate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
import { Button } from "@/components/Button";
import { FuelLogo } from "@/components/FuelLogo";
import { Input } from "@/components/Input";
import { Link } from "@/components/Link";
import { useActiveWallet } from "@/hooks/useActiveWallet";
/** @knipignore */
import { TestPredicateAbi__factory } from "@/sway-api";
import { BN, InputValue, Predicate } from "fuels";
import { bn } from "fuels";
import { useState } from "react";
import toast from "react-hot-toast";
import useAsync from "react-use/lib/useAsync";

export default function PredicateExample() {
let baseAssetId: string;

const { wallet, walletBalance, refreshWalletBalance } = useActiveWallet();

const [predicate, setPredicate] = useState<Predicate<InputValue[]>>();

const [predicateBalance, setPredicateBalance] = useState<BN>();

const [pin, setPin] = useState<string>();

useAsync(async () => {
if (wallet) {
baseAssetId = wallet.provider.getBaseAssetId();
const predicate = TestPredicateAbi__factory.createInstance(wallet.provider);
setPredicate(predicate);
setPredicateBalance(await predicate.getBalance());
}
}, [wallet]);

const refreshBalances = async () => {
await refreshWalletBalance?.();
setPredicateBalance(await predicate?.getBalance());
};

const transferFundsToPredicate = async (amount: BN) => {
if (!predicate) {
return toast.error("Predicate not loaded");
}

if (!wallet) {
return toast.error("Wallet not loaded");
}

await wallet.transfer(predicate.address, amount, baseAssetId, {
gasLimit: 10_000,
});

await refreshBalances();

return toast.success("Funds transferred to predicate.");
};

const unlockPredicateAndTransferFundsBack = async (amount: BN) => {
try {
if (!wallet) {
return toast.error("Wallet not loaded");
}

const reInitializePredicate = TestPredicateAbi__factory.createInstance(wallet.provider, [bn(pin)]);

if (!reInitializePredicate) {
return toast.error("Failed to initialize predicate");
}

const tx = await reInitializePredicate.transfer(wallet.address, amount, baseAssetId);
const { isStatusSuccess } = await tx.wait();

if (!isStatusSuccess) {
toast.error("Failed to unlock predicate");
return;
}

if (isStatusSuccess) {
toast.success("Predicate unlocked");
}

await refreshBalances();
} catch (e) {
console.error(e);
toast.error(
"Failed to unlock predicate. You probably entered the wrong pin, or the predicate does not have enough balance. Try again."
);
}
};

// #region change-pin-react-function
const changePin = async () => {
if (!wallet) {
return toast.error("Wallet not loaded");
}
if (!predicate) {
return toast.error("Predicate not loaded");
}

if (walletBalance?.eq(0)) {
return toast.error(
"Your wallet does not have enough funds. Please click the 'Top-up Wallet' button in the top right corner, or use the local faucet."
);
}

if (!pin) {
return toast.error("Please enter a pin");
}

const configurable = { PIN: bn(pin) };
maschad marked this conversation as resolved.
Show resolved Hide resolved
// instantiate predicate with configurable constants
const reInitializePredicate = TestPredicateAbi__factory.createInstance(wallet.provider, [bn(configurable.PIN)], configurable);

if (!reInitializePredicate) {
return toast.error("Failed to initialize predicate");
}

// transferring funds to the predicate
const tx = await wallet.transfer(reInitializePredicate.address, 1000, baseAssetId, {
gasLimit: 10_000,
});

const { isStatusSuccess } = await tx.wait();

if (!isStatusSuccess) {
toast.error("Failed to update pin in predicate");
return;
}

if (isStatusSuccess) {
toast.success("Predicate pin updated");
}

await refreshWalletBalance?.();
};
// #endregion change-pin-react-function

return (
<>
<div className="flex gap-4">
<FuelLogo />
<h3 className="text-2xl font-semibold">Predicate</h3>
</div>

<div className="mt-12 items-baseline flex gap-2">
<h5 className="font-semibold text-xl">Wallet Balance:</h5>
<span className="text-gray-400">{walletBalance?.toString()}</span>
</div>

<div className="items-baseline flex gap-2">
<h5 className="font-semibold text-xl">Predicate Balance:</h5>
<span className="text-gray-400">{predicateBalance?.toString()}</span>
</div>

<Button onClick={async () => await transferFundsToPredicate(bn(1000))}>Transfer 1000 to Predicate</Button>

<Button onClick={changePin}>Change Pin</Button>

<Input
className="w-[300px] mt-8"
value={pin as string}
onChange={(e) => setPin(e.target.value)}
placeholder="Enter a new pin"
/>

<Button onClick={async () => await unlockPredicateAndTransferFundsBack(bn(1000))}>
Unlock Predicate and Transfer 1000 back to Wallet
</Button>

<span className="mt-8 w-[400px] text-gray-400">
Do note that when you 'unlock' a predicate, the predicate also pays for the gas of the transaction. <br />
This is why you will notice that the balance of the predicate gets reduced by 1000 + a nominal gas fee.
</span>

<Link href="https://docs.fuel.network/docs/intro/glossary/#predicate" target="_blank">
Learn more about Predicates
</Link>

<Link href="/" className="mt-12">
Back to Home
</Link>
</>
);
}
2 changes: 1 addition & 1 deletion apps/create-fuels-counter-guide/sway-programs/Forc.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[workspace]
members = ["contract"]
members = ["contract", "predicate"]
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
out
target
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
name = "test-predicate"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
predicate;

configurable {
PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
return PIN == pin;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { seedTestWallet } from '@fuel-ts/account/test-utils';
import type { Provider, WalletUnlocked } from 'fuels';
import { ScriptTransactionRequest, bn, Predicate, BN } from 'fuels';

import {
DocSnippetProjectsEnum,
getDocsSnippetsForcProject,
} from '../../../test/fixtures/forc-projects';
import { getTestWallet } from '../../utils';

/**
* @group node
*/
describe(__filename, () => {
let wallet: WalletUnlocked;
let receiver: WalletUnlocked;
let baseAssetId: string;
let provider: Provider;
let predicate: Predicate<[string]>;

const { abiContents: abi, binHexlified: bin } = getDocsSnippetsForcProject(
DocSnippetProjectsEnum.SIMPLE_PREDICATE
);

const inputAddress = '0xfc05c23a8f7f66222377170ddcbfea9c543dff0dd2d2ba4d0478a4521423a9d4';

beforeAll(async () => {
wallet = await getTestWallet();
receiver = await getTestWallet();
provider = wallet.provider;

baseAssetId = wallet.provider.getBaseAssetId();

predicate = new Predicate<[string]>({
bytecode: bin,
provider: wallet.provider,
abi,
inputData: [inputAddress],
});
await seedTestWallet(predicate, [[100_000_000, baseAssetId]]);
});

it('should get predicate resources and add them to the predicate data', async () => {
// #region interacting-with-predicates-1

// Instantiate the transaction request
const transactionRequest = new ScriptTransactionRequest({
gasLimit: 2000,
maxFee: bn(0),
});

const predicateCoins = await predicate.getResourcesToSpend([
{ amount: 2000, assetId: baseAssetId },
]);

// Add the predicate input and resources
transactionRequest.addResources(predicateCoins);
// #endregion interacting-with-predicates-1

expect(transactionRequest.inputs.length).toBeGreaterThanOrEqual(1);
expect(transactionRequest.outputs.length).toEqual(1);
});

it('should successfully transfer funds to the predicate', async () => {
const transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) });
transactionRequest.addCoinOutput(receiver.address, 100, baseAssetId);

const txCost = await provider.getTransactionCost(transactionRequest, {
resourcesOwner: predicate,
});

transactionRequest.gasLimit = txCost.gasUsed;
transactionRequest.maxFee = txCost.maxFee;

await predicate.fund(transactionRequest, txCost);

// #region interacting-with-predicates-2

const result = await predicate.sendTransaction(transactionRequest);

await result.waitForResult();
// #endregion interacting-with-predicates-2

const { isStatusSuccess } = await result.waitForResult();

expect(isStatusSuccess).toBeTruthy();
});

it('should successfully simulate a transaction with predicate', async () => {
// #region interacting-with-predicates-3
const transactionRequest = new ScriptTransactionRequest({ gasLimit: 2000, maxFee: bn(0) });
transactionRequest.addCoinOutput(receiver.address, 1000000, baseAssetId);

const txCost = await provider.getTransactionCost(transactionRequest, {
resourcesOwner: predicate,
});

transactionRequest.gasLimit = txCost.gasUsed;
transactionRequest.maxFee = txCost.maxFee;

await predicate.fund(transactionRequest, txCost);

const result = await predicate.simulateTransaction(transactionRequest);

// #endregion interacting-with-predicates-3

expect(result.receipts).toEqual([
{
type: 1,
id: expect.any(String),
val: expect.any(BN),
pc: expect.any(BN),
is: expect.any(BN),
},
{
type: 9,
gasUsed: expect.any(BN),
result: expect.any(BN),
},
]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,12 @@ describe(__filename, () => {
}
);

const chainId = provider.getChainId();
/*
You can retrieve the transaction ID before actually submitting it to the node
like this:
*/

const chainId = provider.getChainId();
const txId = transactionRequest.getTransactionId(chainId);

const res = await predicate.sendTransaction(transactionRequest);
Expand Down
1 change: 1 addition & 0 deletions apps/docs-snippets/test/fixtures/forc-projects/Forc.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ members = [
"script-signing",
"input-output-types",
"bytecode-input",
"configurable-pin",
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[project]
authors = ["Fuel Labs <contact@fuel.sh>"]
entry = "main.sw"
license = "Apache-2.0"
name = "configurable-pin"

[dependencies]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// #region predicate-with-configurable-pin-1
predicate;

configurable {
PIN: u64 = 1337,
}

fn main(pin: u64) -> bool {
return PIN == pin;
}

// #endregion predicate-with-configurable-pin-1
Loading
Loading