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

feat: implement sendAndAwaitStatus subscription #3541

Open
wants to merge 36 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
6c3460a
chore: rebuild
danielbate Dec 24, 2024
b5acb11
chore: rebuild
danielbate Dec 24, 2024
7e26880
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts
danielbate Dec 31, 2024
73687a8
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts
danielbate Jan 2, 2025
f48e18a
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts
danielbate Jan 3, 2025
7f57a6f
feat: implement `sendTransactionAndAwaitStatus`
danielbate Jan 3, 2025
477fc29
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Jan 3, 2025
a8da82e
chore: alter snippet region
danielbate Jan 3, 2025
4757f3d
chore: changeset
danielbate Jan 3, 2025
3508138
chore: add spellcheck work
danielbate Jan 3, 2025
fc50dbe
chore: add spellcheck work
danielbate Jan 3, 2025
1eed044
chore: changeset
danielbate Jan 3, 2025
3bcf18d
Update apps/docs/src/guide/transactions/snippets/transaction-subscrip…
nedsalk Jan 5, 2025
aec7ac6
Update apps/docs/src/guide/transactions/snippets/transaction-subscrip…
nedsalk Jan 5, 2025
f071453
Update apps/docs/src/guide/transactions/transaction-subscriptions.md
nedsalk Jan 5, 2025
7e314dd
Update apps/docs/src/guide/transactions/transaction-subscriptions.md
nedsalk Jan 5, 2025
3645327
Update packages/account/src/providers/provider.ts
nedsalk Jan 5, 2025
465104b
Merge branch 'master' of https://github.com/FuelLabs/fuels-ts into db…
danielbate Jan 6, 2025
e8855c1
docs: improvement
danielbate Jan 6, 2025
c4a798c
test: remove node args
danielbate Jan 6, 2025
f825d44
Merge branch 'db/feat/send-and-await-status' of https://github.com/Fu…
danielbate Jan 6, 2025
f907073
feat: use waitForResult
danielbate Jan 6, 2025
68916ef
chore: remove test on;y
danielbate Jan 6, 2025
010bd52
docs: update docs and tests
danielbate Jan 6, 2025
298961d
chore: update spellcheck
danielbate Jan 6, 2025
3563a56
chore: lint
danielbate Jan 6, 2025
52079ba
chore: rebuild
danielbate Jan 6, 2025
189c5d9
chore: remove redundant method
danielbate Jan 6, 2025
fc5ce61
chore: code style
danielbate Jan 6, 2025
3be2a71
chore: update docs
danielbate Jan 6, 2025
de4976c
Merge branch 'db/feat/send-and-await-status' of https://github.com/Fu…
danielbate Jan 6, 2025
1a580ec
Revert "chore: code style"
danielbate Jan 6, 2025
b6b3605
Merge branch 'master' into db/feat/send-and-await-status
nedsalk Jan 6, 2025
cf73555
chore: cleaner doc
danielbate Jan 6, 2025
e3818d9
Merge branch 'master' into db/feat/send-and-await-status
arboleya Jan 6, 2025
480832b
chor: update test
danielbate Jan 7, 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
5 changes: 5 additions & 0 deletions .changeset/orange-cherries-clean.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/account": patch
---

