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 get method on BaseInvocationScope #1860

Merged
merged 37 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a001e5f
implement method get
Torres-ssf Mar 11, 2024
47134f5
add test cases
Torres-ssf Mar 11, 2024
963acb3
add doc snippets for read only calls doc page
Torres-ssf Mar 12, 2024
ed52659
add read only calls doc page
Torres-ssf Mar 12, 2024
90ba378
Merge branch 'master' into st/feat/implement-get-method
Torres-ssf Mar 12, 2024
83e42fe
fix test case description
Torres-ssf Mar 12, 2024
f266bdf
add changeset
Torres-ssf Mar 12, 2024
b4a70de
add more test cases
Torres-ssf Mar 12, 2024
2205c0c
add code snippet on counter contract
Torres-ssf Mar 12, 2024
7ab39e1
creating more code snippets for doc page
Torres-ssf Mar 12, 2024
0f1fae9
improving doc page
Torres-ssf Mar 12, 2024
c16c5ae
update test description
Torres-ssf Mar 12, 2024
01bd36a
fix typo
Torres-ssf Mar 12, 2024
da2e21c
Merge branch 'master' into st/feat/implement-get-method
Torres-ssf Mar 12, 2024
2020b88
docs: update `simulate-transaction` page (#1868)
Torres-ssf Mar 12, 2024
5d4ccf0
Merge branch 'master' into st/feat/implement-get-method
Torres-ssf Mar 12, 2024
8128241
simplify dryRun on baseInvocationScope
Torres-ssf Mar 12, 2024
42cb7b5
add error code
Torres-ssf Mar 12, 2024
92247bc
throw error on BaseInvocationScope simulate
Torres-ssf Mar 12, 2024
d3fb8d0
updating test snippets
Torres-ssf Mar 12, 2024
f7bb6a9
update doc page read-only-calls
Torres-ssf Mar 12, 2024
b567dbe
rename doc page read-only-calls to interacting-with-contracts
Torres-ssf Mar 12, 2024
448f69d
remove simulate transactions doc page
Torres-ssf Mar 12, 2024
acfec0d
remove unused doc snippet
Torres-ssf Mar 12, 2024
1a8fcd6
simplify type definition
Torres-ssf Mar 12, 2024
456bfbb
update dry run related tests
Torres-ssf Mar 13, 2024
1b56056
add more test cases on contract test suite
Torres-ssf Mar 13, 2024
c14fdad
Update apps/docs/src/guide/contracts/interacting-with-contracts.md
Torres-ssf Mar 13, 2024
e6662df
Update apps/docs/src/guide/contracts/interacting-with-contracts.md
Torres-ssf Mar 13, 2024
e5f2b15
Update apps/docs/src/guide/contracts/interacting-with-contracts.md
Torres-ssf Mar 13, 2024
49503c4
Update apps/docs/src/guide/contracts/interacting-with-contracts.md
Torres-ssf Mar 13, 2024
5ade6b0
Update apps/docs/src/guide/contracts/interacting-with-contracts.md
Torres-ssf Mar 13, 2024
e0493f0
fix flag name
Torres-ssf Mar 13, 2024
fc970b0
remove paragraph
Torres-ssf Mar 13, 2024
b6abdc6
Merge branch 'master' into st/feat/implement-get-method
Torres-ssf Mar 13, 2024
0173666
Merge branch 'master' into st/feat/implement-get-method
nedsalk Mar 14, 2024
fba8f1a
Merge branch 'master' into st/feat/implement-get-method
nedsalk Mar 14, 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
48 changes: 48 additions & 0 deletions apps/docs-snippets/src/guide/contracts/read-only-calls.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Provider } from 'fuels';
import { Wallet, Contract } from 'fuels';

import { DocSnippetProjectsEnum } from '../../../test/fixtures/forc-projects';
import { createAndDeployContractFromProject } from '../../utils';

