feat!: prettify `typegen` api
- Closes #2686
- Closes #2707
Release notes
In this release, we:
- Made
typegend API more straightforward and ergonomic
Summary
Parts of our great experience are shipped through the RTypegend files, which contain part of the boilerplate necessary to make some things work. This PR revisits these templates and trims them nicely to support a more ergonomic and intuitive API.
All main Typegen templates have changed:
-
Contract -
ContractFactory⁽¹⁾ -
Script -
Predicate
⁽¹⁾ Contract
bytecodelives inside theFactoryclass now, no more.hex.tsfiles
To follow these changes, we also modified:
-
launchTestNodeutility -
Predicateclass
Special thanks ❤️
Goes to @petertonysmith94, for the rigorous reviews and additional API prettification via:
- https://github.com/FuelLabs/fuels-ts/pull/2876.
Also, thank you to @nedsalk for all the involvement and for not letting this fade out on the side during such an agitated moment. Releasing this will undoubtedly pave the way for other good things to happen!
Breaking Changes
Predicate class
-
Predicateclass 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
Predicatenow 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[].deployertocontractsConfigs[].factory - Removed
contractsConfigs[].bytecodeand.hex.tsfile
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();
Typegend Contract template
- Removed
Abi__factorysuffix from class names - The file
<name>.hexwas removed (access it via<Name>.bytecode) - The files
<name>__factory.tsand<name>.d.dtswere merged into<name>.ts - The class
<Name>and the interface<Name>Abiare now just<Name>
// before
import { TestContractAbi, TestContract__factory } from './typegen'
import testContractBytecode from './typegen/contracts/TestContract.hex'
const instance: TestContractAbi = 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();
Typegend Predicate template
- Removed
Abi__factorysuffix from class names - Started accepting a single param object in constructor
// before
import { TestPredicateAbi__factory } from './typegen'
const predicate = TestPredicateAbi__factory.createInstance(provider);
// after
import { TestPredicate } from './typegen'
const predicate = new TestPredicate({ provider });
Typegend Script template
- Removed
Abi__factorysuffix from class names
// before
import { TestPredicateAbi__factory } from './typegen'
const script = TestScriptAbi__factory.createInstance(wallet);
// after
import { TestPredicate } from './typegen'
const script = new TestScript(wallet);
Checklist
- [x] I added —
teststo prove my changes - [x] I updated — all the necessary
docs - [x] I reviewed — the entire PR myself, using the GitHub UI
- [x] I described — all breaking changes and the Migration Guide
Outlining the foundation and current state of each template.
- In the breaking changes section, the typegend
Predicatebefore and after are usingwalletwhereas they should be usingprovider:
// before
const predicate = TestPredicateAbi__factory.createInstance(wallet);
// should be
const predicate = TestPredicateAbi__factory.createInstance(provider);
// after
const predicate = new TestPredicate({ wallet });
// should be
const predicate = new TestPredicate({ provider });
- In the
Scriptexample in the "after" section, the typegend script takes in awalletargument but it's part of an object{ wallet }whereas it should be used directly:
// after
const script = new TestScript({ wallet });
// should be
const script = new TestScript(wallet);
Coverage Report:
| Lines | Branches | Functions | Statements |
|---|---|---|---|
| 79.51%(+0%) | 71.75%(-0.05%) | 77.49%(+0.01%) | 79.65%(+0%) |
Changed Files:
| Ok | File (✨=New File) | Lines | Branches | Functions | Statements |
|---|---|---|---|---|---|
| ✅ | ✨ packages/abi-typegen/src/templates/contract/main.ts | 100% (+100%) |
100% (+100%) |
100% (+100%) |
100% (+100%) |
| ✅ | ✨ packages/abi-typegen/src/templates/predicate/main.ts | 100% (+100%) |
100% (+100%) |
100% (+100%) |
100% (+100%) |
| ✅ | ✨ packages/abi-typegen/src/templates/script/main.ts | 100% (+100%) |
100% (+100%) |
100% (+100%) |
100% (+100%) |
| 🔴 | packages/abi-typegen/src/templates/utils/formatEnums.ts | 100% (+0%) |
50% (-50%) |
100% (+0%) |
100% (+0%) |
| 🔴 | packages/abi-typegen/src/templates/utils/formatStructs.ts | 100% (+0%) |
50% (-50%) |
100% (+0%) |
100% (+0%) |
@arboleya after this change, whenever I rebuild locally, the old factories remain in place:
contracts/factories/TestContractAbi__factory.ts
Then I have experienced type errors:
template-nextjs:build: Type error: Property 'deployContract' does not exist on type 'ContractFactory'.
template-nextjs:build:
template-nextjs:build: 102 | const factory = new ContractFactory(bytecode, _abi, wallet);
template-nextjs:build: 103 |
template-nextjs:build: > 104 | return factory.deployContract<TestContractAbi>({
template-nextjs:build: | ^
template-nextjs:build: 105 | storageSlots: _storageSlots,
template-nextjs:build: 106 | ...options,
template-nextjs:build: 107 | });
May it be worth deleting the typegen folder before a typegen build?
@petertonysmith94 Deleting things is always very dangerous.
However, these old files should not be a problem if they're just there and never imported.
The error you pasted looks valid, no? The deployContract method was renamed to deploy.
@arboleya You're right - deleting does seem dangerous.
The error is valid and will cause issues if consumers have TS checking across their project.
Maybe we could add an advisory in the release notes that this factory folder should be deleted?
Oh, this is a very specific tip.
Would you mind editing the PR description and adding this mention?
It will be re-fetched and used in the changelog before the next release.