feat: implement `sendAndAwaitStatus` subscription
12 changes: 8 additions & 4 deletions apps/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,10 +336,6 @@ export default defineConfig({
text: 'Transaction Request',
link: '/guide/transactions/transaction-request',
},
{
text: 'Transaction Response',
link: '/guide/transactions/transaction-response',
},
{
text: 'Transaction Parameters',
link: '/guide/transactions/transaction-parameters',
Expand All @@ -348,6 +344,14 @@ export default defineConfig({
text: 'Transaction Policies',
link: '/guide/transactions/transaction-policies',
},
{
text: 'Transaction Response',
link: '/guide/transactions/transaction-response',
},
{
text: 'Transaction Subscriptions',
link: '/guide/transactions/transaction-subscriptions',
},
],
},
{
Expand Down
5 changes: 4 additions & 1 deletion apps/docs/spell-check-custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -344,4 +344,7 @@ Workspaces
WSL
XOR
XORs
YAML
YAML
TransactionRequest
TransactionResponse
frictionless
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Provider, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';
import { CounterFactory } from '../../../../typegend';

const provider = await Provider.create(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);

const deploy = await CounterFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();

// #region main
// Create a new transaction request from a contract call
const txRequest = await contract.functions
.increment_count(1)
.getTransactionRequest();

// Fund the transaction
await txRequest.autoCost(wallet);

// Sign the transaction
const txSignature = await wallet.signTransaction(txRequest);
txRequest.updateWitnessByOwner(wallet.address, txSignature);

// Send the transaction and await it's result via the opened subscription
const result = await provider.sendTransactionAndAwaitStatus(txRequest);
// #endregion main

console.log('transactionId', result.id);
console.log('status', result.status);
console.log('receipts', result.receipts);
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Provider, ScriptTransactionRequest, Wallet } from 'fuels';

import { LOCAL_NETWORK_URL, WALLET_PVT_KEY } from '../../../../env';

const provider = await Provider.create(LOCAL_NETWORK_URL);
const wallet = Wallet.fromPrivateKey(WALLET_PVT_KEY, provider);
const recipient = Wallet.generate();

// #region main
// Create a new transaction request
const txRequest = new ScriptTransactionRequest();
txRequest.addCoinOutput(recipient.address, 1_000, provider.getBaseAssetId());

// Fund the transaction
await txRequest.autoCost(wallet);

// Sign the transaction
const txSignature = await wallet.signTransaction(txRequest);
txRequest.updateWitnessByOwner(wallet.address, txSignature);

// Send the transaction and await it's result via the opened subscription
const result = await provider.sendTransactionAndAwaitStatus(txRequest);
// #endregion main

console.log('transactionId', result.id);
console.log('status', result.status);
console.log('receipts', result.receipts);
16 changes: 16 additions & 0 deletions apps/docs/src/guide/transactions/transaction-subscriptions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Transaction Subscriptions

When submitting transactions via the SDK, usually this is done by calling a method in a [script](../scripts/running-scripts.md) or [contract](../contracts/methods.md#call), or sending a transaction via a [predicate](../predicates/methods.md#sendtransaction) or [wallet](../wallets/index.md). These methods submit the transaction and then return a [TransactionResponse](./transaction-response.md) that allows you to view the result of a transaction at your convenience, leaving the rest of your app processing unblocked.

However, if you want to send a transaction and wait until it's processed, for convenience the SDK also exposes the `sendTransactionAndAwaitStatus` available on a [Provider](../provider/index.md) which behaves the same as `sendTransaction` but waits until the transaction is processed by the node and then returns the transaction result.

This functionality can be used like so:

<<< @./snippets/transaction-subscriptions/transaction-request.ts#main{ts:line-numbers}

Or used with a contract call like so:

<<< @./snippets/transaction-subscriptions/contract-call.ts#main{ts:line-numbers}

> [!NOTE] Note
> This is a blocking call, which means the rest of your app logic could be blocked for several seconds until the transaction is processed. If this is a problem for your app then we recommend using the previous submission methods mentioned in this guide.
58 changes: 58 additions & 0 deletions packages/account/src/providers/provider.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2266,4 +2266,62 @@ Supported fuel-core version: ${mock.supportedVersion}.`

expect(fetchChainAndNodeInfo).toHaveBeenCalledTimes(2);
});

it('submits transaction and awaits status [success]', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider,
wallets: [wallet],
} = launched;

const transactionRequest = await wallet.createTransfer(wallet.address, 100_000);
const signedTransaction = await wallet.signTransaction(transactionRequest);
transactionRequest.updateWitnessByOwner(wallet.address, signedTransaction);
const transactionId = transactionRequest.getTransactionId(await provider.getChainId());
const response = await provider.sendTransactionAndAwaitStatus(transactionRequest, {
estimateTxDependencies: false,
});
expect(response.status).toBe('success');
expect(response.receipts.length).not.toBe(0);
expect(response.id).toBe(transactionId);
});

it('submits transaction and awaits status [success with estimation]', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider,
wallets: [wallet],
} = launched;

const transactionRequest = await wallet.createTransfer(wallet.address, 100_000);
const signedTransaction = await wallet.signTransaction(transactionRequest);
transactionRequest.updateWitnessByOwner(wallet.address, signedTransaction);
const transactionId = transactionRequest.getTransactionId(await provider.getChainId());
const response = await provider.sendTransactionAndAwaitStatus(transactionRequest);
expect(response.status).toBe('success');
expect(response.receipts.length).not.toBe(0);
expect(response.id).toBe(transactionId);
});

it('submits transaction and awaits status [failure]', async () => {
using launched = await setupTestProviderAndWallets();
const {
provider,
wallets: [wallet],
} = launched;

const transactionRequest = await wallet.createTransfer(wallet.address, 100_000);
transactionRequest.gasLimit = bn(0); // force fail
const signedTransaction = await wallet.signTransaction(transactionRequest);
transactionRequest.updateWitnessByOwner(wallet.address, signedTransaction);
await expectToThrowFuelError(
() =>
provider.sendTransactionAndAwaitStatus(transactionRequest, {
estimateTxDependencies: false,
}),
{
code: ErrorCode.SCRIPT_REVERTED,
}
);
});
});
18 changes: 17 additions & 1 deletion packages/account/src/providers/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ import {
isTransactionTypeScript,
transactionRequestify,
} from './transaction-request';
import type { TransactionResultReceipt } from './transaction-response';
import type { TransactionResult, TransactionResultReceipt } from './transaction-response';
import { TransactionResponse, getDecodedLogs } from './transaction-response';
import { processGqlReceipt } from './transaction-summary/receipt';
import {
Expand Down Expand Up @@ -892,6 +892,22 @@ Supported fuel-core version: ${supportedVersion}.`
return new TransactionResponse(transactionRequest, this, chainId, abis, subscription);
}

/**
* Submits a transaction to the chain and awaits its status response.
*
* @param transactionRequestLike - the request to submit.
* @param sendTransactionParams - The provider send transaction parameters (optional).
* @returns A promise that resolves to a settled transaction.
*/
async sendTransactionAndAwaitStatus(
transactionRequestLike: TransactionRequestLike,
providerSendTxParams: ProviderSendTxParams = {}
): Promise<TransactionResult<void>> {
danielbate marked this conversation as resolved.
Show resolved Hide resolved
const response = await this.sendTransaction(transactionRequestLike, providerSendTxParams);
const result = await response.waitForResult();
return result;
danielbate marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Executes a transaction without actually submitting it to the chain.
*
Expand Down
Loading