Assets
The Asset class — listing a network's tokens with workspace.assets(network), adding and dropping custom tokens, and the AssetInitObject, AssetBalance and AssetCollection types.
An Asset is token metadata bound to a Network: its id, symbol, name, decimals, and contract address. Every workspace is seeded with a curated set of built-in tokens and lets you import your own. This page covers constructing an Asset, listing a network's tokens, importing and removing custom tokens, and the related types.
The Asset class
Asset is a value export of wative-core. Construct one either from an init object or from positional arguments.
import { Asset, Network } from "wative-core";
// Object form (preferred).
const pepe = new Asset({
id: 200,
symbol: "PEPE",
name: "Pepe",
decimals: 18,
contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
network: Network.Ethereum,
});
// Positional form: (id, symbol, name, decimals, network, contractAddress?)
const same = new Asset(200, "PEPE", "Pepe", 18, Network.Ethereum, "0x6982508145454Ce325dDbE47a25d4ec3d2311933");AssetInitObject
The object accepted by the constructor.
| Field | Type | Required | Notes |
|---|---|---|---|
id | AssetId | yes | A non-negative integer. AssetId is a branded number. |
symbol | string | yes | 1–32 characters. |
name | string | yes | 1–128 characters. |
decimals | number | yes | Token decimals. |
network | Network | yes | Must be a Network instance. |
contractAddress | string | null | no | null for a native gas coin. Defaults to null. |
displayDecimals | number | no | Defaults to decimals; must be <= decimals. |
displayStatus | boolean | no | Defaults to true. |
On an EVM network the contractAddress must already be a valid EIP-55 checksummed address (all-lowercase and all-uppercase are also accepted as the no-checksum forms). A mixed-case address whose checksum fails is rejected rather than repaired — a single mistyped nibble would otherwise silently point the wallet at a different contract. An address on the wrong shape for the network's vm (EVM vs. SVM) also throws PARAMETER_ERROR.
Instance properties
| Property | Type | Notes |
|---|---|---|
id | AssetId | readonly |
contractAddress | string | null | readonly; canonicalized on construction (EIP-55 for EVM). null for a native coin. |
native | boolean | readonly; derived. true when the address is null or the network's native placeholder. |
symbol | string | |
name | string | |
decimals | number | |
displayDecimals | number | Defaults to decimals. |
displayStatus | boolean | Defaults to true. |
network | Network | readonly |
Listing a network's tokens — workspace.assets(network)
assets(network: NetworkLike): Promise<readonly Asset[]>network is a NetworkLike: either a Network instance or a network slug string (e.g. "sepolia", "arbitrum-sepolia"). The result is the built-in tokens for that network plus any you have imported.
import { Workspace, Network } from "wative-core";
const ws = await Workspace.open({ path: "./wallet", password: "wsp-pwd" });
// By Network instance…
const eth = await ws.assets(Network.Ethereum);
eth.map((a) => a.symbol); // ["ETH", "USDC", "USDT", "WETH"]
// …or by network slug.
const sepolia = await ws.assets("sepolia"); // length 1 — [ETH]
const arb = await ws.assets("arbitrum-sepolia");
const usdc = arb.find((a) => a.symbol === "USDC");
usdc?.decimals; // 6
usdc?.native; // false
usdc?.contractAddress; // "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d"Adding a custom token — addAsset
addAsset(asset: Asset): Promise<Asset>Imports a user token. The write is persisted immediately and the in-memory registry rolls back if persistence fails; the imported Asset is returned.
const pepe = new Asset({
id: 200,
symbol: "PEPE",
name: "Pepe",
decimals: 18,
contractAddress: "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
network: Network.Ethereum,
});
await ws.addAsset(pepe);
const eth = await ws.assets(Network.Ethereum);
eth.length; // 5 — the four built-ins plus PEPEaddAsset throws a WativeError in these cases:
code | When |
|---|---|
PARAMETER_ERROR | The argument is not an Asset instance, the id already exists, or the (network, contractAddress) pair is already imported (including trying to claim the network's native slot). |
UNSUPPORTED_NETWORK | The asset's network is not registered with this workspace. |
id and address collisions are rejected
Ids and addresses must be unique within the workspace, and the built-in tokens already occupy their ids and addresses. Re-using either rejects with PARAMETER_ERROR.
// id 1 is the built-in ETH.
await ws.addAsset(new Asset({
id: 1, symbol: "FAKE", name: "Fake", decimals: 18,
contractAddress: "0x1234567890123456789012345678901234567890",
network: Network.Ethereum,
})); // rejects: WativeError { code: "PARAMETER_ERROR" }
// This address is already the built-in USDC.
await ws.addAsset(new Asset({
id: 201, symbol: "USDC2", name: "Other USDC", decimals: 6,
contractAddress: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
network: Network.Ethereum,
})); // rejects: WativeError { code: "PARAMETER_ERROR" }Dropping a token — dropAsset
dropAsset(id: AssetId): Promise<void>Removes a user-imported token by id. Like addAsset, the write is persisted and rolls back on failure.
await ws.addAsset(myToken); // id 300
await ws.dropAsset(300);
const eth = await ws.assets(Network.Ethereum);
eth.some((a) => a.id === 300); // falsecode | When |
|---|---|
UNSUPPORTED_OP | The id belongs to a built-in token — those are protected. |
RECORD_NOT_FOUND | No user asset with that id exists. |
await ws.dropAsset(1); // rejects: WativeError { code: "UNSUPPORTED_OP" }Finding an asset
The workspace's general filter helper resolves a single Asset by symbol or contract address (returning null when nothing matches):
const bySymbol = await ws.filter("USDC", "Asset");
bySymbol?.symbol; // "USDC"
const byAddr = await ws.filter("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", "Asset");
byAddr?.symbol; // "USDC"AssetBalance
A read of an on-chain balance for one asset. Balances live on an address, not on the Asset itself.
| Field | Type | Description |
|---|---|---|
assetId | AssetId | Which asset the balance is for. |
raw | bigint | The balance in base units (unscaled by decimals). |
decimals | number | The asset's decimals, for formatting raw. |
displayStatus | boolean | Whether the asset is shown in balance listings. |
fetchedAt | number | When the balance was read. |
All fields are readonly.
AssetCollection
interface AssetCollection extends ReadonlyArray<Asset> {
byId(id: AssetId): Asset | null;
}A read-only array of Asset with an added byId lookup. This is the type of an address's .assets property.
workspace.assets(network) returns a plain readonly Asset[], not an AssetCollection — use Array.prototype.find on it. The byId convenience belongs to an address's asset list.