## File: README.md

# fuels-rs

[](https://github.com/FuelLabs/fuels-rs/actions/workflows/ci.yml)
[](https://crates.io/crates/fuels)
[](https://docs.rs/fuels)
[](https://discord.gg/xfpK4Pe)

Rust SDK for Fuel. It can be used for a variety of things, including but not limited to:

- Compiling, deploying, and testing [Sway](https://github.com/FuelLabs/sway) contracts;
- Launching a local Fuel network;
- Crafting and signing transactions with hand-crafted scripts or contract calls;
- Generating type-safe Rust bindings of contract methods;
- And more, `fuels-rs` is still in active development.

## Documentation

See [the `fuels-rs` book](https://fuellabs.github.io/fuels-rs/latest/)

## Features

- [x] Launch Fuel nodes
- [x] Deploy contracts
- [x] Interact with deployed contracts
- [x] Type-safe Sway contracts bindings code generation
- [x] Run Sway scripts
- [x] CLI for common operations
- [x] Local test wallets
- [ ] Wallet integration
- [ ] Events querying/monitoring

## FAQ

### What dependencies do I need?

- [The latest `stable` Rust toolchain](https://docs.fuel.network/guides/installation/#installing-rust);
- [`forc` and `fuel-core` binaries](https://docs.fuel.network/guides/installation/#installing-the-fuel-toolchain-using-fuelup).

### How can I run the SDK tests?

First, build the test projects using `forc`:

```shell
forc build --release --path e2e
```

Then you can run the SDK tests with:

```shell
cargo test
```

You can also run specific tests. The following example will run all integration tests in `types.rs` whose names contain `in_vector` and show their outputs:

```shell
cargo test --test types in_vector -- --show-output
```

### How to run WASM tests?

You need to have wasm32 as a target, if you don't already:

```shell
 rustup target add wasm32-unknown-unknown
```

You also need `wasm-pack`, if you don't already:

```shell
cargo install wasm-pack
```

Navigate to `packages/wasm-tests` and run `wasm-pack test`.

### What to do if my tests are failing on `master`

Before doing anything else, try all these commands:

```shell
cargo clean
rm Cargo.lock
forc build --release --path e2e
cargo test
```

### Why is the prefix `fuels` and not `fuel`?

In order to make the SDK for Fuel feel familiar with those coming from the [ethers.js](https://github.com/ethers-io/ethers.js) ecosystem, this project opted for an `s` at the end. The `fuels-*` family of SDKs is inspired by The Ethers Project.

### How can I run the docs locally?

Install `mdbook` by running:

```shell
cargo install mdbook
```

Next, navigate to the `docs` folder and run the command below to start a local server and open a new tab in your browser.

```shell
mdbook serve --open
```

You can build the book by running:

```shell
mdbook build
```

---

## File: docs/src/abigen/index.md

# Generating bindings with abigen

You might have noticed this snippet in the previous sections:

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:abigen_example}}
```



The SDK lets you transform ABI methods of a smart contract, specified as JSON objects (which you can get from [Forc](https://github.com/FuelLabs/sway/tree/master/forc)), into Rust structs and methods that are type-checked at compile time.
In order to call your contracts, scripts or predicates, you first need to generate the Rust bindings for them.


The following subsections contain more details about the `abigen!` syntax and the code generated from it.

---

## File: docs/src/abigen/the-abigen-macro.md

# abigen



`abigen!` is a procedural macro -- it generates code. It accepts inputs in the format of:

```text
ProgramType(name="MyProgramType", abi="my_program-abi.json")...
```

where:

- `ProgramType` is one of: `Contract`, `Script` or `Predicate`,

- `name` is the name that will be given to the generated bindings,

- `abi` is either a path to the JSON ABI file or its actual contents.


---
So, an `abigen!` which generates bindings for two contracts and one script looks like this:

```rust,ignore
{{#include ../../../examples/macros/src/lib.rs:multiple_abigen_program_types}}
```

## How does the generated code look?

A rough overview:

```rust,ignore
pub mod abigen_bindings {
    pub mod contract_a_mod {
        struct SomeCustomStruct{/*...*/};
        // other custom types used in the contract

        struct ContractA {/*...*/};
        impl ContractA {/*...*/};
        // ...
    }
    pub mod contract_b_mod {
        // ...
    }
    pub mod my_script_mod {
        // ...
    }
    pub mod my_predicate_mod{
        // ...
    }
    pub mod shared_types{
        // ...
    }
}

pub use contract_a_mod::{/*..*/};
pub use contract_b_mod::{/*..*/};
pub use my_predicate_mod::{/*..*/};
pub use shared_types::{/*..*/};
```

Each `ProgramType` gets its own `mod` based on the `name` given in the `abigen!`. Inside the respective mods, the custom types used by that program are generated, and the bindings through which the actual calls can be made.

One extra `mod` called `shared_types` is generated if `abigen!` detects that the given programs share types. Instead of each `mod` regenerating the type for itself, the type is lifted out into the `shared_types` module, generated only once, and then shared between all program bindings that use it. Reexports are added to each mod so that even if a type is deemed shared, you can still access it as though each `mod` had generated the type for itself (i.e. `my_contract_mod::SharedType`).

A type is deemed shared if its name and definition match up. This can happen either because you've used the same library (a custom one or a type from the `stdlib`) or because you've happened to define the exact same type.

Finally, `pub use` statements are inserted, so you don't have to fully qualify the generated types. To avoid conflict, only types that have unique names will get a `pub use` statement. If you find `rustc` can't find your type, it might just be that there is another generated type with the same name. To fix the issue just qualify the path by doing `abigen_bindings::whatever_contract_mod::TheType`.

> **Note:**
> It is **highly** encouraged that you generate all your bindings in one `abigen!` call. Doing it in this manner will allow type sharing and avoid name collisions you'd normally get when calling `abigen!` multiple times inside the same namespace. If you choose to proceed otherwise, keep in mind the generated code overview presented above and appropriately separate the `abigen!` calls into different modules to resolve the collision.

## Using the bindings

Let's look at a contract with two methods: `initialize_counter(arg: u64) -> u64` and `increment_counter(arg: u64) -> u64`, with the following JSON ABI:

```json,ignore
{{#include ../../../examples/rust_bindings/src/abi.json}}
```

By doing this:

```rust,ignore
{{#include ../../../examples/rust_bindings/src/lib.rs:use_abigen}}
```

or this:

```rust,ignore
{{#include ../../../examples/rust_bindings/src/lib.rs:abigen_with_string}}
```

you'll generate this (shortened for brevity's sake):

```rust,ignore
{{#include ../../../examples/rust_bindings/src/rust_bindings_formatted.rs}}
```

> **Note:** that is all **generated** code. No need to write any of that. Ever. The generated code might look different from one version to another, this is just an example to give you an idea of what it looks like.

Then, you're able to use it to call the actual methods on the deployed contract:

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:use_deployed_contract}}
```

---

## File: docs/src/abigen/the-json-abi-file.md

# The JSON ABI file



Whether you want to deploy or connect to a pre-existing smart contract, the JSON ABI file is extremely important: it's what tells the SDK about the [ABI methods](https://docs.fuel.network/guides/quickstart/building-a-smart-contract/#abi) in your smart contracts.


For the same example Sway code as above:

```Rust
contract;

abi MyContract {
    fn test_function() -> bool;
}

impl MyContract for Contract {
    fn test_function() -> bool {
        true
    }
}
```

The JSON ABI file looks like this:

```json
$ cat out/release/my-test-abi.json
[
  {
    "type": "function",
    "inputs": [],
    "name": "test_function",
    "outputs": [
      {
        "name": "",
        "type": "bool",
        "components": null
      }
    ]
  }
]
```

The Fuel Rust SDK will take this file as input and generate equivalent methods (and custom types if applicable) that you can call from your Rust code.

---

## File: docs/src/calling-contracts/call-params.md

# Call parameters



The parameters for a contract call are:

1. Amount
2. Asset ID
3. Gas forwarded


You can use these to forward coins to a contract. You can configure these parameters by creating an instance of [`CallParameters`](https://docs.rs/fuels/latest/fuels/programs/calls/struct.CallParameters.html) and passing it to a chain method called `call_params`.


For instance, suppose the following contract that uses Sway's `msg_amount()` to return the amount sent in that transaction.

```rust,ignore
{{#include ../../../e2e/sway/contracts/contract_test/src/main.sw:msg_amount}}
```

Then, in Rust, after setting up and deploying the above contract, you can configure the amount being sent in the transaction like this:

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:call_parameters}}
```



`call_params` returns a result to ensure you don't forward assets to a contract method that isn't payable.

In the following example, we try to forward an amount of `100` of the base asset to `non_payable`. As its name suggests, `non_payable` isn't annotated with `#[payable]` in the contract code. Passing `CallParameters` with an amount other than `0` leads to an error:

```rust,ignore
{{#include ../../../e2e/tests/contracts.rs:non_payable_params}}
```

> **Note:** forwarding gas to a contract call is always possible, regardless of the contract method being non-payable.

You can also use `CallParameters::default()` to use the default values:

```rust,ignore
{{#include ../../../packages/fuels-core/src/utils/constants.rs:default_call_parameters}}
```

This way:

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:call_parameters_default}}
```



The `gas_forwarded` parameter defines the limit for the actual contract call as opposed to the gas limit for the whole transaction. This means that it is constrained by the transaction limit. If it is set to an amount greater than the available gas, all available gas will be forwarded.


```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:call_params_gas}}
```



If you don't set the call parameters or use `CallParameters::default()`, the transaction gas limit will be forwarded instead.

---

## File: docs/src/calling-contracts/call-response.md

# Call response



You've probably noticed that you're often chaining `.call().await.unwrap()`. That's because:

1. You have to choose between `.call()` and `.simulate()` (more on this in the next section).
2. Contract calls are asynchronous, so you can choose to either `.await` it or perform concurrent tasks, making full use of Rust's async.
3. `.unwrap()` the `Result<CallResponse, Error>` returned by the contract call.




Once you unwrap the `CallResponse`, you have access to this struct:


```rust,ignore
{{#include ../../../packages/fuels-programs/src/responses/call.rs:call_response}}
```



Where `value` will hold the value returned by its respective contract method, represented by the exact type returned by the FuelVM, E.g., if your contract returns a FuelVM's `u64`, `value`'s `D` will be a `u64`. If it's a FuelVM's tuple `(u8,bool)`, then `D` will be a `(u8,bool)`. If it's a custom type, for instance, a Sway struct `MyStruct` containing two components, a `u64`, and a `b256`, `D` will be a struct generated at compile-time, called `MyStruct` with `u64` and a `[u8; 32]` (the equivalent of `b256` in Rust).

- `receipts` will hold all [receipts](https://docs.fuel.network/docs/specs/abi/receipts/) generated by that specific contract call.
- `gas_used` is the amount of gas consumed by the contract call.
- `tx_id` will hold the ID of the corresponding submitted transaction.


## Error handling



You can use the `is_ok` and `is_err` methods to check if a contract call `Result` is `Ok` or contains an error. These methods will return either `true` or `false`.




```rust, ignore
let is_ok = response.is_ok();
let is_error = response.is_err();
```




If `is_err` returns `true`, you can use the `unwrap_err` method to unwrap the error message.




```rust, ignore
if response.is_err() {
    let err = response.unwrap_err();
    println!("ERROR: {:?}", err);
};
```

---

## File: docs/src/calling-contracts/calls-with-different-wallets.md

# Calls with different wallets



You can use the `with_account()` method on an existing contract instance as a shorthand for creating a new instance connected to the provided wallet. This lets you make contracts calls with different wallets in a chain like fashion.


```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:connect_wallet}}
```

> **Note:** connecting a different wallet to an existing instance ignores its set provider in favor of the provider used to deploy the contract. If you have two wallets connected to separate providers (each communicating with a separate fuel-core), the one assigned to the deploying wallet will also be used for contract calls. This behavior is only relevant if multiple providers (i.e. fuel-core instances) are present and can otherwise be ignored.

---

## File: docs/src/calling-contracts/cost-estimation.md

# Estimating contract call cost

With the function `estimate_transaction_cost(tolerance: Option<f64>, block_horizon: Option)` provided by `CallHandler`, you can get a cost estimation for a specific call. The return type, `TransactionCost`, is a struct that contains relevant information for the estimation:

```rust,ignore
{{#include ../../../packages/fuels-accounts/src/provider.rs:transaction_cost}}
```

> **Note** `script_gas` refers to the part of the gas spent on the script execution.

Below are examples that show how to get the estimated transaction cost from single and multi call transactions.

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:contract_call_cost_estimation}}
```

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:multi_call_cost_estimation}}
```

The transaction cost estimation can be used to set the gas limit for an actual call, or to show the user the estimated cost.

> **Note** The same estimation interface is available for scripts.

---

## File: docs/src/calling-contracts/custom-asset-transfer.md

# Custom asset transfer



The SDK provides the option to transfer assets within the same transaction, when making a contract call. By using `add_custom_asset()` you specify the asset ID, the amount, and the destination address:


```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:add_custom_assets}}
```

---

## File: docs/src/calling-contracts/custom-inputs-outputs.md

# Custom inputs and outputs

If you need to add specific inputs and outputs to contract calls, you can use the `with_inputs` and `with_outputs` methods.

```rust,ignore
{{#include ../../../examples/contracts/src/lib.rs:add_custom_inputs_outputs}}
```

> **Note:** if custom inputs include coins that need to be signed, use the `add_signer` method to add the appropriate signer.