/**
* @group node
arboleya marked this conversation as resolved.
Show resolved Hide resolved
*/
describe(__filename, () => {
let contract: Contract;
let provider: Provider;
beforeAll(async () => {
contract = await createAndDeployContractFromProject(DocSnippetProjectsEnum.ECHO_VALUES);
provider = contract.provider;
});

it('should successfully execute a read only call with get', async () => {
// #region read-only-calls-1
const { value } = await contract.functions.echo_u8(15).get();
// #endregion read-only-calls-1
expect(value).toEqual(15);
});

it('should successfully execute a contract call using an unfunded wallet', async () => {
// #region read-only-calls-2
const unfundedWallet = Wallet.generate({ provider });

contract.account = unfundedWallet;

const { value } = await contract.functions.echo_u8(15).get();
// #endregion read-only-calls-2
expect(value).toEqual(15);
});

it('should successfully execute a contract call without a wallet', async () => {
const abi = contract.interface;
const contractId = contract.id;

// #region read-only-calls-3
// contract instantiated without an account instance
const myContract = new Contract(contractId, abi, provider);

const { value } = await myContract.functions.echo_u8(15).get();
// #endregion read-only-calls-3
expect(value).toEqual(15);
});
Torres-ssf marked this conversation as resolved.
Show resolved Hide resolved
});
4 changes: 4 additions & 0 deletions apps/docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,10 @@ export default defineConfig({
text: 'Managing Deployed Contracts',
link: '/guide/contracts/managing-deployed-contracts',
},
{
text: 'Read Only Calls',
link: '/guide/contracts/read-only-calls',
},
{
text: 'Simulate Transactions',
link: '/guide/contracts/simulate-transactions',
Expand Down
23 changes: 23 additions & 0 deletions apps/docs/src/guide/contracts/read-only-calls.md
danielbate marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Read Only Calls

When interacting with a contract, you may need to validate if a contract function behaves as intended without spending any real resources.

The `get()` method can be used for this purpose.

## Read-only Calls Using `get()`

The `get` method allows you to dry-run a contract call to validate its intended behavior.

It can be used to read a contract state or retrieve a returned value from a contract function without executing a real transaction.

Here's an example of using the `get` method:

<<< @/../../docs-snippets/src/guide/contracts/read-only-calls.test.ts#read-only-calls-1{ts:line-numbers}

It can be used with a wallet that has no funds available:

<<< @/../../docs-snippets/src/guide/contracts/read-only-calls.test.ts#read-only-calls-2{ts:line-numbers}

The `get` method can also be used without a wallet to perform read-only calls.

<<< @/../../docs-snippets/src/guide/contracts/read-only-calls.test.ts#read-only-calls-3{ts:line-numbers}
28 changes: 28 additions & 0 deletions packages/fuel-gauge/src/contract.test.ts
Torres-ssf marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -1147,4 +1147,32 @@ describe('Contract', () => {
new FuelError(ErrorCode.INVALID_TRANSFER_AMOUNT, 'Transfer amount must be a positive number.')
);
});

it('should ensure "get" can be used to execute a contract call without a wallet', async () => {
const contract = await setupContract();

// contract with no account set
const contractToCall = new Contract(contract.id, contract.interface, contract.provider);

const { value } = await contractToCall.functions.sum(10, 5).get();

expect(contractToCall.account).toBeNull();
expect(value.toNumber()).toBe(15);
});

it('should ensure "get" can be used to execute a contract call with an unfunded wallet', async () => {
const contract = await setupContract();

const unfundedWallet = Wallet.generate({ provider: contract.provider });

contract.account = unfundedWallet;

const balance = await contract.account.getBalance();
expect(balance.toNumber()).toBe(0);

const { value } = await contract.functions.sum(10, 20).get();

expect(contract.account).toBeDefined();
expect(value.toNumber()).toBe(30);
});
});
16 changes: 15 additions & 1 deletion packages/program/src/functions/base-invocation-scope.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* eslint-disable no-param-reassign */
/* eslint-disable @typescript-eslint/no-explicit-any */
import type { InputValue } from '@fuel-ts/abi-coder';
import type { BaseWalletUnlocked, Provider, CoinQuantity } from '@fuel-ts/account';
import type { BaseWalletUnlocked, Provider, CoinQuantity, CallResult } from '@fuel-ts/account';
import { ScriptTransactionRequest } from '@fuel-ts/account';
import { Address } from '@fuel-ts/address';
import { ErrorCode, FuelError } from '@fuel-ts/errors';
Expand Down Expand Up @@ -410,6 +410,20 @@ export class BaseInvocationScope<TReturn = any> {
return InvocationCallResult.build<T>(this.functionInvocationScopes, response, this.isMultiCall);
}

async get<T = TReturn>(): Promise<InvocationCallResult<T>> {
const { receipts } = await this.getTransactionCost();
danielbate marked this conversation as resolved.
Show resolved Hide resolved

const callResult: CallResult = {
receipts,
};

return InvocationCallResult.build<T>(
this.functionInvocationScopes,
callResult,
this.isMultiCall
);
}

getProvider(): Provider {
const provider = <Provider>this.program.provider;

Expand Down
Loading