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!: optimizing frontend apps #3573

Merged
merged 27 commits into from
Jan 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
c14be30
chore: update tx page titles
danielbate Jan 10, 2025
975fc41
docs: optimizing FE apps
danielbate Jan 10, 2025
f0a2e9e
docs: add final comment
danielbate Jan 10, 2025
63f2ec0
Revert "feat: implement `sendAndAwaitStatus` subscription (#3541)"
danielbate Jan 10, 2025
b1f053f
feat: `autoCost` -> `estimateAndFund`
danielbate Jan 10, 2025
e8bb60c
chore: fix docs links
danielbate Jan 10, 2025
b5ea0dc
feat: autoCost -> fundWithRequiredCoins
danielbate Jan 10, 2025
51bb7f8
docs: add react advanced example
danielbate Jan 10, 2025
f54e34c
docs: actually push the advanced example
danielbate Jan 10, 2025
2fe8fee
Merge branch 'master' of github.com:FuelLabs/fuels-ts into db/docs/tx…
danielbate Jan 10, 2025
dbdbe4e
chore: lint
danielbate Jan 10, 2025
f194ea2
chore: changeset
danielbate Jan 10, 2025
fa7bcd7
docs: use other wallet gen in react example
danielbate Jan 10, 2025
0f897fc
chore: changeset is breaking
danielbate Jan 10, 2025
eaaa903
chore: fix test
danielbate Jan 10, 2025
8cca7c4
Merge branch 'master' of github.com:FuelLabs/fuels-ts into db/docs/tx…
danielbate Jan 10, 2025
015a6c4
chore: lint
danielbate Jan 10, 2025
8aa6a0f
chore: update react example
danielbate Jan 10, 2025
5d68edc
chore: remove dust
danielbate Jan 10, 2025
2af7a31
docs: optimizing frontend apps touchups (#3574)
arboleya Jan 10, 2025
5dae357
chore: lintfix
petertonysmith94 Jan 10, 2025
a8c42c3
chore: remove deploy from docs dev command
danielbate Jan 10, 2025
80fe1f1
docs: advanced react example and language updats
danielbate Jan 10, 2025
e0dace5
Merge branch 'db/docs/tx-speed' of github.com:FuelLabs/fuels-ts into …
danielbate Jan 10, 2025
17ad54e
chore: reintroduce deploy flag in docs dev command
danielbate Jan 10, 2025
92f6ed6
docs: add link file endings
danielbate Jan 10, 2025
3563090
docs: fix relative links
danielbate Jan 10, 2025
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
7 changes: 7 additions & 0 deletions .changeset/khaki-candles-beg.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@fuel-ts/account": minor
"@fuel-ts/program": minor
"@fuel-ts/script": patch
---

docs!: optimizing frontend apps
5 changes: 0 additions & 5 deletions .changeset/orange-cherries-clean.md

This file was deleted.

24 changes: 14 additions & 10 deletions apps/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,24 +333,24 @@ export default defineConfig({
collapsed: true,
items: [
{
text: 'Transaction Request',
link: '/guide/transactions/transaction-request',
text: 'Modifying the Request',
link: '/guide/transactions/modifying-the-request',
},
{
text: 'Transaction Parameters',
link: '/guide/transactions/transaction-parameters',
text: 'Adding Parameters',
link: '/guide/transactions/adding-parameters',
},
{
text: 'Transaction Policies',
link: '/guide/transactions/transaction-policies',
text: 'Adding Policies',
link: '/guide/transactions/adding-policies',
},
{
text: 'Transaction Response',
link: '/guide/transactions/transaction-response',
text: 'Getting the Response',
link: '/guide/transactions/getting-the-response',
},
{
text: 'Transaction Subscriptions',
link: '/guide/transactions/transaction-subscriptions',
text: 'Optimizing Frontend Apps',
link: '/guide/transactions/optimizing-frontend-apps',
},
],
},
Expand Down Expand Up @@ -437,6 +437,10 @@ export default defineConfig({
text: 'Splitting UTXOs',
link: '/guide/cookbook/splitting-utxos',
},
{
text: 'Optimized React Example',
link: '/guide/cookbook/optimized-react-example',
},
],
},
{
Expand Down
5 changes: 1 addition & 4 deletions apps/docs/spell-check-custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -343,7 +343,4 @@ Workspaces
WSL
XOR
XORs
YAML
TransactionRequest
TransactionResponse
frictionless
YAML
4 changes: 2 additions & 2 deletions apps/docs/src/guide/contracts/call-parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ When interacting with contracts, you can configure specific parameters for contr
2. `gasLimit`
<!-- call_params:example:end -->

> **Note**: Setting transaction parameters is also available when calling contracts. More information on this can be found at [Transaction Parameters](../transactions/transaction-parameters.md).
> **Note**: Setting transaction parameters is also available when calling contracts. More information on this can be found at [Transaction Parameters](../transactions/adding-parameters.md).

The contract in use in this section has the following implementation:

Expand Down Expand Up @@ -39,7 +39,7 @@ The `gasLimit` refers to the maximum amount of gas that can be consumed specific

## Call Parameter `gasLimit` vs Transaction Parameter `gasLimit`

The call parameter `gasLimit` sets the maximum gas allowed for the actual contract call, whereas the transaction parameter `gasLimit` _(see [Transaction Parameters](../transactions/transaction-parameters.md))_ sets the maximum gas allowed for the entire transaction and constrains the `gasLimit` call parameter. If the call parameter `gasLimit` is set to a value greater than the _available_ transaction gas, then the entire available transaction gas will be allocated for the contract call execution.
The call parameter `gasLimit` sets the maximum gas allowed for the actual contract call, whereas the transaction parameter `gasLimit` _(see [Transaction Parameters](../transactions/adding-parameters.md))_ sets the maximum gas allowed for the entire transaction and constrains the `gasLimit` call parameter. If the call parameter `gasLimit` is set to a value greater than the _available_ transaction gas, then the entire available transaction gas will be allocated for the contract call execution.

If you don't set the `gasLimit` for the call, the transaction `gasLimit` will be applied.

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/guide/contracts/using-different-wallets.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ const newProvider = new Provider(NEW_URL);
deployedContract.provider = newProvider;
```

> **Note:** When connecting a different wallet to an existing contract instance, the provider used to deploy the contract takes precedence over the newly set provider. If you have two wallets connected to separate providers (each communicating with a different fuel-core instance), the provider assigned to the deploying wallet will be used for contract calls. This behavior is only relevant when multiple providers (i.e., fuel-core instances) are present and can be ignored otherwise.
> **Note:** When connecting a different wallet to an existing contract instance, the provider used to deploy the contract takes precedence over the newly set provider. If you have two wallets connected to separate providers (each communicating with a different fuel-core instance), the provider assigned to the deploying wallet will be used for contract calls. This behavior is only relevant when multiple providers (i.e. fuel-core instances) are present and can be ignored otherwise.
69 changes: 69 additions & 0 deletions apps/docs/src/guide/cookbook/optimized-react-example.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Optimized React Example

This example implements the strategies outlined in [Optimizing Frontend Apps](../transactions/optimizing-frontend-apps.md) and demonstrates how to improve the perceived speed of transactions in a React application.

```tsx
import { Provider, Wallet, ScriptTransactionRequest } from "fuels";
import { useEffect, useState } from "react";

import { TestContract } from "./typegend";
import contractIds from "./typegend/contract-ids.json";

function App() {
const [request, setRequest] = useState<ScriptTransactionRequest | null>(null);

// Initialize the provider and wallet
const NETWORK_URL = "https://mainnet.fuel.network/v1/graphql";
const provider = new Provider(NETWORK_URL);
const wallet = Wallet.fromAddress("0x...", provider);

/**
* Here we'll prepare our transaction upfront on page load, so that
* by the time the user interacts with your app (i.e. clicking a btn),
* the transaction is ready to be submitted
*/
useEffect(() => {
const onPageLoad = async () => {
// 1. Connect to the contract
const contractInstance = new TestContract(
contractIds.testContract,
wallet,
);

// 2. Invoke the contract function whilst estimating and funding the
// call, which gives us the transaction request
const preparedRequest = await contractInstance.functions
.increment_counter(1)
.fundWithRequiredCoins();

setRequest(preparedRequest);
};

onPageLoad();
}, []);

/**
* By the time user user clicks the submit button, we only need to
* submit the transaction to the network
*/
const handleSubmit = async () => {
if (!request) return;

// 1. Submit the transaction to the network
const response = await wallet.sendTransaction(request);

// 2. Wait for the transaction to settle and get the result
const result = await response.waitForResult();

console.log("result", result);
};

return (
<div>
<button onClick={handleSubmit}>Submit</button>
</div>
);
}

export default App;
```
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ transactionRequest.addCoinOutput(
);

// Estimate and fund the transaction
await transactionRequest.autoCost(wallet);
await transactionRequest.estimateAndFund(wallet);

// Submit the transaction
const response = await wallet.sendTransaction(transactionRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ request.addResources(resources);

// Estimate and fund the request
request.addWitness('0x');
await request.autoCost(predicate, {
await request.estimateAndFund(predicate, {
signatureCallback: (txRequest) => txRequest.addAccountWitnesses(signer),
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const encodedArguments = abiInterface.encodeType(argument, [argumentToAdd]);
request.scriptData = encodedArguments;

// Now we can estimate and fund the transaction
await request.autoCost(wallet);
await request.estimateAndFund(wallet);

// Finally, submit the built transaction
const response = await wallet.sendTransaction(request);
Expand Down
7 changes: 4 additions & 3 deletions apps/docs/src/guide/getting-started/react-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ function App() {
const [balance, setBalance] = useState(0);

useEffect(() => {
const main = async () => {
const onPageLoad = async () => {
const provider = new Provider("https://mainnet.fuel.network/v1/graphql");

const wallet = Wallet.fromAddress("0x...", provider);
Expand All @@ -19,7 +19,7 @@ function App() {
setBalance(new BN(balances[0].amount).toNumber());
};

main();
onPageLoad();
}, []);

return <div>My Balance: {balance}</div>;
Expand All @@ -28,6 +28,7 @@ function App() {
export default App;
```

# More
# See Also

- [Optimized React Example](../cookbook/optimized-react-example.md)
- [CDN Usage](./cdn-usage.md)
2 changes: 1 addition & 1 deletion apps/docs/src/guide/predicates/custom-transactions.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Utilizing predicate logic unlocks a wide range of possibilities for your dApps when creating transactions. Therefore, pairing predicates with custom transactions can help you achieve more complex use cases. This can be achieved by instantiating a custom transaction, appending the predicate resources, and submitting the transaction via a successfully validated predicate.

Custom transactions can be shaped via a `ScriptTransactionRequest` instance. For more information on crafting custom transactions and the methods available to them, please refer to the [Transaction Request](../transactions/transaction-request.md) guide.
Custom transactions can be shaped via a `ScriptTransactionRequest` instance. For more information on crafting custom transactions and the methods available to them, please refer to the [Transaction Request](../transactions/modifying-the-request.md) guide.

However, this guide will demonstrate how to use a predicate in a custom transaction. Consider the following predicate, where a configurable pin must be used to validate the predicate and unlock the funds:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ customRequest.addResources(predicateResources);
customRequest.addCoinOutput(receiver.address, amountToReceiver, assetId);

// Estimate the transaction cost and fund accordingly
await customRequest.autoCost(predicate);
await customRequest.estimateAndFund(predicate);

// Submit the transaction and await it's result
const predicateTx = await predicate.sendTransaction(customRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const predicateCoins = await predicate.getResourcesToSpend([
transactionRequest.addResources(predicateCoins);

// Estimate and fund the transaction
await transactionRequest.autoCost(predicate);
await transactionRequest.estimateAndFund(predicate);

// Send the transaction using the predicate
const result = await predicate.sendTransaction(transactionRequest);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const transactionRequest = new ScriptTransactionRequest({
transactionRequest.addCoinOutput(receiver.address, 1000000, baseAssetId);

// Estimate and fund the transaction
await transactionRequest.autoCost(predicate);
await transactionRequest.estimateAndFund(predicate);

const result = await predicate.simulateTransaction(transactionRequest);

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/src/guide/scripts/custom-script-call.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Preparing a Script Transaction

Akin to Contracts, we can configure the [call parameters](../contracts/call-parameters.md) and [transaction parameters](../transactions/transaction-parameters.md) for Scripts, as well as retrieve the entire transaction request or transaction ID prior to submission.
Akin to Contracts, we can configure the [call parameters](../contracts/call-parameters.md) and [transaction parameters](../transactions/adding-parameters.md) for Scripts, as well as retrieve the entire transaction request or transaction ID prior to submission.

<<< @./snippets/script-with-configurable.ts#preparing-scripts{ts:line-numbers}
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ const quantities = [
];

// 5. Estimate and fund the transaction
await request.autoCost(wallet, { quantities });
await request.estimateAndFund(wallet, { quantities });

// 6. Send the transaction
const tx = await wallet.sendTransaction(request);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Transaction Parameters
# Adding Parameters

Transaction parameters allow you to configure various aspects of your blockchain transactions. Dependent on these parameters, it may introduce a [transaction policy](./transaction-policies.md).
Transaction parameters allow you to configure various aspects of your blockchain transactions. Dependent on these parameters, it may introduce a [transaction policy](./adding-policies.md).

All available parameters are shown below:

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Transaction Policies
# Adding Policies

Transaction policies are rules that can govern how a transaction is processed, introduced by the [transaction parameters](./transaction-parameters.md) that you pass to a transaction request. The available policies are as follows:
Transaction policies are rules that can govern how a transaction is processed, introduced by the [transaction parameters](./adding-parameters.md) that you pass to a transaction request. The available policies are as follows:

### Tip

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,17 +38,17 @@ Including `OutputCoin`s in the transaction request specifies the UTXOs that will

### Estimating and Funding the Transaction Request

Before submitting a transaction, it is essential to ensure it is properly funded to meet its requirements and cover the associated fee. The SDK offers two approaches for this, one is to use the `autoCost` helper:
Before submitting a transaction, it is essential to ensure it is properly funded to meet its requirements and cover the associated fee. The SDK offers two approaches for this, one is to use the `estimateAndFund` helper:

<<< @./snippets/transaction-request/auto-cost.ts#auto-cost{ts:line-numbers}
<<< @./snippets/transaction-request/estimate-and-fund.ts#estimate-and-fund{ts:line-numbers}

This approach provides a simple one-liner for estimating and funding the transaction request. Ensuring that the `gasLimit` and `maxFee` are accurately calculated and that the required amounts for `OutputCoin`s are fulfilled, as well as fetching and adding any missing resources from the calling account.

The other more manual approach is as so:

<<< @./snippets/transaction-request/estimate-and-fund.ts#transaction-request-4{ts:line-numbers}
<<< @./snippets/transaction-request/get-transaction-cost.ts#transaction-request-4{ts:line-numbers}

This approach provides the same behaviour as the `autoCost` helper, but gives more granular control over the transaction request. The `getTransactionCost` method also returns various information about the simulated request that you may want to use to further modify the transaction request, more on that can be found in the [API reference](https://fuels-ts-docs-api.vercel.app/types/_fuel_ts_account.TransactionCost.html).
This approach provides the same behaviour as the `estimateAndFund` helper, but gives more granular control over the transaction request. The `getTransactionCost` method also returns various information about the simulated request that you may want to use to further modify the transaction request, more on that can be found in the [API reference](https://fuels-ts-docs-api.vercel.app/types/_fuel_ts_account.TransactionCost.html).

### Manually Fetching Resources

Expand Down
39 changes: 39 additions & 0 deletions apps/docs/src/guide/transactions/optimizing-frontend-apps.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Optimizing Frontend Apps

Your application must perform a series of operations to estimate, submit and receive the result of a transaction. However, the flow in which it performs these actions can be organized or performed optimistically, increasing it's perceived speed.

## Use Case

In a frontend application, imagine we have a button that executes a contract call:

```tsx
<Button onClick={handleSubmit}>Submit</Button>
```

The handler would be implemented as follows:

<<< @./snippets/transaction-speed/transaction-speed-init.ts#main{ts:line-numbers}

Once the user clicks the button, multiple sequential calls are made to the network, which can take a while because the transaction must be:

1. Estimated
1. Funded
1. Submitted

## Optimization Strategy

With a few optimizations, the flow can be organized as follows:

<<< @./snippets/transaction-speed/transaction-speed-optimized.ts#main{ts:line-numbers}

## Conclusion

Finally, when users click the button, they only need to submit the transaction, which vastly improves the perceived speed of the transaction because many of the necessary requests were done upfront, under the hood.

Just remember:

- _After preparation, any changes made to the transaction request will require it to be re-estimated and re-funded before it can be signed and submitted._

# See Also

- Check a full example at [Optimized React Example](../cookbook/optimized-react-example.md)
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ transactionRequest.inputs.push({
});

// Fund the transaction
await transactionRequest.autoCost(sender);
await transactionRequest.estimateAndFund(sender);

// Send the transaction with asset burn enabled
const tx = await sender.sendTransaction(transactionRequest, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,12 @@ import { ScriptSum } from '../../../../typegend';
const provider = new Provider(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

// #region transaction-request-4
// #region estimate-and-fund
const transactionRequest = new ScriptTransactionRequest({
script: ScriptSum.bytecode,
});

const cost = await wallet.getTransactionCost(transactionRequest);

transactionRequest.gasLimit = cost.gasUsed;
transactionRequest.maxFee = cost.maxFee;

await wallet.fund(transactionRequest, cost);
await transactionRequest.estimateAndFund(wallet);

await wallet.sendTransaction(transactionRequest);
// #endregion transaction-request-4
// #endregion estimate-and-fund
Loading
Loading