Skip to content

Repository files navigation

@sentrix/chain

CILicenseLatest release

Official TypeScript SDK for Sentrix Chain (chain ID 7119 mainnet, 7120 testnet). Six independent surfaces under one package — pick the one you actually need; tree-shaking drops the rest:

  • @sentrix/chain/evm — viem-based EVM client (standard EVM dApp door)
  • @sentrix/chain/native — typed REST client for Sentrix-shaped endpoints (validators, epochs, BFT justification, fork status)
  • @sentrix/chain/bft — WebSocket subscription manager for all 9 channels (newHeads, logs, sentrix_finalized, sentrix_jail, …) with keepalive ping + automatic reconnect + typed payloads
  • @sentrix/chain/wallet — secp256k1 keypair + Sentrix-native tx signing (same address as your MetaMask key — Sentrix derives addresses identically to Ethereum)
  • @sentrix/chain/grpc — Node-side gRPC client over @grpc/grpc-js for the chain's sentrix.v1.Sentrix service (getBlock, getBalance, getValidatorSet, getSupply, getMempool, streamEvents). Bundled .proto so version drift can't bite you.
  • @sentrix/chain/grpc-web — browser-side equivalent over @protobuf-ts/grpcweb-transport. Same surface, same chain endpoint (grpc.sentrixchain.com — Caddy transcodes gRPC-Web ↔ native gRPC).

Install

npm install @sentrix/chain viem
# or
pnpm add @sentrix/chain viem

viem is a peer-dep — bring your own version (we test against ^2.21.0).

Quick start

EVM read

import{evm}from"@sentrix/chain";constclient=evm.httpClient("mainnet");constblock=awaitclient.getBlockNumber();console.log("Current block:",block);

Native REST read

import{native}from"@sentrix/chain";constsentrix=native.nativeClient("mainnet");constinfo=awaitsentrix.chainInfo();console.log(`Height ${info.height}, ${info.active_validators} validators, supply ${info.total_minted_srx} SRX of ${info.max_supply_srx}`);constvalidators=awaitsentrix.validators();for(constvofvalidators){console.log(`${v.name??v.address}: ${v.is_active ? "active" : "jailed"} self_stake=${v.self_stake} delegated=${v.total_delegated}`);}

Watch new heads + sentrix-native channels

import{bft}from"@sentrix/chain";constmgr=newbft.SubscriptionManager("mainnet");awaitmgr.subscribe("newHeads",{onMessage: (head)=>console.log("new head:",head),});awaitmgr.subscribe("sentrix_jail",{onMessage: (event)=>console.log("jail event:",event),});// Same socket carries both subscriptions; reconnects automatically with// exponential backoff and re-subscribes everything.

The 9 channels available, all dispatched via eth_subscribe:

ChannelWhat you get
newHeadsStandard EVM block-header push
logsStandard EVM log filter (pass filter option)
newPendingTransactionsEVM mempool admission events
syncingEVM sync-status
sentrix_finalizedBFT-finalised block (after 2/3+1 precommit supermajority)
sentrix_validatorSetActive validator set rotation events
sentrix_tokenOpsNative SRC-20 Mint/Burn/Transfer/Approve/Deploy
sentrix_stakingOpsNative Delegate/Undelegate/ClaimRewards/RegisterValidator/AddSelfStake/Unjail
sentrix_jailPer-validator jail / unjail events

All sentrix-native channels go through eth_subscribe by channel name — there is no separate sentrix_subscribe method on the chain. Common confusion source.

For typed payloads (instead of unknown):

