Skip to content

Releases: FuelLabs/fuels-rs

v0.31.1

16 Nov 21:34
2e952d2
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.31.0...v0.31.1

v0.31.0

10 Nov 16:06
4af01fd
Compare
Choose a tag to compare

What's Changed

  • Remove note on --generate-logged-types in the Book by @mohammadfawaz in #678
  • feat: add format and clean to test-projects by @hal3e in #685
  • feat: support evm address by @MujkicA in #668
  • fix: rustc can't prove Send on futures returned by contract methods by @Salka1988 in #669
  • fix!: get_asset_inputs_for_amount uses resources by @MujkicA in #692
  • release: bump versions to 0.31.0 by @digorithm in #693

Full Changelog: v0.30.0...v0.31.0

Breaking changes

Wallet's get_asset_inputs_for_amount now uses Resources instead of Coins

This means that if you want to cover fees of a transaction using any Resource, i.e., Coin and Message (if you're bridging to Ethereum, for instance) get_asset_inputs_for_amount will now consider Messages, which it didn't before.

v0.30.0

05 Nov 19:56
5498136
Compare
Choose a tag to compare

What's Changed

  • fuel-core v0.14 tai64 timestamp support by @Voxelot in #676
  • bump to v0.30.0 to release breaking fuel-core changes by @Voxelot in #677

Full Changelog: v0.29.0...v0.30.0

v0.29.0

04 Nov 21:55
3374c68
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.28.0...v0.29.0

Breaking changes

All test helpers related to spinning up test nodes now take a Option<ChainConfig> parameter. This is useful for configuring things like gas limits of the test chain, etc. Most likely, you won't need it, which means all you have to do is add a None to that test helper method.

v0.28.0

01 Nov 22:41
d19674e
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.27.0...v0.28.0

v0.27.0

27 Oct 14:48
025d0c0
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.26.0...v0.27.0

Breaking changes

Contract instance creation now takes a Bech32ContractId, not a string

This type-safety enforcement is needed to avoid many issues down the line. This also makes the UX a bit more friendly by not needing many conversions back and forth between strings, Bech32ContractId, and ContractId.

Once you deploy your contract using the SDK, the contract_id you receive back is already a Bech32ContractId, so the workflow looks like this:

let contract_id = Contract::deploy(
    "../../packages/fuels/tests/contracts/contract_test/out/debug/contract_test.bin",
    &wallet,
    TxParameters::default(),
    StorageConfiguration::default(),
)
.await?;

let contract_methods = MyContract::new(contract_id, wallet).methods(); // No need to call `.to_string()` on `contract_id`. 

New features

Variable output estimation

Instead of manually setting the exact number of variable output in your transaction (which sometimes includes guessing this number), the SDK now offers an estimate_tx_dependencies() that will do this guesswork for you and automatically update the transaction with the right value for variable output. E.g.:

let _ = contract_methods
        .mint_to_addresses(amount, addresses)
        .estimate_tx_dependencies(None) // It takes a limit of how many estimation/guesses it'll perform, `None` for no limits.
        .await?
        .call()
        .await?;

The same will be done for the contract input set through the same API (estimate_tx_dependencies()) in the next release.

Bits256 from strings

A new helper method to create Bits256 from strings is also included in this release: let bits256 = Bits256::from_hex_str(hex_str)?;

Query the balance from your contract through the contract_instance

It's very common to try and check the contract's balance. Before you had to use the Provider directly; now you can use the contract_instance itself: let contract_balances = contract_instance.get_balances().await?;.

v0.26.0

14 Oct 15:51
5c81de8
Compare
Choose a tag to compare

What's Changed

  • feat!: add Option<Provider> as parameter in run_compiled_script by @Salka1988 in #610
  • Fix: change transfer_to_output to transfer_to_address by @digorithm in #614
  • Some minor cosmetic updates to the SDK Sway tests by @mohammadfawaz in #621
  • Test logging generics by @MujkicA in #616
  • feat: ParamType from TypeApplication/TypeDeclaration in order to generate fn selectors without code generation by @segfault-magnet in #619
  • refactor: change organisation of the integration tests by @hal3e in #607
  • fix: Ignore lock files and out/ directory by @digorithm in #623
  • ci: update forc version in CI by @iqdecay in #627
  • release: bump versions to v0.26.0 by @iqdecay in #626

New Contributors

Full Changelog: v0.25.1...v0.26.0

Breaking changes

Option<Provider> on run_compiled_script

run_compiled_script now takes an Option<Provider>, this is a straightforward change; All you have to do to migrate is add a None or pass a provider, if desired, to your run_compiled_script call.

New features

Generate ParamTypes from your JSON ABI TypeApplications

This has a niche use, mostly for internal tooling development. All you have to do is use ParamType::try_from_type_application(&type_appl, &type_lookup). Here's an example:

let abi: ProgramABI = serde_json::from_str(&abi_file_contents)?;

let type_lookup = abi
    .types
    .into_iter()
    .map(|a_type| (a_type.type_id, a_type))
    .collect::<HashMap<_, _>>();

let a_fun = abi
    .functions
    .into_iter()
    .find(|fun| fun.name == "array_of_structs")
    .unwrap();

let inputs = a_fun
    .inputs
    .into_iter()
    .map(|type_appl| ParamType::try_from_type_application(&type_appl, &type_lookup))
    .collect::<Result<Vec<_>, _>>()?;

let selector = resolve_fn_selector(&a_fun.name, &inputs);

assert_eq!(selector, [0, 0, 0, 0, 39, 152, 108, 146,]);

v0.25.1

04 Oct 16:33
1eb8bcc
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.25.0...v0.25.1

v0.25.0

03 Oct 21:44
2ce1ceb
Compare
Choose a tag to compare

What's Changed

Full Changelog: v0.24.0...v0.25.0

New features

Logs and events parsing

The SDK can now parse logs and events with all types (including custom types), as opposed to only binary data.

We’ve introduced two ways to get these typed logs/events:

First, with type-specific log fetching, contract_instance.logs_with_type::<T>:

setup_contract_test!(
    contract_instance,
    wallet,
    "packages/fuels/tests/test_projects/logged_types"
);

let contract_methods = contract_instance.methods();
let response = contract_methods.produce_logs_values().call().await?;

let log_u64 = contract_instance.logs_with_type::<u64>(&response.receipts)?;
let log_u32 = contract_instance.logs_with_type::<u32>(&response.receipts)?;
let log_u16 = contract_instance.logs_with_type::<u16>(&response.receipts)?;
let log_u8 = contract_instance.logs_with_type::<u8>(&response.receipts)?;

This way, you’ll retrieve all logs that happened in that contract_instance that match the type <T>.

Second, if you want to retrieve all logs, in a stringified way, you can use fetch_logs():

let contract_methods = contract_instance.methods();
let response = contract_methods.produce_multiple_logs().call().await?;
let logs = contract_instance.fetch_logs(&response.receipts);

Vec support (input only)

The long waited Vec support is finally here, partially at least. You can now pass Vec to ABI methods that take dynamically-sized vectors. For instance:

let methods = contract_instance.methods();
{
    // vec of u32s
    let arg = vec![0, 1, 2];
    methods.u32_vec(arg).call().await?;
}
{
    // vec of vecs of u32s
    let arg = vec![vec![0, 1, 2], vec![0, 1, 2]];
    methods.vec_in_vec(arg.clone()).call().await?;
}
{
    // vec of structs
    let arg = vec![SomeStruct { a: 0 }, SomeStruct { a: 1 }];
    methods.struct_in_vec(arg.clone()).call().await?;
}

However, we don’t yet support Vec as return values; this will be coming up very soon!

New script crafting interface

Manually creating scripts just became a bit easier with the new API for crafting scripts:

ScriptBuilder::new()
        .set_gas_price(tx_parameters.gas_price)
        .set_gas_limit(tx_parameters.gas_limit)
        .set_maturity(tx_parameters.maturity)
        .set_script(script)
        .set_script_data(script_data)
        .set_inputs(inputs.to_vec())
        .set_outputs(outputs.to_vec())
        .set_amount(amount)
        .build(&wallet)
        .await?
        .call(wallet.get_provider()?)
        .await?;

Support for script’s main arguments are coming up soon.

Breaking changes

The new methods() interface

TLDR:

  1. Remove .build() from your contract instantiation statement (MyContractBuilder::new(…).build()MyContractBuilder::new(...))
  2. Chain .methods() before accessing the desired method from your contract (contract_instance.my_method().call()contract_instance.methods().my_method().call())

Longer explanation motivation behind this change:

Before this release, users relied on the builder .build() method when constructing a new contract instance. For instance:

let contract_instance = MyContractBuilder::new(contract_id.to_string(), wallet).build();

Access to contract_instance methods was done directly:

let transaction_cost = contract_instance
            .initialize_counter(42)
            .call()
            .await?;

This was causing one big problem: conflict between ABI methods and contract instance specific methods generated by the SDK (_get_wallet(), _get_contract_id(), and so on.)

Notice how, to mitigate the issue, the SDK was prepending _ before the method name, but this isn’t sustainable for too long.

To resolve this problem, we’ve removed the need to chain .build() when creating a contract instance, and now, when accessing ABI methods, you must chain .methods() to access all the ABI methods. To get SDK generated methods bound to the contract instance, you can do it directly. For instance:

abigen!(
        SimpleContract,
        "packages/fuels/tests/takes_ints_returns_bool-abi.json",
    );

    let wallet = launch_provider_and_get_wallet().await;

    // `SimpleContract` is the name of the contract.
    // No more `.build()` here.
    let contract_instance = SimpleContract::new(null_contract_id(), wallet);
	
		// `.methods()` before accessing the actual method. The rest
    // follows as usual.
    let call_handler = contract_instance.methods().takes_ints_returns_bool(42);

v0.24.0

19 Sep 21:21
a4c899a
Compare
Choose a tag to compare

What's Changed

  • feat(test-helpers): warn if multiple fuel-core binaries are detected in PATH by @Br1ght0ne in #558
  • feat!: Add messages support by @Salka1988 in #555
  • Make gas_forwarded use gas_limit as default by @MujkicA in #571
  • feat: Implement generic support by @segfault-magnet in #573
  • Replace script_with_data_offset! with GTF instructions by @Salka1988 in #575
  • refactor: expose the default derivation path to downstream crates by @kayagokalp in #578
  • feat: add options and results support by @hal3e in #574
  • docs: update docs related to the changes introduced by generics by @digorithm in #580
  • feat: add setup_contract_test proc macro by @hal3e in #566
  • Bump versions to 0.24.0 by @digorithm in #581

New Contributors

Full Changelog: v0.23.0...v0.24.0

New features

Generics

We now offer full support to generic structs and enums. Nothing special needs to be done to make this work. Generic parameters are reflected identically from the generic parameters in your Sway code. E.g., struct Person<T> in your Sway code will be struct Person<T> in your Rust code.

Option and Result

Option and Result have full support now. The Option<T>s and Result<T, E>s, along with their generic parameters, in your Sway code will be identical in your Rust code. The generated Rust code uses the actual Rust's Option and Result.

InputMessage

As part of the initial support for the upcoming bridges, you can now use Messages to pay for transactions. Check out the official documentation on this for more details.

setup_contract_test

Setting up the test infrastructure for your tests has become a lot easier; instead of having to instantiate test wallets and nodes and deploy your contract binaries to the test node every time, all you have to do for simple use cases is this:

#[tokio::test]
async fn simple_test() -> Result<(), Error> {
    setup_contract_test!(
        contract_instance,
        wallet,
        "packages/fuels/tests/test_projects/contract_test"
    );

    let response = contract_instance
        .initialize_counter(42)
        .call()
        .await?;

    assert_eq!(42, response.value);
    Ok(())
}