@hyunggyujang/typechain-polkadot v0.6.10
Typechain-polkadot
Package for generating TypeScript definitions & runtime code for Polkadot smart contracts.
Usage
In your project install this package:
npm i -D @727-ventures/typechain-polkadotNow you can use it to generate TS definitions & runtime code for Polkadot smart contracts. To use typechain-polkadot.
Note, that ink! contracts generate two files:
metadata.jsonand<contract-name>.contract. You need to provide both of them to typechain-polkadot, and renamemetadata.jsonto<contract-name>.json.
Typechain can be used in two ways:
- As a CLI tool
- As a library
CLI tool
After installing the package, you can use it as a CLI tool. To use it, run the following command:
npx @727-ventures/typechain-polkadot --input path/to/abis --output path/to/outputMethods and namespaces used in the typechain, and their description
build-extrinsic
In this namespace you can find all the functions that are related to building extrinsics.
const tx = contract.buildExtrinsic.<methodName>(...args, options);
tx.signAndSend(account, (result) => {
	// Handle result
});constructors
Used to deploy contracts, using different constructors.
Let's deploy the following contract:
#![cfg_attr(not(feature = "std"), no_std)]
#![feature(min_specialization)]
#[openbrush::contract]
pub mod my_psp22 {
    // imports from openbrush
	use openbrush::contracts::psp22::*;
	use openbrush::traits::Storage;
    #[ink(storage)]
    #[derive(Default, Storage)]
    pub struct Contract {
    	#[storage_field]
		psp22: psp22::Data,
    }
    // Section contains default implementation without any modifications
	impl PSP22 for Contract {}
    impl Contract {
        #[ink(constructor)]
        pub fn new(initial_supply: Balance) -> Self {
            let mut _instance = Self::default();
			_instance._mint_to(_instance.env().caller(), initial_supply).expect("Should mint");
			_instance
        }
    }
}This contract has a constructor new with one argument initial_supply.
To deploy this contract, you need to use the following code:
// Import here Constructors and Contract classes
// Here we are creating an instance of the Constructors class, which is used to deploy contracts,
// Constructors is typechain-generated class that contains all the constructors of the contract
const factory = new Constructors(api, UserAlice);
// You can access to the different constructors using the name of the constructor, here we will use "new"
const {result, address} = await factory.new('10', {});
// Here we are creating an instance of the Contract class, which is used to interact with the deployed contract
contract = new Contract(address, UserAlice, api);contract
Contract is the main namespace for interacting with contracts. It contains all the functions that are related to contracts.
const contract = new Contract(
		address,
		signer,
		nativeAPI,
)
contract.name() // get the name of the contract
contract.address() // get the address of the contract
contract.abi() // get the abi of the contract
contract.<namespace>.<functionName>(...args, options) // call a function from a namespace
// namespace can be tx, query, events, etc.
contract.withSigner(signer)
// change the signer of the contract in the current context,
// basically it will create a new contract with the new signer
contract.withAddress(address)
// change the address of the contract in the current context,
// basically it will create a new contract with the new address
// useful for proxy contracts
contract.withAPI(api)
// change the api of the contract in the current context
// basically it will create a new contract with the new apidata
Utility file. Contains all info about types. It's used in runtime to parse return values from contracts.
mixed-methods
This namespace contains both tx and query methods.
contract.mixedMethods.<functionName>(...args, options)query
This namepsace contains all query methods
const result = contract.query.<functionName>(...args, options)
console.log(result.value)You can also use it to get errors from contracts
try {
	await contract.withSigner(UserBob).query.transfer(UserAlice.address, '10', []);
} catch ({ _err }) {
	console.log(_err);
}console.log
	{ insufficientBalance: null }tx-sign-and-send
This namespace is used send transactions.
const result = await contract.tx.<functionName>(...args, options)Library
You can also use typechain-polkadot as a library. To use it, you need to import it in your code:
import {Typechain} from '@727-ventures/typechain-polkadot/src/types/typechain';
import {testPathPatternToRegExp} from "jest-util";
const typechain = new Typechain();
typechain.loadDefaultPlugins();
typechain.run(
	pathToInput,
	pathToOutput
)Plugins
Typechain-polkadot uses plugins to generate code. By default, it uses the following plugins:
- build-extrinsic docs
- constructors docs
- contract docs
- data docs
- events docs
- events-types docs
- mixed-methods docs
- query docs
- tx-sign-and-send docs
You can also create your own plugins to add some custom logic to the typechain-polkadot. To do this, you need to create a class that implements the TypechainPlugin interface:
import {TypechainPlugin} from '@727-ventures/typechain-polkadot/src/types/interfaces';
import {Abi} from "@polkadot/api-contract";
/**
 * generates a contract file
 *
 * @param abi - The ABI of the contract
 * @param fileName - The name of the file to write to
 * @param absPathToOutput - The absolute path to the output directory
 * @param absPathToABIs - The absolute path to the ABIs directory
 */
function generate(abi: Abi, fileName: string, absPathToOutput: string, absPathToABIs: string) {
	console.log('Hello World!');
}
export default class HelloWorldPlugin implements TypechainPlugin {
	name: string = 'HelloWorld';
	outputDir: string = 'HelloWorld';
	generate(abi: Abi, fileName: string, absPathToABIs: string, absPathToOutput: string): void {
		generate(abi, fileName, absPathToOutput, absPathToABIs);
	}
}Then you need to add your plugin to the list of plugins:
typechain.loadPlugins(new MyPlugin());Or you can load them via cli:
npx @727-ventures/typechain-polkadot --input path/to/abis --output path/to/output --plugins ./plugins-directoryNote: if you're using the cli, every plugin should end with
.plugin.tsand have default export of the plugin itself.
Also you can use loadPluginsFromFiles method to load plugins from files:
typechain.loadPluginsFromFiles(
	'./plugins-directory'
)Example of plugins usage
You can find an example of plugins usage in the examples directory.
3 years ago