Next-gen Ethereum library for TypeScript
npm i @hazae41/cubane
- 100% TypeScript and ESM
- Minimal dependencies
- Rust-like patterns
- Human-readable code
- Bottom-up abstractions
- Bring your own algorithms
- Zero-copy bytes encoding
- Compile-time codegen
- ABI / ABIv2 (except
fixed
) - Function parsing (e.g.
f(uint256)
) - Recursive-Length Prefix (RLP) coding
- TypedData (EIP-712) hashing
- ENS (e.g.
namehash
)
- JSON-ABI parsing
- Return type of functions
- Signatures and transactions
You may need to polyfill Symbol.dispose
import "@hazae41/symbol-dispose-polyfill"
See https://github.com/hazae41/symbol-dispose-polyfill for more
You can bring your own implementation for some algorithms
Morax includes a fast WebAssembly port of Keccak256
npm i @hazae41/morax
keccak256.ts
import { Keccak256 } from "@hazae41/keccak256"
Keccak256.set(await Keccak256.fromMorax())
See https://github.com/hazae41/keccak256 for more
Alocer includes a fast WebAssembly port of Base16
npm i @hazae41/alocer
base16.ts
import { Base16 } from "@hazae41/base16"
Base16.set(await Base16.fromBufferOrAlocer())
See https://github.com/hazae41/base16 for more
Parse the function from its signature
import { Abi } from "@hazae41/cubane"
const f = Abi.FunctionSignature.parseOrThrow("f(bool,uint256,string)")
Encode the function selector and its arguments (it will return a 0x
-prefixed hex string)
const hex = f.from(true, 123456789n, "hello world").encodeOrThrow()
// c4b71e130000000000000000000000000000000000000000000000000000000000000001...
Cubane provides Saumon macros to generate typed ABI functions
f.abi.macro.ts
import "@hazae41/symbol-dispose-polyfill"
import { Abi } from "@hazae41/cubane"
/**
* Your Keccak256 adapter code
*/
import "./keccak256.js"
export const f = Abi.FunctionSignature.$parse$("f(bool,uint256,string)")
saumon build ./f.abi.macro.ts
main.ts
import { f } from "./f.abi.ts"
/**
* f is fully typed as (bool,uint256,string)
*/
const hex = f.from(true, 123456789n, "hello world").encodeOrThrow()
// c4b71e130000000000000000000000000000000000000000000000000000000000000001...
You can generate the function from its signature
> import { Abi } from "@hazae41/cubane"
> console.log(Abi.FunctionSignature.parseOrThrow("f(bool,uint256,string)").codegen())
Paste it in a file f.abi.ts
export const f = /*generated code*/
Encode the function selector and its arguments (it will return a 0x
-prefixed hex string)
import { f } from "./f.abi.ts"
/**
* f is fully typed as (bool,uint256,string)
*/
const hex = f.from(true, 123456789n, "hello world").encodeOrThrow()
// c4b71e130000000000000000000000000000000000000000000000000000000000000001...
import { RlpString, RlpList } from "@hazae41/cubane"
import { Writable } from "@hazae41/binary"
const cat = RlpString.from(Bytes.fromUtf8("cat"))
const dog = RlpString.from(Bytes.fromUtf8("dog"))
const catAndDog = RlpList.from([cat, dog])
const bytes = Writable.writeToBytesOrThrow(catAndDog)
import { RlpString, RlpList } from "@hazae41/cubane"
import { Writable } from "@hazae41/binary"
const cat = RlpString.from(Bytes.fromUtf8("cat"))
const dog = RlpString.from(Bytes.fromUtf8("dog"))
const catAndDog = RlpList.from([cat, dog])
const bytes = Writable.writeToBytesOrThrow(catAndDog)
const hex = "0x" + Base16.get().encodeOrThrow(bytes)