Skip to main content
@chipi-stack/core is in development (v0.1.0). APIs may change before stable release.

Overview

Erc20 provides a typed wrapper around ERC20 contract interactions on StarkNet. Read methods (balanceOf, allowance) return Amount objects. Write methods (approveCall, transferCall) return Call objects for use with TxBuilder or Account.execute().

Usage

import { Erc20, Amount, TokenRegistry } from "@chipi-stack/core";

const registry = new TokenRegistry("mainnet");
const usdcInfo = registry.bySymbol("USDC")!;
const usdc = new Erc20(usdcInfo, account);

// Query balance (returns Amount)
const balance = await usdc.balanceOf(myAddress);
console.log(balance.toFormatted()); // "150.5 USDC"

Constructor

new Erc20(token: TokenInfo, account: Account)

Parameters

  • token (TokenInfo): Object with symbol, decimals, and address
  • account (Account): A starknet.js Account instance

Methods

balanceOf(address)

Query the ERC20 balance of an address.
const balance = await usdc.balanceOf("0x123...");
console.log(balance.toFormatted()); // "1500.0 USDC"
console.log(balance.toBase());      // 1500000000n

Parameters

  • address (string): StarkNet address to query

Returns

Promise<Amount>: The balance as an Amount object

allowance(owner, spender)

Query the allowance granted by owner to spender.
const allowed = await usdc.allowance(ownerAddress, spenderAddress);
if (allowed.lt(transferAmount)) {
  console.log("Need to approve more tokens");
}

Parameters

  • owner (string): Token owner address
  • spender (string): Approved spender address

Returns

Promise<Amount>: The allowance as an Amount object

approveCall(spender, amount)

Build an ERC20 approve Call object. Does not execute the transaction.
const call = usdc.approveCall(spenderAddress, amount);
// Use with TxBuilder
await new TxBuilder(account).add(call).send();

Parameters

  • spender (string): Address to approve
  • amount (Amount): Amount to approve

Returns

Call: A StarkNet Call object for use with TxBuilder or Account.execute()

Throws

  • If amount.decimals doesn’t match the token’s decimals
  • If amount.symbol doesn’t match the token’s symbol (when set)

transferCall(recipient, amount)

Build an ERC20 transfer Call object. Does not execute the transaction.
const call = usdc.transferCall(recipientAddress, amount);
await new TxBuilder(account).add(call).send();

Parameters

  • recipient (string): Destination address
  • amount (Amount): Amount to transfer

Returns

Call: A StarkNet Call object

Throws

  • If amount.decimals doesn’t match the token’s decimals
  • If amount.symbol doesn’t match the token’s symbol (when set)

Example

Full Flow: Check Balance, Approve, Transfer

import { Erc20, Amount, TxBuilder, TokenRegistry } from "@chipi-stack/core";

const registry = new TokenRegistry("mainnet");
const usdcInfo = registry.bySymbol("USDC")!;
const usdc = new Erc20(usdcInfo, account);

const sendAmount = Amount.parse("25.0", usdcInfo);

// Check balance
const balance = await usdc.balanceOf(myAddress);
if (balance.lt(sendAmount)) {
  throw new Error(`Insufficient: ${balance.toFormatted()} < ${sendAmount.toFormatted()}`);
}

// Check allowance
const allowed = await usdc.allowance(myAddress, dexAddress);

// Build atomic transaction
const builder = new TxBuilder(account);
if (allowed.lt(sendAmount)) {
  builder.add(usdc.approveCall(dexAddress, sendAmount));
}
builder.add(usdc.transferCall(recipientAddress, sendAmount));

// Preview fee, then send
const fee = await builder.estimateFee();
console.log(`Fee: ${fee.overall_fee} wei`);

const result = await new TxBuilder(account)
  .add(usdc.approveCall(dexAddress, sendAmount))
  .add(usdc.transferCall(recipientAddress, sendAmount))
  .send();
  • Amount: The value type returned by balanceOf() and allowance()
  • TxBuilder: Execute Call objects in atomic batches
  • TokenRegistry: Look up TokenInfo for the Erc20 constructor