@droplinked_inc/web3-kit
v2.0.0
Published
Higher-level web3 building blocks (chain registry, known-token registry, display formatters, tx builders) — hardened rebuild of the original [email protected].
Readme
@droplinked_inc/web3-kit
Higher-level web3 building blocks for the Droplinked frontend stack: a frozen chain registry, a hard-coded known-token registry, decimal-safe display formatters, and viem-backed transaction builders.
This is a hardened rebuild of the original [email protected].
See THREAT_MODEL.md for the security deltas.
Status
Initial rebuild. Stable surface; coverage 96.81% statements / 96.87% branches.
Install
pnpm add @droplinked_inc/web3-kit @droplinked_inc/wallet-connection@droplinked_inc/wallet-connection is a peer dependency — this kit
does not reimplement EIP-1193 provider discovery, EIP-712 login signing,
session storage, or wallet-protocol logic. Those primitives live in
@droplinked_inc/wallet-connection.
Modules
| Module | Surface |
| ------------- | ----------------------------------------------------------------------------- |
| chains | chains, getChainByName, getChainDetails, isRpcUrlAllowed, getTransactionLink |
| tokens | TOKEN_REGISTRY, getTokenInfo, hasToken, listTokens, assertCanonicalTokenAddress |
| format | formatAmount, parseAmount, formatEther, parseEther, shortenAddress, escapeTokenDisplay, formatBalance |
| tx-builder | buildErc20Transfer, buildErc20Approve, buildNativeTransfer, buildEip712Domain |
| types | Chains, Network, Groups, PaymentTokens, zod schemas |
| errors | typed exception hierarchy mirroring v1.0.13 |
Quick examples
Look up a chain and a token
import { Chains, Network, getChainDetails, getTokenInfo } from '@droplinked_inc/web3-kit';
const polygon = getChainDetails(Chains.POLYGON, Network.MAINNET);
// polygon.chainIdNumber === 137
const usdc = getTokenInfo(Chains.POLYGON, Network.MAINNET, 'USDC');
// usdc.address === '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359'Reject a spoofed token address
import { assertCanonicalTokenAddress, TokenAddressMismatchError } from '@droplinked_inc/web3-kit';
try {
assertCanonicalTokenAddress({
chain: Chains.POLYGON,
network: Network.MAINNET,
symbol: 'USDC',
claimedAddress: backendResponse.usdcAddress, // attacker-controlled
});
} catch (err) {
if (err instanceof TokenAddressMismatchError) {
// refuse the checkout — your backend lied about what address USDC has
}
}Build an ERC-20 transfer
import { buildErc20Transfer, parseAmount } from '@droplinked_inc/web3-kit';
const call = buildErc20Transfer({
chain: Chains.POLYGON,
network: Network.MAINNET,
tokenSymbol: 'USDC',
to: recipient,
amount: parseAmount('1.5', 6),
});
// call.to === USDC contract on Polygon
// call.data === 0x...a9059cbb… (transfer(address,uint256))
// call.value === 0n
// call.chainIdNumber === 137Then hand call to a wallet connector from @droplinked_inc/wallet-connection
to actually broadcast it.
Format balances safely
import { formatBalance, escapeTokenDisplay } from '@droplinked_inc/web3-kit';
formatBalance({ value: 1_999_999n, decimals: 6, displayDecimals: 2 });
// "1.99" — truncated, never rounded up. The user can't be shown more than they hold.
escapeTokenDisplay(maliciousTokenName);
// HTML-escaped, control-char-stripped, bidi-override-stripped, length-capped.Security model
See THREAT_MODEL.md. Highlights:
- The chain registry and the known-token registry are frozen at package build time. No remote fetches, no backend-driven addresses.
- Caller-supplied token addresses for known symbols (USDC, USDT, DAI,
WETH, USDS) are validated against the registry — passing any other
address as e.g. "USDC" throws
TokenAddressMismatchError. - All amounts are
bigint.parseAmountrejects inputs with more fractional digits than the token allows, preventing silent truncation that could let a UI display "1.234 USDC" but submit "1.23 USDC". escapeTokenDisplaystrips ASCII control chars, Unicode bidi-override chars, and HTML metachars before any on-chain string reaches a UI.- RPC URLs passed by callers are validated against the registry via
isRpcUrlAllowed(https-only, exact host+path match). - Transaction-hash inputs to
getTransactionLinkare regex-validated to blockjavascript:open-redirect payloads.
License
MIT — see LICENSE.
