v0.94.0
Summary
In this release, we:
- Cached
Message
resources upon transaction submission - Made
typegen
API more straightforward and ergonomic - Reduced required roundtrips & bandwidth for submitting TXs
- Made
ContractFactory.deployAsBlobTx
a non-blocking call - Upgraded
forc
to v0.63.0 & v0.63.1 - Added support for the new ABI spec (#596, #599)
- Improved the bytecode compression for Typegen, making files 40%+ smaller
- Improved the type handling for
()
andOption<T>
types - Upgraded
fuel-core
to v0.32.1 - Implemented deploying large contracts using blob transactions
- Fixed
forc
andfuel-core
version reporting on typegen-generated files - Fixed
getInputFromAssetId
so it returns the correctInputCoin
andInputMessage
- Upgraded
fuel-core
to v0.33.0 - Added
createAssetId
function to create a nativeAssetId
type - Added validation for max. input limit exceeded, as per the consensus parameters
- Removed
FUEL_NETWORK_URL
andLOCAL_NETWORK_URL
constants - Removed
generateTestWallet
,seedTestWallet
andlaunchNodeAndGetWallets
utilities - Renamed testing class
AssetId
toTestAssetId
Breaking
- Features
- #2872 - Consider message on resources cache, by @Torres-ssf
- #2824 - Prettify
typegen
api, by @arboleya - #2962 - Read malleable fields from transaction status on subscription, by @nedsalk
- #2929 - Non-blocking blob deployment, by @danielbate
- #2856 - Adding
abi
transpiler, by @arboleya - #2777 - Improve
()
andOption<T>
type handling, by @petertonysmith94 - #2827 -
[email protected]
and large contract deployments, by @danielbate
- Fixes
- #2963 - Assembly process for account transfer operation, by @Torres-ssf
- Chores
- #2915 - Deprecate
FUEL_NETWORK_URL
andLOCAL_NETWORK_URL
, by @petertonysmith94 - #2811 - Integrate
launchTestNode
in remaining packages, by @maschad - #2964 - Wrap subscriptions in promise, by @nedsalk
- #2905 - Renamed
AssetId
toTestAssetId
, by @petertonysmith94
- #2915 - Deprecate
Features
- #2897 - Improve typegen bytecode compression, by @Dhaiwat10
- #2903 - Add randomUUID into
fuel-ts/crypto
, by @Torres-ssf
Fixes
- #2888 - Typegen reporting the correct versions, by @petertonysmith94
- #2982 - Avoid re-add fake resources at
Account.getTransactionCost
, by @Torres-ssf - #2896 - Transaction revert error, by @petertonysmith94
- #2981 - Gas price estimation test flakiness, by @nedsalk
- #2926 -
Account.createTransfer
return type, by @Torres-ssf - #2859 - Typegen generic configurables, by @nedsalk
- #2782 - Return correct operations from coin and message inputs, by @maschad
Chores
- #2839 - Refactor helpers related to transaction operations, by @maschad
- #2978 - Upgrade
[email protected]
, by @danielbate - #2665 - Implement a helper createAssetId function, by @bolajahmad
- #2822 - Handle exceeding maximum inputs when funding a transaction, by @mvares
- #2925 - Improve node incompatibility warning, by @Torres-ssf
- #2891 - Default TestMessage to be spendable, by @Torres-ssf
- #2883 - Dependencies version consistency, by @petertonysmith94
- #2879 - Switching
Error
toFuelError
, by @petertonysmith94 - #2890 - Add missing reasons to
PANIC_REASONS
constant, by @Torres-ssf - #2899 - Add validation for TX max outputs exceeded, by @Torres-ssf
- #2851 - Add infra to support multiple
create fuels
templates, by @Dhaiwat10
Migration Notes
Features
#2872 - Consider message on resources cache
The provider option flag cacheUtxo
was renamed to resourceCacheTTL
// before
const provider = await Provider.create(FUEL_NETWORK_URL, {
cacheUtxo: 5000,
});
using launched = await launchTestNode({
providerOptions: {
cacheUtxo: 5000,
},
});
// after
const provider = await Provider.create(FUEL_NETWORK_URL, {
resourceCacheTTL: 5000,
});
using launched = await launchTestNode({
providerOptions: {
resourceCacheTTL: 5000,
},
});
#2824 - Prettify typegen
api
Predicate
class
Predicate
class constructor parameters renamed:inputData
>data
// before
import { Predicate } from 'fuels';
const predicate = new Predicate({
...unchangedParameters,
inputData,
});
// after
import { Predicate } from 'fuels';
const predicate = new Predicate({
...unchangedParameters,
data,
});
- Typegen extended/generated
Predicate
now accepts a single parameter for initialization
// before
import { TestPredicateAbi__factory } from './typegend';
TestPredicateAbi__factory.createInstance(provider, data, configurableConstants);
// after
import { TestPredicate } from './typegen';
new TestPredicate({
provider,
data,
configurableConstants
});
launchTestNode
utility
- Renamed
contractsConfigs[].deployer
tocontractsConfigs[].factory
- Removed
contractsConfigs[].bytecode
and.hex.ts
file
The bytecode is now saved within the factory class, so you don't have to deal with it.
// before
import { TokenAbi__factory } from './typegend';
import TokenAbiHex from './typegend/contracts/TokenAbi.hex';
using launched = await launchTestNode({
contractsConfigs: [{
deployer: TokenAbi__factory,
bytecode: TokenAbiHex
}],
});
// after
import { TokenFactory } from './typegend';
using launched = await launchTestNode({
contractsConfigs: [{
factory: TokenFactory,
}],
})
Renamed method deployContract
to deploy
Removed the redundant suffix on the ContractFactory
class method name.
// before
import { ContractFactory } from 'fuels';
const factory = new ContractFactory(wallet);
factory.deployContract();
// after
import { ContractFactory } from 'fuels';
const factory = new ContractFactory(wallet);
factory.deploy();
Typegen Contract
template
- Removed
Abi__factory
suffix from class names - The file
<name>.hex
was removed (access it via<Name>.bytecode
) - The files
<name>__factory.ts
and<name>.d.dts
were merged into<name>.ts
- The class
<Name>
and the interface<Name>Abi
are now just<Name>
- Method
<Name>Factory.deployContract()
renamed to<Name>Factory.deploy()
- You may need to remove the previously generated
<typegenDir>/contracts/factories
directory
// before
import { TestContractAbi, TestContract__factory } from './typegen'
import testContractBytecode from './typegen/contracts/TestContract.hex'
const instance = await TestContract__factory.connect(id, wallet);
const deploy = await TestContract__factory.deployContract(testContractBytecode, wallet);
const { contract } = await deploy.waitForResult();
// after
import { TestContract, TestContractFactory } from './typegen'
const instance = new TestContract(id, wallet);
const deploy = await TestContractFactory.deploy(wallet);
const { contract } = await deploy.waitForResult();
Typegen Predicate
template
- Removed
Abi__factory
suffix from class names - Started accepting a single param object in constructor
- You may need to remove the previously generated
<typegenDir>/predicates/factories
directory
// before
import { TestPredicateAbi__factory } from './typegen'
const predicate = TestPredicateAbi__factory.createInstance(provider);
// after
import { TestPredicate } from './typegen'
const predicate = new TestPredicate({ provider });
Typegen Script
template
- Removed
Abi__factory
suffix from class names - You may need to remove the previously generated
<typegenDir>/scripts/factories
directory
// before
import { TestPredicateAbi__factory } from './typegen'
const script = TestScriptAbi__factory.createInstance(wallet);
// after
import { TestPredicate } from './typegen'
const script = new TestScript(wallet);
#2962 - Read malleable fields from transaction status on subscription
Removed TransactionResult.gqlTransaction. You can use the TransactionResult.transaction
field and other fields on the response instead, which have all the data that TransactionResult.gqlTransaction
has.
// before
const { gqlTransaction } = await new TransactionResponse('your-tx-id').waitForResult();
// after
const { transaction, id, fee, ...rest } = await new TransactionResponse('your-tx-id').waitForResult();
#2929 - Non-blocking blob deployment
The transaction ID from a contract deployment is now returned as a promise.
// before
import { ContractFactory } from 'fuels';
const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, transactionId } = await factory.deploy();
console.log(transactionId); // 0x123....
// after
import { ContractFactory } from 'fuels';
const factory = new ContractFactory(bytecode, abi, wallet);
const { waitForResult, contractId, waitForTransactionId } = await factory.deploy();
const transactionId = await waitForTransactionId();
console.log(transactionId); // 0x123....
#2856 - Adding abi
transpiler
New ABI spec
The SDK now adheres to the new specs introduced via:
Check these out to understand all its changes.
AbiCoder
is no longer available to import
The class AbiCoder
is no longer exported, and the way to do encoding and decoding of specific types is now via the Interface.encodeType
and Interface.decodeType
methods:
// before
const abi = yourAbi;
const functionArg = abi.functions.inputs[0];
const encoded = AbiCoder.encode(abi, functionArg, valueToEncode);
const decoded = AbiCoder.decode(abi, functionArg, valueToDecode, 0);
// after
import { Interface } from 'fuels';
const abi = yourAbi;
const functionArg = abi.functions.inputs[0];
const abiInterface = new Interface(abi);
const encoded = abiInterface.encodeType(functionArg.concreteTypeId, valueToEncode);
const decoded = abiInterface.decodeType(functionArg.concreteTypeId, valueToDecode);
Interface.findTypeById
has been removed
Previously, you could get a type from the ABI via the Interface.findTypeById
. This method was removed after introducing the new abi specification because the concept of a type has been split into concrete and metadata types. If you want a specific type, you can get it directly from the ABI.
// before
const abiInterface = new Interface(abi);
// internally this method searched the abi types:
// abi.types.find(t => t.typeId === id);
const type = abiInterface.findTypeById(id);
// after
import { Interface } from 'fuels';
// search the types on the abi directly
const concreteType = abi.concreteTypes.find(ct => ct.concreteTypeId === id);
const metadataType = abiInterface.jsonAbi.metadataTypes.find(mt => mt.metadataTypeId === id);
JsonAbiArgument
is no longer exported
The JsonAbiArgument
type isn't part of the new ABI spec (#596, #599) as such so we stopped exporting it. Its closest equivalent now would be a concrete type because it fully defines a type.
// before
const arg: JsonAbiArgument = {...};
// after
import { Interface } from 'fuels';
type ConcreteType = JsonAbi["concreteTypes"][number]
const arg: ConcreteType = {...};
#2777 - Improve ()
and Option<T>
type handling
()
andOption<T>
Sway types are now either required or optional, dependent on where the argument appears in the function arguments.
Given these Sway functions:
fn type_then_void_then_type(x: u8, y: (), z: u8) -> ()
fn type_then_void_then_void(x: u8, y: (), z: ()) -> ()
fn type_then_option_then_type(x: u8, y: Option<u8>, z: u8) -> ()
fn type_then_option_then_option(x: u8, y: Option<u8>, z: Option<u8>) -> ()
This is what changes:
// before
contract.functions.type_then_void_then_type(42, 43)
contract.functions.type_then_void_then_void(42) // Unchanged
contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42, undefined, undefined)
// after
contract.functions.type_then_void_then_type(42, undefined, 43)
contract.functions.type_then_void_then_void(42) // Unchanged
contract.functions.type_then_option_then_type(42, undefined, 43)
contract.functions.type_then_option_then_option(42)
#2827 - [email protected]
and large contract deployments
MAX_CONTRACT_SIZE
is no longer exported, it should now be fetched from the chain.
// before
import { MAX_CONTRACT_SIZE } from 'fuels';
// after
import { Provider, FUEL_NETWORK_URL } from 'fuels';
const provider = await Provider.create(FUEL_NETWORK_URL);
const { consensusParameters } = provider.getChain();
const maxContractSize = consensusParameters.contractParameters.contractMaxSize.toNumber();
Fixes
#2963 - Assembly process for account transfer operation
The getTransferOperations
helper function now requires an additional baseAssetId parameter.
// before
const transferOperations = getTransferOperations({ inputs, outputs, receipts })
// after
const transferOperations = getTransferOperations({ inputs, outputs, receipts, baseAssetId })
Chores
#2915 - Deprecate FUEL_NETWORK_URL
and LOCAL_NETWORK_URL
Removed FUEL_NETWORK_URL
constant.
// before
import { FUEL_NETWORK_URL } from 'fuels';
const provider = await Provider.create(FUEL_NETWORK_URL);
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
Removed LOCAL_NETWORK_URL
constant.
// before
import { LOCAL_NETWORK_URL } from 'fuels';
const provider = await Provider.create(LOCAL_NETWORK_URL);
// after
const provider = await Provider.create('https://127.0.0.1:4000/v1/graphql');
#2811 - Integrate launchTestNode
in remaining packages
Removed generateTestWallet
and seedTestWallet
utilities.
// before
import { bn } from "@fuel-ts/math";
import {
seedTestWallet,
generateTestWallet,
} from "@fuel-ts/account/test-utils";
const provider = await Provider.create("http://127.0.0.1:4000/v1/graphql");
// seeding
const walletA = Wallet.fromPrivateKey("0x...", provider);
const baseAssetId = provider.getBaseAssetId();
seedTestWallet(wallet, [{ assetId: baseAssetId, amount: bn(100_000) }]);
// generating
const walletB = await generateTestWallet(provider, [[1_000, baseAssetId]]);
// after
import { launchTestNode } from 'fuels/test-utils';
// create two wallets seeded with 100_000 units of the base asset
using launched = await launchTestNode({
walletsConfig: {
count: 2,
amountPerCoin: 100_000,
},
});
const {
wallets: [walletA, walletB]
} = launched;
const balance = await walletA.getBalance() // 100_000
Removed launchNodeAndGetWallets
utility.
// before
import { launchNodeAndGetWallets } from 'fuels/test-utils';
const { provider, wallets } = await launchNodeAndGetWallets();
// after
import { launchTestNode } from 'fuels/test-utils';
using launched = await launchTestNode();
const { provider, wallets } = launched;
#2964 - Wrap subscriptions in promise
// before
const subscription = provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
const submittedTxSubscription = this.operations.submitAndAwait({ encodedTransaction: '0x' });
// after
const subscription = await provider.operations.statusChange({ transactionId });
for await (const response of subscription) { ... }
const submittedTxSubscription = await this.operations.submitAndAwait({ encodedTransaction: '0x' });
#2905 - Renamed AssetId
to TestAssetId
Renamed testing class AssetId
to TestAssetId
.
// before
import { AssetId } from 'fuels/test-utils';
const [assetA] = AssetId.random();
// after
import { TestAssetId } from 'fuels/test-utils';
const [assetA] = TestAssetId.random();