TypeScript Integration with Cairo ABIs
Starknet.js provides seamless TypeScript integration for Cairo smart contracts through Abi-Wan-Kanabi. This powerful feature enables:
- 🔍 Real-time type checking for contract interactions
- 💡 Smart autocompletion in your IDE
- 🐛 Early error detection before on-chain execution
- 📝 Better developer experience with type safety
Supported Cairo Versions
The integration supports various Cairo versions through Abi-Wan-Kanabi. Check the compatibility matrix for specific version support.
Basic Usage
1. Define Your Contract ABI
First, create a TypeScript file with your contract's ABI. The ABI must be wrapped in an array and exported as a const
:
export const ABI = [
{
type: 'function',
name: 'increase_balance',
inputs: [
{
name: 'amount',
type: 'core::felt252',
},
],
outputs: [],
state_mutability: 'external',
},
] as const;
2. Create a Typed Contract Instance
Use the ABI to create a typed contract instance:
import { Contract, RpcProvider } from 'starknet';
const address = 'YOUR_CONTRACT_ADDRESS';
const myProvider = new RpcProvider({ nodeUrl: `${yourNodeUrl}` });
// Create a typed contract instance
const myContract = new Contract({
abi: ABI,
address,
providerOrAccount: myProvider,
}).typedv2(ABI);
// Enjoy autocompletion and type checking!
const result = await myContract.increase_balance(100);
Working with Deployed Contracts
Generating TypeScript Types from Deployed Contracts
For existing contracts on Starknet, you can generate TypeScript types in two ways:
Using Contract Class JSON:
npx abi-wan-kanabi --input /path/to/contract_class.json --output /path/to/abi.ts
Directly from Network (using starkli):
# Fetch ABI and generate types in one command
starkli class-at "CONTRACT_ADDRESS" --network mainnet | npx abi-wan-kanabi --input /dev/stdin --output abi.ts
Example: Interacting with a Deployed Contract
Here's a complete example of interacting with a deployed contract using generated types:
import { Contract, RpcProvider, constants } from 'starknet';
import { ABI } from './abi';
const address = '0x00000005dd3d2f4429af886cd1a3b08289dbcea99a294197e9eb43b0e0325b4b';
const myProvider = new RpcProvider({ nodeUrl: constants.NetworkName.SN_MAIN });
// Create typed contract instance
const myContract = new Contract({
abi: ABI,
address,
providerOrAccount: myProvider,
}).typedv2(ABI);
// Enjoy type inference and autocompletion
const primaryInterfaceId = await myContract.get_primary_interface_id();
const protocolFees = await myContract.get_protocol_fees_collected('0x1');
Benefits of Type Safety
Using typed contracts provides several advantages:
- Compile-Time Error Detection: Catch parameter type mismatches before deployment
- IDE Support: Get function parameter hints and return type information
- Refactoring Support: Safely rename functions and update parameters
- Documentation: Types serve as inline documentation for contract interfaces
Best Practices
- Always use
typedv2()
for the latest type-checking features - Keep your ABI files in a dedicated directory for better organization
- Use meaningful variable names that reflect the typed nature of your contracts
- Consider creating type-safe wrapper functions for common contract interactions