-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docs: custom transactions with predicates (#2864)
* doc: add test and doc for predicate custom transaction * chore: changeset * docs: typo * docs: fix workding Co-authored-by: Anderson Arboleya <[email protected]> * docs: fix wording Co-authored-by: Anderson Arboleya <[email protected]> * docs: move test launcher out of snippet * docs: fix context imports * docs: fix import * docs: use import * test: fix provider * docs: spacing * chore: fix imports --------- Co-authored-by: Sérgio Torres <[email protected]> Co-authored-by: Anderson Arboleya <[email protected]>
- Loading branch information
1 parent
751d638
commit 2f0a176
Showing
4 changed files
with
111 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--- | ||
--- | ||
|
||
docs: custom transactions with predicates |
90 changes: 90 additions & 0 deletions
90
apps/docs-snippets/src/guide/predicates/predicate-custom-transactions.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
import { Provider, ScriptTransactionRequest, Wallet, TESTNET_NETWORK_URL } from 'fuels'; | ||
import { launchTestNode } from 'fuels/test-utils'; | ||
|
||
import { ConfigurablePinAbi__factory as PredicateFactory } from '../../../test/typegen'; | ||
import type { ConfigurablePinAbiInputs as PredicateInputs } from '../../../test/typegen'; | ||
|
||
/** | ||
* @group node | ||
* @group browser | ||
*/ | ||
describe('Predicate Custom Transactions', () => { | ||
it('uses a predicate in a custom transaction', async () => { | ||
using launched = await launchTestNode(); | ||
const { | ||
wallets: [testSender, testReceiver], | ||
provider: testProvider, | ||
} = launched; | ||
|
||
const SENDER_PVT_KEY = testSender.privateKey; | ||
const RECEIVER_ADDRESS = testReceiver.address; | ||
// eslint-disable-next-line @typescript-eslint/no-shadow | ||
const TESTNET_NETWORK_URL = testProvider.url; | ||
|
||
await Provider.create(TESTNET_NETWORK_URL); | ||
|
||
const initialRecieverBalance = await testReceiver.getBalance(testProvider.getBaseAssetId()); | ||
|
||
// #region predicate-custom-transaction | ||
// #import { Provider, ScriptTransactionRequest, TESTNET_NETWORK_URL, Wallet }; | ||
// #context import { PredicateFactory } from 'path/to/typegen/outputs'; | ||
// #context import type { PredicateInputs } from 'path/to/typegen/outputs'; | ||
// #context import { SENDER_PVT_KEY, RECEIVER_ADDRESS } from 'path/to/my/env/file'; | ||
|
||
// Setup | ||
const provider = await Provider.create(TESTNET_NETWORK_URL); | ||
const sender = Wallet.fromPrivateKey(SENDER_PVT_KEY, provider); | ||
const receiver = Wallet.fromAddress(RECEIVER_ADDRESS, provider); | ||
const assetId = provider.getBaseAssetId(); | ||
const amountToFundPredicate = 300_000; | ||
const amountToReceiver = 100_000; | ||
|
||
// Instantiate the predicate using valid predicate data, aka the pin we need | ||
// to send the funds to the receiver | ||
const predicateData: PredicateInputs = [1337]; | ||
const predicate = PredicateFactory.createInstance(provider, predicateData); | ||
|
||
// Fund the predicate, so that we can send these funds via predicate logic | ||
// to the receiver | ||
const fundPredicateTx = await sender.transfer( | ||
predicate.address, | ||
amountToFundPredicate, | ||
assetId | ||
); | ||
await fundPredicateTx.waitForResult(); | ||
const initialPredicateBalance = await predicate.getBalance(assetId); | ||
|
||
// Instantiate the script request | ||
const customRequest = new ScriptTransactionRequest(); | ||
|
||
// Get the predicate resources that we would like to transfer | ||
const predicateResources = await predicate.getResourcesToSpend([ | ||
{ assetId, amount: amountToReceiver }, | ||
]); | ||
|
||
// Add the resources for the transfer of the asset to the receiver. The resources | ||
// adds the required inputs, and the output is for the transfer to the receiver address | ||
customRequest.addResources(predicateResources); | ||
customRequest.addCoinOutput(receiver.address, amountToReceiver, assetId); | ||
|
||
// Estimate the transaction cost and fund accordingly | ||
const txCost = await predicate.getTransactionCost(customRequest); | ||
customRequest.gasLimit = txCost.gasUsed; | ||
customRequest.maxFee = txCost.maxFee; | ||
await predicate.fund(customRequest, txCost); | ||
|
||
// Submit the transaction and await it's result | ||
const predicateTx = await predicate.sendTransaction(customRequest); | ||
await predicateTx.waitForResult(); | ||
// #endregion predicate-custom-transaction | ||
|
||
expect(initialPredicateBalance.toNumber()).toEqual(amountToFundPredicate); | ||
const { isStatusSuccess } = await predicateTx.waitForResult(); | ||
expect(isStatusSuccess).toBe(true); | ||
const finalReceiverBalance = await receiver.getBalance(assetId); | ||
expect(finalReceiverBalance.toNumber()).toEqual( | ||
initialRecieverBalance.add(amountToReceiver).toNumber() | ||
); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
# Custom Transactions | ||
|
||
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. | ||
|
||
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: | ||
|
||
<<< @/../../docs-snippets/test/fixtures/forc-projects/configurable-pin/src/main.sw#predicate-with-configurable-pin-1{rust:line-numbers} | ||
|
||
We can interact with the above and include it in a custom transaction like so: | ||
|
||
<<< @/../../docs-snippets/src/guide/predicates/predicate-custom-transactions.test.ts#predicate-custom-transaction{ts:line-numbers} |