- Notifications
You must be signed in to change notification settings - Fork1
hazae41/cubane
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
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
) - Signatures
- JSON-ABI parsing
- Return type of functions
- Transactions
Cubane can encode both to hexadecimal string and to Uint8Array, this benchmark aims to check the speed difference between both engines and between other libraries
- @hazae41/cubane@0.1.14
- viem@2.4.1
- ethers@6.10.0
Running on Node 20.3.1 on Apple M1 Max
┌────────────────┬──────────────────┬─────────────┬─────────────┐│ (index) │ average │ minimum │ maximum │├────────────────┼──────────────────┼─────────────┼─────────────┤│ cubane (bytes) │'4.10 μs/iter' │'3.08 μs' │'129.37 μs' ││ cubane (hex) │'4.47 μs/iter' │'3.83 μs' │'76.13 μs' ││ viem │'18.77 μs/iter' │'16.58 μs' │'184.83 μs' ││ ethers │'211.55 μs/iter' │'194.08 μs' │'586.21 μs' │└────────────────┴──────────────────┴─────────────┴─────────────┘Summary- cubane (hex) is 4.20x faster than viem- cubane (hex) is 47.28x faster than ethersSummary- cubane (bytes) is 4.58x faster than viem- cubane (bytes) is 51.59x faster than ethers
You may need to polyfillSymbol.dispose
import"@hazae41/symbol-dispose-polyfill"
Seehttps://github.com/hazae41/symbol-dispose-polyfill for more
You can bring your own implementation for some algorithms
Seehttps://github.com/hazae41/keccak256 for setup
Seehttps://github.com/hazae41/secp256k1 for setup
Seehttps://github.com/hazae41/base16 for setup
Parse the function from its signature
import{Abi}from"@hazae41/cubane"constf=Abi.FunctionSignature.parseOrThrow("f(bool,uint256,string)")
Encode the function selector and its arguments (it will return a0x
-prefixed hex string)
consthex=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"exportconstf=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) */consthex=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 filef.abi.ts
exportconstf=/*generated code*/
Encode the function selector and its arguments (it will return a0x
-prefixed hex string)
import{f}from"./f.abi.ts"/** * f is fully typed as (bool,uint256,string) */consthex=f.from(true,123456789n,"hello world").encodeOrThrow()// c4b71e130000000000000000000000000000000000000000000000000000000000000001...
import{RlpString,RlpList}from"@hazae41/cubane"import{Writable}from"@hazae41/binary"constcat=RlpString.from(Bytes.fromUtf8("cat"))constdog=RlpString.from(Bytes.fromUtf8("dog"))constcatAndDog=RlpList.from([cat,dog])constbytes=Writable.writeToBytesOrThrow(catAndDog)
import{RlpString,RlpList}from"@hazae41/cubane"import{Writable}from"@hazae41/binary"constcat=RlpString.from(Bytes.fromUtf8("cat"))constdog=RlpString.from(Bytes.fromUtf8("dog"))constcatAndDog=RlpList.from([cat,dog])constbytes=Writable.writeToBytesOrThrow(catAndDog)consthex="0x"+Base16.get().getOrThrow().encodeOrThrow(bytes)
import{Bytes}from"@hazae41/bytes"import{ExtPrivateKey}from"@hazae41/cubane"import{Secp256k1}from"@hazae41/secp256k1"import{Base16}from"@hazae41/base16"constmessage="hello world"constprivateKeyBytes=Bytes.random(32)constprivateKeyExt=newExtPrivateKey(Secp256k1.get().PrivateKey.importOrThrow(privateKeyBytes))constsignatureExt=privateKeyExt.signPersonalMessageOrThrow(message)constsignatureBytes=signatureExt.value.exportOrThrow().copyAndDispose()constsignatureZeroHex=`0x${Base16.get().getOrThrow().encodeOrThrow(signatureBytes)}`
import{ExtPublicKey,Address}from"@hazae41/cubane"constrecoveredPublicKeyExt=ExtPublicKey.recoverPersonalMessageOrThrow(message,signatureExt)constrecoveredPublicKeyBytes=recoveredPublicKeyExt.value.exportUncompressedOrThrow().copyAndDispose()constrecoveredAddressZeroHex=Address.computeOrThrow(recoveredPublicKeyBytes)
About
Next-gen Ethereum library for TypeScript