Skip to content

Commit

Permalink
feat: expose decoded transaction in fetch method (#618)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuizAsFight authored Nov 28, 2022
1 parent aacc9c6 commit 563ecc5
Show file tree
Hide file tree
Showing 4 changed files with 452 additions and 359 deletions.
5 changes: 5 additions & 0 deletions .changeset/hip-seas-reflect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fuel-ts/providers": minor
---

include decoded transaction in #fetch method response
55 changes: 30 additions & 25 deletions packages/providers/src/transaction-response/transaction-response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,28 +104,33 @@ export class TransactionResponse {
this.provider = provider;
}

async #fetch(): Promise<NonNullable<GqlGetTransactionWithReceiptsQuery['transaction']>> {
const { transaction } = await this.provider.operations.getTransactionWithReceipts({
transactionId: this.id,
});
if (!transaction) {
async fetch<TTransactionType = void>(): Promise<{
transactionWithReceipts: NonNullable<GqlGetTransactionWithReceiptsQuery['transaction']>;
transaction: Transaction<TTransactionType>;
}> {
const { transaction: transactionWithReceipts } =
await this.provider.operations.getTransactionWithReceipts({
transactionId: this.id,
});
if (!transactionWithReceipts) {
throw new Error('No Transaction was received from the client.');
}
return transaction;

const transaction = new TransactionCoder().decode(
arrayify(transactionWithReceipts.rawPayload),
0
)?.[0] as Transaction<TTransactionType>;

return { transactionWithReceipts, transaction };
}

/** Waits for transaction to succeed or fail and returns the result */
async waitForResult<TTransactionType = void>(): Promise<
TransactionResult<any, TTransactionType>
> {
const transaction = await this.#fetch();

const decodedTransaction = new TransactionCoder().decode(
arrayify(transaction.rawPayload),
0
)?.[0] as Transaction<TTransactionType>;
const { transactionWithReceipts, transaction } = await this.fetch<TTransactionType>();

switch (transaction.status?.type) {
switch (transactionWithReceipts.status?.type) {
case 'SubmittedStatus': {
// This code implements a similar approach from the fuel-core await_transaction_commit
// https://github.com/FuelLabs/fuel-core/blob/cb37f9ce9a81e033bde0dc43f91494bc3974fb1b/fuel-client/src/client.rs#L356
Expand All @@ -140,40 +145,40 @@ export class TransactionResponse {
return this.waitForResult();
}
case 'FailureStatus': {
const receipts = transaction.receipts!.map(processGqlReceipt);
const receipts = transactionWithReceipts.receipts!.map(processGqlReceipt);
const { gasUsed, fee } = calculateTransactionFee({
receipts,
gasPrice: bn(transaction?.gasPrice),
gasPrice: bn(transactionWithReceipts?.gasPrice),
});

this.gasUsed = gasUsed;
return {
status: { type: 'failure', reason: transaction.status.reason },
status: { type: 'failure', reason: transactionWithReceipts.status.reason },
receipts,
transactionId: this.id,
blockId: transaction.status.block.id,
time: transaction.status.time,
blockId: transactionWithReceipts.status.block.id,
time: transactionWithReceipts.status.time,
gasUsed,
fee,
transaction: decodedTransaction,
transaction,
};
}
case 'SuccessStatus': {
const receipts = transaction.receipts?.map(processGqlReceipt) || [];
const receipts = transactionWithReceipts.receipts?.map(processGqlReceipt) || [];
const { gasUsed, fee } = calculateTransactionFee({
receipts,
gasPrice: bn(transaction?.gasPrice),
gasPrice: bn(transactionWithReceipts?.gasPrice),
});

return {
status: { type: 'success', programState: transaction.status.programState },
status: { type: 'success', programState: transactionWithReceipts.status.programState },
receipts,
transactionId: this.id,
blockId: transaction.status.block.id,
time: transaction.status.time,
blockId: transactionWithReceipts.status.block.id,
time: transactionWithReceipts.status.time,
gasUsed,
fee,
transaction: decodedTransaction,
transaction,
};
}
default: {
Expand Down
23 changes: 20 additions & 3 deletions packages/script/src/script.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { AbiCoder } from '@fuel-ts/abi-coder';
import { NativeAssetId } from '@fuel-ts/constants';
import type { BigNumberish } from '@fuel-ts/math';
import { bn } from '@fuel-ts/math';
import type { CoinQuantityLike, TransactionResult } from '@fuel-ts/providers';
import type { CoinQuantityLike, TransactionResponse, TransactionResult } from '@fuel-ts/providers';
import { Provider, ScriptTransactionRequest } from '@fuel-ts/providers';
import { ReceiptType } from '@fuel-ts/transactions';
import type { BaseWalletLocked } from '@fuel-ts/wallet';
Expand All @@ -31,7 +31,11 @@ const callScript = async <TData, TResult>(
wallet: BaseWalletLocked,
script: Script<TData, TResult>,
data: TData
): Promise<{ transactionResult: TransactionResult<any>; result: TResult }> => {
): Promise<{
transactionResult: TransactionResult<any>;
result: TResult;
response: TransactionResponse;
}> => {
const request = new ScriptTransactionRequest({
gasLimit: 1000000,
});
Expand All @@ -52,7 +56,7 @@ const callScript = async <TData, TResult>(
const transactionResult = await response.waitForResult();
const result = script.decodeCallResult(transactionResult);

return { transactionResult, result };
return { transactionResult, result, response };
};

const scriptAbi = [
Expand Down Expand Up @@ -136,4 +140,17 @@ describe('Script', () => {
expect(JSON.stringify(result)).toEqual(JSON.stringify(output));
expect(transactionResult.gasUsed?.toNumber()).toBeGreaterThan(0);
});

it('should TransactionResponse fetch return graphql transaction and also decoded transaction', async () => {
const wallet = await setup();
const input = {
arg_one: true,
arg_two: 1337,
};
const { response } = await callScript(wallet, script, input);
const { transactionWithReceipts, transaction } = await response.fetch();

expect(transactionWithReceipts.rawPayload).toBeDefined();
expect(transaction.scriptLength).toBeGreaterThan(0);
});
});
Loading

0 comments on commit 563ecc5

Please sign in to comment.