first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,147 @@
# @suaveplan/cryptocurrency - Universal cryptocurrency utilities: wallet address validation across 15 chains with EIP-55 checksumming, unit conversion (ETH/BTC/SOL), chain registry with async adapter, EIP-1559 gas estimation, ERC-20 token registry, calldata/selector decoder, transaction hash parsing. Zero browser/Node deps; injectable LoggerLike; typed CryptocurrencyError hierarchy.
Universal cryptocurrency utilities for wallet address validation, unit conversion, chain registry, gas estimation, ERC-20 token registry, calldata / function-selector decoding, and transaction hash parsing. Zero browser or Node-specific dependencies — runs unchanged under Node ≥ 18, Bun, modern browsers, and Web Workers. Not a wallet, not a signing library — just pure utility primitives.
<!-- begin:auto-docs -->
## Documentation tree
- [address](./src/address/validator.md) — Provides the three address / hash validation primitives that the rest of the package builds on: `validateAddress` for c…
- [validator](./src/address/validator.md) — Provides the three address / hash validation primitives that the rest of the package builds on: `validateAddress` for c…
- [chain-data](./src/chains/chain-data.md) — Holds the canonical `CHAINS` constant: a `Record<ChainId, ChainInfo>` containing one entry per supported mainnet networ…
- [chain-registry](./src/chains/chain-registry.md) — Provides the async chain-registry façade for callers that need dynamic chain data — custom mainnet sets, runtime regist…
- [registry](./src/chains/registry.md) — Exposes the synchronous fast-path over the built-in `CHAINS` constant. Every helper here is a pure function that reads…
- [error-codes](./src/error-codes/error-codes.md) — Declares the stable, namespaced error registry for `@suaveplan/cryptocurrency` and the typed `CryptocurrencyError` clas…
- [error-codes](./src/error-codes/error-codes.md) — Declares the stable, namespaced error registry for `@suaveplan/cryptocurrency` and the typed `CryptocurrencyError` clas…
- [gas](./src/gas/gas-estimator.md) — Provides EIP-1559 gas-estimation primitives for Ethereum-style chains. Every helper accepts and returns `bigint` values…
- [gas-estimator](./src/gas/gas-estimator.md) — Provides EIP-1559 gas-estimation primitives for Ethereum-style chains. Every helper accepts and returns `bigint` values…
- [token-data](./src/tokens/token-data.md) — Provides the `COMMON_TOKENS` constant: a curated list of eight well-known ERC-20 tokens on Ethereum mainnet — USDT, USD…
- [token-registry](./src/tokens/token-registry.md) — Provides the `TokenRegistry` class for adding, retrieving, and searching ERC-20 / token information across chains, plus…
- [transaction](./src/transaction/tx-decoder.md) — Provides naive transaction-hash classification and 4-byte function-selector decoding for EVM calldata. `decodeTxHash` c…
- [tx-decoder](./src/transaction/tx-decoder.md) — Provides naive transaction-hash classification and 4-byte function-selector decoding for EVM calldata. `decodeTxHash` c…
- [units](./src/units/converter.md) — Provides generic and convenience unit conversion for cryptocurrency denominations. The generic `convertUnits` operates…
- [converter](./src/units/converter.md) — Provides generic and convenience unit conversion for cryptocurrency denominations. The generic `convertUnits` operates…
<!-- end:auto-docs -->
## Install
```bash
bun add @suaveplan/cryptocurrency
```
## Quick start
```ts
import {
estimateGas,
formatGwei,
getChain,
getExplorerTxUrl,
satoshiToBitcoin,
validateAddress,
weiToEther,
} from "@suaveplan/cryptocurrency";
// Multi-chain address validation with auto-detection
const r = validateAddress("0x742d35Cc6634C0532925a3b844Bc9e7595f2bD28");
// { valid: true, normalized: "0x...", chains: ["ethereum", "polygon", ...] }
// Unit conversion (bigint-pure)
weiToEther("1000000000000000000"); // "1"
satoshiToBitcoin("100000000"); // "1"
// Chain metadata + explorer URLs
const eth = getChain("ethereum");
// { id: "ethereum", evmChainId: 1, decimals: 18, ... }
const url = getExplorerTxUrl("ethereum", "0xabc...");
// EIP-1559 gas estimation
const estimate = estimateGas({
gasLimit: 21000n,
baseFeePerGas: 30000000000n,
maxPriorityFeePerGas: 2000000000n,
});
formatGwei(estimate.gasPrice); // "32"
```
## Features
- **Address validation across 15 chains** (Bitcoin, Ethereum, Solana, Polygon, Arbitrum, Optimism, Avalanche, BSC, Base, TRON, Litecoin, Dogecoin, Cardano, Polkadot, Cosmos) via `validateAddress` / `validateAddressForChain`.
- **Transaction hash classification** (EVM / UTXO / Solana) via `validateTxHash` and `decodeTxHash`.
- **EIP-55 checksumming** for EVM addresses (simplified positional algorithm preserved from upstream; full keccak256 deferred to a follow-up change).
- **Static chain registry** with `getChain` / `getAllChainIds` / `getEvmChains` / `getChainByEvmId` / explorer URL helpers.
- **Async chain registry** (`ChainRegistry` + `MemoryChainRegistry`) supporting custom adapters and typed `CryptocurrencyError({ code: CRYPTOCURRENCY.UNKNOWN_CHAIN })`.
- **Bigint-pure unit conversion** across ETH / BTC / SOL (`convertUnits`, `weiToEther`, `etherToWei`, `gweiToEther`, `satoshiToBitcoin`, `bitcoinToSatoshi`, `lamportToSol`, `getUnits`).
- **EIP-1559 gas estimation** (`estimateGas`, `calculateMaxFeePerGas`, `calculateEffectiveGasPrice`, `formatGwei`, `estimateTxCostEth`).
- **ERC-20 token registry** (`TokenRegistry`, `COMMON_TOKENS`, `formatTokenBalance`) — case-insensitive address lookups, substring search by symbol / name.
- **Calldata + function-selector decoder** (`KNOWN_SELECTORS`, `lookupSelector`, `extractSelector`, `decodeCalldata`).
- **Typed `CryptocurrencyError` hierarchy** with `CRYPTOCURRENCY.*` code registry and optional `chainId` / `currency` / `unit` discriminants.
- **Optional `LoggerLike` injection** on `ChainRegistry` (no-op default) emitting `chain.registered` / `chain.lookup.miss` events.
- **Tree-shakeable subpath exports** — import only what you use.
- **Universal tier** — no `node:*`, no `bun:*`, no `fs` / `path` / `crypto` imports.
## Modules
Co-located docs for every implementation file:
- [`src/address/validator.md`](./src/address/validator.md) — `validateAddress`, `validateAddressForChain`, `validateTxHash`.
- [`src/chains/chain-data.md`](./src/chains/chain-data.md) — `CHAINS` constant.
- [`src/chains/chain-registry.md`](./src/chains/chain-registry.md) — `ChainRegistry`, `MemoryChainRegistry`, `LoggerLike` integration.
- [`src/chains/registry.md`](./src/chains/registry.md) — synchronous getters.
- [`src/error-codes/error-codes.md`](./src/error-codes/error-codes.md) — `CRYPTOCURRENCY_CODES`, `CryptocurrencyError`.
- [`src/gas/gas-estimator.md`](./src/gas/gas-estimator.md) — EIP-1559 gas helpers.
- [`src/tokens/token-data.md`](./src/tokens/token-data.md) — `COMMON_TOKENS`.
- [`src/tokens/token-registry.md`](./src/tokens/token-registry.md) — `TokenRegistry`, `formatTokenBalance`.
- [`src/transaction/tx-decoder.md`](./src/transaction/tx-decoder.md) — calldata / selector / tx-hash decoder.
- [`src/types/crypto.types.md`](./src/types/crypto.types.md) — public type contract.
- [`src/units/converter.md`](./src/units/converter.md) — generic + convenience unit conversion.
## Subpath exports
Every public module ships its own subpath so consumers can tree-shake:
```ts
import { validateAddress } from "@suaveplan/cryptocurrency/address/validator";
import { CHAINS } from "@suaveplan/cryptocurrency/chains/chain-data";
import { ChainRegistry } from "@suaveplan/cryptocurrency/chains/chain-registry";
import { getChain } from "@suaveplan/cryptocurrency/chains/registry";
import { CRYPTOCURRENCY_CODES } from "@suaveplan/cryptocurrency/error-codes/error-codes";
import { estimateGas } from "@suaveplan/cryptocurrency/gas/gas-estimator";
import { COMMON_TOKENS } from "@suaveplan/cryptocurrency/tokens/token-data";
import { TokenRegistry } from "@suaveplan/cryptocurrency/tokens/token-registry";
import { decodeCalldata } from "@suaveplan/cryptocurrency/transaction/tx-decoder";
import type { ChainInfo } from "@suaveplan/cryptocurrency/types/crypto.types";
import { convertUnits } from "@suaveplan/cryptocurrency/units/converter";
```
## Error handling
```ts
import {
CRYPTOCURRENCY_CODES,
CryptocurrencyError,
convertUnits,
} from "@suaveplan/cryptocurrency";
try {
convertUnits("1", "wei", "ether", "XYZ");
} catch (err) {
if (err instanceof CryptocurrencyError) {
if (err.code === CRYPTOCURRENCY_CODES.UNKNOWN_CURRENCY) {
console.error(`unsupported currency: ${err.currency}`);
}
}
}
```
## What this package is not
- **Not a wallet** — no key management, no transaction signing.
- **Not an RPC client** — no on-chain calls; the `ChainRegistry` adapter contract lets you wire your own RPC layer.
- **Not an ABI decoder** — `decodeCalldata` only recognises 4-byte selectors. Full ABI decoding (dynamic types, tuples) lands in a follow-up change.
- **Not an ENS resolver** — name-resolution lands in a separate package.
- **Not RFC-correct EIP-55** — uses a simplified positional checksum preserved from upstream; full keccak256 lands in a follow-up change.
## License
MIT