@cfxdevkit/contracts
Standard contract bindings (ERC-20/721/1155, multicall3) and a thin read/write/deploy surface for @cfxdevkit/cdk.
Install
pnpm
pnpm add @cfxdevkit/contractsStandard contract bindings (ERC-20 / 721 / 1155 / Multicall3) and a thin,
framework-native read / write / deploy surface for @cfxdevkit/cdk.
import { erc20 } from '@cfxdevkit/contracts/erc20';
import { createClient, http } from '@cfxdevkit/cdk';
import { espaceTestnet } from '@cfxdevkit/cdk/chains';
const client = createClient({ chain: espaceTestnet, transport: http() });
const symbol = await erc20.symbol({ client, address: '0xToken…' });Installation
npm install @cfxdevkit/contracts @cfxdevkit/cdkSub-paths
| Sub-path | Exports |
|---|---|
. | 23 symbols |
./abis | 5 symbols |
./read | 3 symbols |
./write | 6 symbols |
./deploy | 4 symbols |
./erc20 | 2 symbols |
./bridge | 10 symbols |
./errors | 2 symbols |
Usage
Read calls
Use readContract for view/pure functions:
import { readContract } from '@cfxdevkit/contracts';
import { ERC20_ABI } from '@cfxdevkit/contracts/abis';
const balance = await readContract({
client,
abi: ERC20_ABI,
address: '0xToken…',
functionName: 'balanceOf',
args: ['0xUser…'],
});Write calls
Use prepareWrite to construct a transaction, then sendWrite to submit it:
import { prepareWrite, sendWrite } from '@cfxdevkit/contracts';
import { ERC20_ABI } from '@cfxdevkit/contracts/abis';
const tx = await prepareWrite({
client,
abi: ERC20_ABI,
address: '0xToken…',
functionName: 'transfer',
args: ['0xUser…', 1000n],
});
const receipt = await sendWrite({ client, tx });Deploy
Deploy contracts using deployContract:
import { deployContract } from '@cfxdevkit/contracts';
const result = await deployContract({
client,
abi: myContractAbi,
bytecode: '0x...',
args: ['arg1', 42n],
});ERC-20 helpers
Convenience wrappers for common ERC-20 functions:
import { erc20 } from '@cfxdevkit/contracts/erc20';
const symbol = await erc20.symbol({ client, address: '0xToken…' });
const decimals = await erc20.decimals({ client, address: '0xToken…' });Bridge support
Bridge contract bindings and helpers are available under ./bridge:
import { bridge } from '@cfxdevkit/contracts/bridge';
// Example: get cross-space transfer status
const status = await bridge.getTransferStatus({ client, id: '0x...' });Error handling
All errors are typed under ContractsErrorCode and extend ContractsError:
import { ContractsError } from '@cfxdevkit/contracts';
try {
await readContract(...);
} catch (err) {
if (err instanceof ContractsError) {
console.error(err.code); // e.g., 'contracts/reverted'
}
}eSpace & Core Space
Fully compatible with both eSpace and Core Space chains. Specify your target chain via client.chain.
See API.md for the full surface and STRUCTURE.md for the layout.
Tier
Tier 0 — framework — Must not runtime-import from any higher tier.
API Reference
.
Usage
import { readContract, ERC20_ABI } from '@cfxdevkit/contracts';
const balance = await readContract({
abi: ERC20_ABI,
target: '0x...',
functionName: 'balanceOf',
args: ['0x...']
});// ABI for ERC-20 tokens
export { ERC20_ABI }
// ABI for ERC-721 tokens
export { ERC721_ABI }
// ABI for ERC-1155 tokens
export { ERC1155_ABI }
// ABI for Multicall3
export { MULTICALL3_ABI }
// The standard Multicall3 contract address
export { MULTICALL3_ADDRESS }
// Configuration for deploying a contract
export { DeployContractInput }
// Result of a contract deployment
export { DeployContractResult }
// Converts a value to a hex string
export { toHex }
// Interface for ERC-20 contract bindings
export { Erc20Bind }
// Factory function to create ERC-20 bindings
export { erc20 }
// Waits for a transaction receipt to be available
export { waitForReceipt }
// Deploys a new contract to the network
export declare function deployContract<TAbi extends Abi>(input: DeployContractInput<TAbi>): Promise<DeployContractResult>;
// Executes a read-only contract call
export declare function readContract<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'pure' | 'view'>>>(input: ReadContractInput<TAbi, TName>): Promise<ReturnType<typeof decodeFunctionResult<TAbi, TName>>>;
// Prepares a transaction for signing
export declare function prepareWrite<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>>>(input: PrepareWriteInput<TAbi, TName>): SignableTx;
// Sends a write transaction
export declare function sendWrite<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>>>(input: SendWriteInput<TAbi, TName>): Promise<SendWriteResult>;./abis
Usage
import { ERC20_ABI } from '@cfxdevkit/contracts/abis';// ABI for ERC-20 tokens
export { ERC20_ABI }
// ABI for ERC-721 tokens
export { ERC721_ABI }
// ABI for ERC-1155 tokens
export { ERC1155_ABI }
// ABI for Multicall3
export { MULTICALL3_ABI }
// The standard Multicall3 contract address
export { MULTICALL3_ADDRESS }./read
Usage
import { readContract, ReadContractInput } from '@cfxdevkit/contracts/read';
const val = await readContract({
abi: myAbi,
target: '0x...',
functionName: 'someViewFunction',
args: [123]
});// Tag for specifying block epoch
export type ReadEpochTag = Exclude<EpochTag, 'latest_confirmed'>;
// Input parameters for reading a contract
export interface ReadContractInput<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'pure' | 'view'>> {
// Executes a read-only contract call
export declare function readContract<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'pure' | 'view'>>>(input: ReadContractInput<TAbi, TName>): Promise<ReturnType<typeof decodeFunctionResult<TAbi, TName>>>;./write
Usage
import { prepareWrite, sendWrite } from '@cfxdevkit/contracts/write';
const tx = await prepareWrite({ abi, target, functionName, args });
const result = await sendWrite({ ...tx, chainId: 1 });// Waits for a transaction receipt to be available
export { waitForReceipt }
// Input parameters for preparing a write transaction
export interface PrepareWriteInput<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>> {
// Input parameters for sending a write transaction
export interface SendWriteInput<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>> extends Omit<PrepareWriteInput<TAbi, TName>, 'chainId' | 'family'> {
// Result of a write transaction
export interface SendWriteResult {
// Prepares a transaction for signing
export declare function prepareWrite<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>>>(input: PrepareWriteInput<TAbi, TName>): SignableTx;
// Sends a write transaction
export declare function sendWrite<TAbi extends Abi, TName extends ContractFunctionName<TAbi, 'nonpayable' | 'payable'>>>(input: SendWriteInput<TAbi, TName>): Promise<SendWriteResult>;./deploy
Usage
import { deployContract } from '@cfxdevkit/contracts/deploy';
const { address } = await deployContract({
abi: myAbi,
bytecode: '0x...'
});// Configuration for deploying a contract
export { DeployContractInput }
// Result of a contract deployment
export { DeployContractResult }
// Converts a value to a hex string
export { toHex }
// Deploys a new contract to the network
export declare function deployContract<TAbi extends Abi>(input: DeployContractInput<TAbi>): Promise<DeployContractResult>;./erc20
Usage
import { erc20 } from '@cfxdevkit/contracts/erc20';
const token = erc20({ address: '0x...', provider });
const balance = await token.balanceOf('0x...');// Interface for ERC-20 contract bindings
export interface Erc20Bind {
// Factory function to create ERC-20 bindings
export declare const erc20: {./bridge
Usage
import { transferToEspace } from '@cfxdevkit/contracts/bridge';
await transferToEspace({
target: '0x...',
amount: 100n,
// ... other options
});// ABI for cross-space calls
export { CROSS_SPACE_CALL_ABI }
// Hex representation of cross-space call
export { CROSS_SPACE_CALL_HEX }
// Maps a core address to an Espace address
export declare function mappedEspaceAddress(coreHexAddress: Hex): HexAddress;
// Transfers assets to Espace
export declare function transferToEspace(opts: BridgeBaseOptions & {
// Calls a contract on Espace
export declare function callEspace(opts: BridgeBaseOptions & {
// Withdraws assets from a mapped address
export declare function withdrawFromMapped(opts: BridgeBaseOptions & {
// Gets balance of a mapped address
export declare function getMappedBalance(input: {
// Gets nonce of a mapped address
export declare function getMappedNonce(input: {
// Converts bigint to hex string
export declare function uint256Hex(n: bigint): Hex;
// Converts hex string to bigint
export declare function hexToUint256(hex: Hex): bigint;./errors
Usage
import { ContractsError, ContractsErrorCode } from '@cfxdevkit/contracts/errors';
try {
// ...
} catch (e) {
if (e instanceof ContractsError && e.code === 'contracts/reverted') {
// ...
}
}// Error codes for contract operations
export type ContractsErrorCode = 'contracts/unsupported-family' | 'contracts/decode-failure' | 'contracts/receipt-timeout' | 'contracts/reverted' | 'contracts/invalid-argument';
// Base error class for contract operations
export declare class ContractsError extends CfxError {