awaitmgr.subscribeTyped("newHeads",{onMessage: (head)=>console.log(head.number,head.hash),// typed as NewHeadsPayload});

Sign + broadcast a native Sentrix tx

import{native,SentrixWallet}from"@sentrix/chain";import{buildTransfer}from"@sentrix/chain/native";constw=SentrixWallet.fromPrivateKeyHex(process.env.PRIVATE_KEY!);constsentrix=native.nativeClient("mainnet");const{ nonce }=awaitsentrix.balance(w.address);constunsigned=buildTransfer({from: w.address,to: "0x0804a00f53fde72d46abd1db7ee3e97cbfd0a107",amount: 100_000_000n,// 1 SRX = 100M sentrifee: 10_000n,// 0.0001 SRX
nonce,chainId: 7119n,});constsigned=awaitw.sign(unsigned);const{ txid }=awaitsentrix.submitTx(signed);

The wallet uses the same secp256k1 derivation as Ethereum — your MetaMask private key is also a Sentrix native private key, same address on both rails.

Read via gRPC (Node only)

import{GrpcClient}from"@sentrix/chain/grpc";constc=newGrpcClient("mainnet");constblock=awaitc.getLatestBlock();constbal=awaitc.getBalance("0x4693b113e523A196d9579333c4ab8358e2656553");// Server-stream chain eventsforawait(constevofc.streamEvents([])){console.log(ev);}c.close();

The chain's sentrix.v1.Sentrix service mirrors the JSON-RPC + REST shape. v0.4+ adds getValidatorSet / getSupply / getMempool and a server-streaming streamEvents for push-style consumption without the WebSocket overhead. Older chain hosts return Status::unimplemented for the newer methods; the SDK forwards the error verbatim so callers can fall back to JSON-RPC / REST.

Browser consumers: use @sentrix/chain/grpc-web instead. Same surface, same chain endpoint — only the transport changes (@protobuf-ts/grpcweb-transport instead of @grpc/grpc-js). The /grpc subpath stays Node-only because @grpc/grpc-js needs raw HTTP/2 sockets browsers don't expose.

Read via gRPC-Web (browser)

import{GrpcWebClient}from"@sentrix/chain/grpc-web";constc=newGrpcWebClient("mainnet");constblock=awaitc.getLatestBlock();forawait(constevofc.streamEvents([])){console.log(ev);}

Same chain endpoint as the Node /grpc subpath (grpc.sentrixchain.com) — Caddy at the edge transcodes gRPC-Web ↔ native gRPC via tonic-web so server code is identical.

Network identity helpers

import{sentrixMainnet,sentrixTestnet,viemChain,CANONICAL_CONTRACTS}from"@sentrix/chain";console.log(sentrixMainnet.rpcUrl);// https://rpc.sentrixchain.comconsole.log(sentrixTestnet.faucetUrl);// https://faucet.sentrixchain.com// Drop-in viem Chain object:import{createPublicClient,http}from"viem";constclient=createPublicClient({chain: viemChain("mainnet"),transport: http(),});// Canonical contract addresses:console.log(CANONICAL_CONTRACTS.mainnet.WSRX);// 0x4693...6553

Decimals — the one thing that confuses everyone

Sentrix's underlying ledger is 8-decimal native (1 SRX = 100,000,000 sentri). The EVM tooling sees a 18-decimal view because eth_getBalance returns wei-scaled values for compatibility with MetaMask + ethers + viem.

When you use evm.httpClient(...).getBalance(...) you get 18-decimal wei. When you use native.nativeClient(...).balance(...) you get 8-decimal sentri scaled to SRX directly.

Status

v0.3.0-rc.0 — six-door surface: EVM (read + write via viem), native REST (typed read + tx submit + tx builders), BFT WebSocket (multiplexed subs + keepalive + typed payloads), wallet (secp256k1 + native tx signing), gRPC (Node-side typed client over the chain's sentrix.v1.Sentrix service), gRPC-Web (browser-side equivalent over @protobuf-ts/grpcweb-transport).

License

MIT — see LICENSE.

About

Official TypeScript SDK for Sentrix Chain — typed wrappers around the EVM JSON-RPC + native REST surface, plus WebSocket subscription helpers.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages