Chain Helpers & Subpaths
The heavier EVM/SVM helpers kept off the main entry on wative-core/artifacts/evm and wative-core/artifacts/svm (ERC20, TokenProgram, Token2022Program) so they are pulled in only when needed.
The chain helpers turn an ABI or an IDL into ready-to-sign call data. The wrapper classes — Contract for EVM and Program for Solana — ship on the main wative-core entry. The ready-made artifacts built from them — ERC20, TokenProgram, Token2022Program — live on dedicated subpaths so their bundled ABI/IDL JSON is pulled into your build only when you import them.
Why subpaths
An artifact carries its ABI or IDL as embedded JSON, and a Token program's IDL in particular is large. Exposing those instances from the root entry would fold that JSON into every bundle that imports wative-core — including a browser app that only ever signs native transfers. Keeping them behind wative-core/artifacts/evm and wative-core/artifacts/svm means a tree-shaking bundler includes an artifact's payload only in the code paths that actually reference it.
The wrapper classes themselves are small and stay on the main entry, so you can build your own Contract / Program from an ABI/IDL you already hold without touching a subpath at all.
These subpaths are isomorphic — they work in both Node and the browser. They are distinct from wative-core/node, which holds the Node-only providers and sinks (HybridProviderV3, FileSink, …).
What each subpath exports
wative-core/artifacts/evm
| Export | Kind | Notes |
|---|---|---|
ERC20 | Contract instance | The standard ERC-20 ABI, ready for encode / decode / call |
wative-core/artifacts/svm
| Export | Kind | Notes |
|---|---|---|
TokenProgram | Program instance | Legacy SPL Token (TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA) |
Token2022Program | Program instance | SPL Token-2022 (TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb) |
TOKEN_PROGRAM_ID | string | Legacy SPL Token program id |
TOKEN_2022_PROGRAM_ID | string | Token-2022 program id |
ASSOCIATED_TOKEN_PROGRAM_ID | string | Associated-token program id (works for both) |
NATIVE_SOL_MINT | string | Wrapped-SOL mint |
splTokenEncodeInstruction | function | Low-level native SPL instruction encoder → SvmInstruction |
SplTokenArgs | type | Argument shape for splTokenEncodeInstruction |
SplTokenAccountSet | type | Account shape for splTokenEncodeInstruction |
Import examples
import { ERC20 } from "wative-core/artifacts/evm";
// Encode a `transfer(address,uint256)` call to hex data.
const data = ERC20.encode("transfer", [
"0x1234567890123456789012345678901234567890",
1_000_000n,
]);import { TokenProgram, Token2022Program } from "wative-core/artifacts/svm";
// Build a legacy SPL Token transfer instruction.
const ix = TokenProgram.encodeInstruction(
"transfer",
{ amount: 1_000_000n },
{ source: srcAta, destination: dstAta, authority: ownerPubkey },
);
// Same wire bytes, Token-2022 program id.
const ix2 = Token2022Program.encodeInstruction(
"transfer",
{ amount: 1_000_000n },
{ source: srcAta, destination: dstAta, authority: ownerPubkey },
);The subpath specifier is what a consumer writes verbatim — require("wative-core/artifacts/evm") and require("wative-core/artifacts/svm") both resolve the same way under CommonJS and ESM.
The wrapper classes are also at the root
The Contract and Program classes are re-exported from the main wative-core entry, so you can wrap your own ABI or IDL without reaching for a subpath:
import { Contract, Program } from "wative-core";
import type { AbiItem, SvmInstruction } from "wative-core";
const myToken = new Contract("MyToken", myAbi);
const myProgram = new Program("MyProgram", myIdl);Only the ready-made instances (ERC20, TokenProgram, Token2022Program) are subpath-only — that is where their embedded ABI/IDL JSON lives, and keeping the instances off the root is what keeps that JSON out of bundles that never use it.