{"_id":"@0xsingularity/web3.js","_rev":"4-0f3926dc3d64cb169374f10637dd2bea","name":"@0xsingularity/web3.js","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@0xsingularity/web3.js","version":"0.1.0","keywords":["singularity","solana","svm","web3","blockchain"],"author":{"name":"bajpainaman","email":"naman@entropytoorder.xyz"},"license":"MIT","_id":"@0xsingularity/web3.js@0.1.0","maintainers":[{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"}],"dist":{"shasum":"939dfd2739e7a922a523126e993ec5c1c4bfe5a0","tarball":"https://registry.npmjs.org/@0xsingularity/web3.js/-/web3.js-0.1.0.tgz","fileCount":30,"integrity":"sha512-m4R87lUw9SjoLecRZUHKjZ+8UWtVhbVZLOuf4zvd8w/rAioPfoPVLb9KV+jlYgB3TYZqVjZSvI6XJS5n2QSvEg==","signatures":[{"sig":"MEUCIQCTRT3GnQ+G3mHJ/s5phCQRPxL1h1gnfDh0LhwGS3WohQIgBZs5iAusxAbcq2nBqHETwri99njZkxnPOLZjM7odsKg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78091},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","engines":{"node":">=18"},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"},"_npmVersion":"9.2.0","description":"Thin drop-in wrapper around @solana/web3.js preconfigured for the Singularity chain.","directories":{},"_nodeVersion":"22.22.2","_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^20.0.0","@solana/web3.js":"^1.98.0"},"peerDependencies":{"@solana/web3.js":"^1.87.0"},"_npmOperationalInternal":{"tmp":"tmp/web3.js_0.1.0_1785608893456_0.15992307610333234","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@0xsingularity/web3.js","version":"0.1.1","keywords":["singularity","solana","svm","web3","blockchain"],"author":{"name":"bajpainaman","email":"naman@entropytoorder.xyz"},"license":"MIT","_id":"@0xsingularity/web3.js@0.1.1","maintainers":[{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"}],"dist":{"shasum":"511c91d7a3fd9400b7190f83e1d41f8ec3b05ac5","tarball":"https://registry.npmjs.org/@0xsingularity/web3.js/-/web3.js-0.1.1.tgz","fileCount":30,"integrity":"sha512-sGbkfvt/7BVL9cOUeoyAYtWOs7ruAFG1ujYYOgLTCjDSw4rmWePkaSNL/D0KgV+pA0bknQgu9VMK8a4tHHnWMA==","signatures":[{"sig":"MEQCIEps1YHUOA8vVm1ld8UOW6SGgJmClJvYxQU900QinFUrAiApI69SdYbpmLYPCIgRN2H3kLS5QyCsSVBNyB1MhlMgHA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":81154},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","browser":{"./dist/wallet.js":false},"engines":{"node":">=18"},"gitHead":"71cf28b057c29a5a0d6d5f1171454193f9a7737e","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:756f1448-0300-489b-98ed-3d982bca67d2"}},"_npmVersion":"12.0.2","description":"Thin drop-in wrapper around @solana/web3.js preconfigured for the Singularity chain.","directories":{},"_nodeVersion":"22.23.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.6","typescript":"^5.6.0","@types/node":"^20.0.0","@solana/web3.js":"^1.98.0"},"peerDependencies":{"@solana/web3.js":"^1.87.0"},"_npmOperationalInternal":{"tmp":"tmp/web3.js_0.1.1_1785620077582_0.9188719858732524","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@0xsingularity/web3.js","version":"0.2.0","keywords":["singularity","solana","svm","web3","blockchain"],"author":{"name":"bajpainaman","email":"naman@entropytoorder.xyz"},"license":"MIT","_id":"@0xsingularity/web3.js@0.2.0","maintainers":[{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"}],"dist":{"shasum":"c4b126dfad0c60d0f2847fce6abbabc74f844302","tarball":"https://registry.npmjs.org/@0xsingularity/web3.js/-/web3.js-0.2.0.tgz","fileCount":50,"integrity":"sha512-jMMQ0kb0EOFCzfWwi3+zEg+Y5YOEZcgvgzj1XX12Lf+uYK5YEG9vF3j6p8GXwAwSXD/0MAKrfSWFzhUJuSXtKw==","signatures":[{"sig":"MEUCIB0UhgxNSiZ9Y0HPm9MjkUCkCq2wzgE2Kvv7CIYR1sBbAiEAui4+Km2o0FvIF8JqC+BmoQXJdy+SOnA0magrWsxlsiM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":170107},"main":"dist/index.js","type":"commonjs","types":"dist/index.d.ts","browser":{"./dist/wallet.js":false},"engines":{"node":">=18"},"gitHead":"b5efefce198d28e6a4c3c590db7191d27108f284","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:756f1448-0300-489b-98ed-3d982bca67d2"}},"_npmVersion":"12.0.2","description":"Thin drop-in wrapper around @solana/web3.js preconfigured for the Singularity chain.","directories":{},"_nodeVersion":"22.23.1","_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.6","typescript":"^5.6.0","@types/node":"^20.0.0","@solana/web3.js":"^1.98.0"},"peerDependencies":{"@solana/web3.js":"^1.87.0"},"_npmOperationalInternal":{"tmp":"tmp/web3.js_0.2.0_1785623030437_0.5561063471421972","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"_id":"@0xsingularity/web3.js@0.3.0","dist":{"shasum":"05f4cf226341a3ef7aa2146639be1df9569f8338","tarball":"https://registry.npmjs.org/@0xsingularity/web3.js/-/web3.js-0.3.0.tgz","fileCount":90,"integrity":"sha512-ue4QWRt3qNrjGGBxMrqnlIHy43L0dvvLhHdizBceW8WZOj5ISUI2VTaKy6EWdlsIgqhLIzlnpunHDf7nHC7ELw==","signatures":[{"sig":"MEYCIQCWGxmi1Qt4x5tXWWk8eYVgPWQr7Tkc4kk8vP8M2Ww+1QIhAMzzTlF3GFLean+SgsFQNe98Bn4xV5b1G7SDmjsKRHuO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDGKikw9yxkYaQdHG+w3qFjhBBsUH+HvkY0aRzg531hSQIhANiJd5SkrC0TUl++x4Dlop9cUzsHhfDS51jYpKsoTlPD"}],"unpackedSize":771503},"main":"dist/index.js","name":"@0xsingularity/web3.js","type":"commonjs","types":"dist/index.d.ts","author":{"name":"bajpainaman","email":"naman@entropytoorder.xyz"},"browser":{"./dist/wallet.js":false},"engines":{"node":">=18"},"gitHead":"297b7ff90ebcfe2bb52bda20004513a99c023d51","license":"MIT","scripts":{"test":"vitest run","build":"tsc -p tsconfig.build.json","clean":"rm -rf dist","typecheck":"tsc -p tsconfig.json --noEmit","prepublishOnly":"npm run build"},"version":"0.3.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:756f1448-0300-489b-98ed-3d982bca67d2"}},"keywords":["singularity","solana","svm","web3","blockchain"],"_npmVersion":"12.0.2","description":"Thin drop-in wrapper around @solana/web3.js preconfigured for the Singularity chain.","directories":{},"maintainers":[{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"}],"_nodeVersion":"22.23.2","dependencies":{"@noble/curves":"^1.4.2","@noble/hashes":"^1.8.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.6","typescript":"^5.6.0","@types/node":"^20.0.0","@solana/web3.js":"^1.98.0"},"peerDependencies":{"@solana/web3.js":"^1.87.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/web3.js_0.3.0_1789403110087_0.827199644732193"}}},"time":{"created":"2026-08-01T18:28:13.259Z","modified":"2026-09-14T16:25:10.400Z","0.1.0":"2026-08-01T18:28:13.604Z","0.1.1":"2026-08-01T21:34:37.718Z","0.2.0":"2026-08-01T22:23:50.585Z","0.3.0":"2026-09-14T16:25:10.176Z"},"author":{"name":"bajpainaman","email":"naman@entropytoorder.xyz"},"license":"MIT","keywords":["singularity","solana","svm","web3","blockchain"],"description":"Thin drop-in wrapper around @solana/web3.js preconfigured for the Singularity chain.","maintainers":[{"name":"singularitywastaken","email":"namanbajpai23@gmail.com"}],"readme":"# `@0xsingularity/web3.js`\n\nA thin, drop-in wrapper around [`@solana/web3.js`](https://github.com/solana-labs/solana-web3.js) for the **Singularity** chain.\n\nThis package re-exports `@solana/web3.js` and adds Singularity endpoint\nconfiguration, SING amounts, wallet files, a faucet helper, and an `eto_*`\nclient. The drop-in claim applies to JavaScript export identity. It does not\nclaim that every upstream RPC method or write is supported by the chain.\n\nVersion 0.2.0 is published on npm as `@0xsingularity/web3.js`.\n\n> [!WARNING]\n> **Support ceiling (2026-08-29):** This README describes SDK and repository\n> behavior, not a live public service. The audit used base\n> `bc7b834de9bf22aa35d0294f3dd16212c72d7500`. Current remediation is an\n> unreleased candidate with no published or deployed SHA. The last public-edge audit\n> found the configured endpoint unavailable. Public reads and SVM\n> transfer/deploy are **PREVIEW**. EVM, WASM, and Move writes are **DISABLED**.\n> UTH is **PREVIEW** with identity and supply work incomplete. Agents, A2A, and\n> MCP are **TARGET** capabilities. Historical finality, latency, and rate-limit\n> observations below are not current release evidence. See the\n> [capability matrix](../../docs/capability-matrix.md).\n\n## Install\n\n```bash\nnpm install @0xsingularity/web3.js @solana/web3.js\n```\n\n`@solana/web3.js` is a peer dependency, so you supply it.\n\n## Use it as a drop-in\n\nChange the import. That's the migration.\n\n```diff\n-import { Keypair, SystemProgram, Transaction } from '@solana/web3.js';\n+import { Keypair, SystemProgram, Transaction } from '@0xsingularity/web3.js';\n```\n\nEvery named export of `@solana/web3.js` is re-exported unchanged, by identity — `singularity.Keypair === solana.Keypair`. Nothing is overridden or reimplemented.\n\nThen connect:\n\n```ts\nimport { connect, checkCompat } from '@0xsingularity/web3.js';\n\nconst connection = connect();            // RPC + WS endpoints preset, commitment 'confirmed'\nawait checkCompat(connection);           // warns loudly if this isn't actually Singularity\n\nconst slot = await connection.getSlot();\n```\n\nThe default endpoint is retained for compatibility, but the last audit found\nit unavailable. Use an operator-provided endpoint and verify its tested release\nSHA before you depend on a response.\n\n`connect()` returns an ordinary `Connection`. RPC support still follows the\ncapability ceiling and the divergence list below. Some upstream methods are\nabsent, placeholders, or operator-gated.\n\n```ts\nconnect({ endpoint: 'http://127.0.0.1:8899' });  // point somewhere else\nconnect({ commitment: 'finalized' });            // any ConnectionConfig option passes through\n```\n\nSetting `wsEndpoint` matters: from an HTTPS URL, upstream would derive `wss://host:8900/`, which is wrong here. `connect()` sets the correct root-path WebSocket URL for you.\n\n## Wallets, shared with the CLI\n\n```ts\nimport { createWallet, loadWallet, loadOrCreateWallet } from '@0xsingularity/web3.js';\n\nconst wallet = createWallet();            // ~/.config/singularity/id.json\nconsole.log(wallet.publicKey.toBase58());\n\nconst keypair = loadWallet();             // the same file the CLI reads\n```\n\nThe file is the ordinary `solana-keygen` format — a JSON array of 64 bytes. A wallet made by `singularity wallet new` loads here, and a wallet made here works with `solana --keypair`. The default path honours `SINGULARITY_WALLET`, exactly like the CLI.\n\n`createWallet` refuses to overwrite an existing file unless you pass `{ force: true }`, because overwriting a keypair destroys funds. These functions use `node:fs`, so they are Node-only; the rest of the package runs in a browser. Browser bundlers replace the wallet module with an empty stub (via the `browser` field), so importing the browser-safe exports never pulls in `node:fs`.\n\n## SING, not SOL\n\n```ts\nimport {\n  LAMPORTS_PER_SING, singToLamports, lamportsToSing, formatSing,\n  getBalanceSing, requestAirdrop,\n} from '@0xsingularity/web3.js';\n\nconst balance = await getBalanceSing(connection, wallet.publicKey);   // 1.5\nformatSing(1_500_000_000);                                            // \"1.5\"\n\nconst signature = await requestAirdrop(connection, wallet.publicKey, 1);\n```\n\n`requestAirdrop` converts SING to lamports, calls `connection.requestAirdrop`, and polls until the transfer confirms. The faucet's rejections come back typed:\n\nThis is an SVM technical-preview write helper. The audit found no available\npublic faucet or edge, so the example is not proof that funding works now.\n\n| Error | When |\n|---|---|\n| `FaucetCapError` | Above the 10 SING per-request cap (code `-32602`) |\n| `FaucetRateLimitError` | A daily cap was reached (code `-32005`) |\n| `FaucetError` | Any other faucet rejection |\n| `AirdropConfirmationError` | Accepted, then failed or timed out — carries the `signature` |\n\n```ts\ntry {\n  await requestAirdrop(connection, wallet.publicKey, 50);\n} catch (error) {\n  if (error instanceof FaucetCapError) { /* ask for less */ }\n}\n```\n\nThe scale is nine decimals, the same as SOL, so upstream's `LAMPORTS_PER_SOL` is numerically correct. `LAMPORTS_PER_SING` is that number under the right name.\n\n## `eto_*` — the chain's own RPC\n\nThe repository defines five VM namespaces over a shared state design, but their\nsupport levels differ. `@solana/web3.js` cannot call the `eto_*` namespace, so\nthis package includes a small typed client. Two token identities still coexist.\nUTH identity unification and supply reconciliation are incomplete.\n\n```ts\nimport { connect, EtoRpc } from '@0xsingularity/web3.js';\n\nconst eto = EtoRpc.fromConnection(connect());\n\nconst stats = await eto.getStats();\nstats.block_height;      // 2124558\nstats.vm_support;        // ['svm', 'evm', 'wasm', 'move', 'zk']\n\nconst tx = await eto.getTransaction(signature);   // null when unknown\ntx?.vm;                  // 'svm'\n\nawait eto.getUniversalToken(tokenAccount);        // the token-ACCOUNT address, not the mint\nawait eto.getUniversalTokensByOwner(owner);       // [] when none\nawait eto.getAccountTransactions(address);        // first page (25); [] when none\nawait eto.getAccountTransactions(address, { limit: 100, offset: 100 }); // page 2 of 100\nawait eto.search('some-address-or-signature');    // hits carry a `type`\n```\n\n| Method | JSON-RPC | Returns |\n|---|---|---|\n| `getStats()` | `eto_getStats` | `EtoStats` |\n| `getTransaction(sig)` | `eto_getTransaction` | `EtoTransaction \\| null` |\n| `getUniversalToken(tokenAccount)` | `eto_getUniversalToken` | `EtoUniversalToken \\| null` |\n| `getUniversalTokensByOwner(owner)` | `eto_getUniversalTokensByOwner` | `EtoUniversalToken[]` |\n| `getAccountTransactions(address, {limit, offset}?)` | `eto_getAccountTransactions` | `EtoTransaction[]` (paginated: server default 25/page, cap 100) |\n| `search(query)` | `eto_search` | `EtoSearchResult[]` |\n| `call(method, params)` | anything | `unknown` |\n\nThe legacy explorer methods in this table were observed on the configured\nendpoint on 2026-08-01. That is historical evidence, not evidence for a current\nrelease: the later public-edge audit found the endpoint unavailable. Their\nresponse types name only fields from that earlier observation and allow unknown\nkeys. Treat every field as optional at runtime. The OneBook methods below are\nversioned protocol contracts and require a node deployment with OneBook\nenabled. Use `call()` for a method that has no wrapper yet.\n\n> `getUniversalToken` takes the base58 **token-account** address (the `account` field of the result), not the mint. Passing a `0x` hex mint returns `-32602 invalid base58 account pubkey`.\n\nThe client uses the global `fetch` (Node 18+). Pass `{ fetch }` to supply your own.\n\n### OneBook RPC and SDK\n\nOneBook exposes its committed SkippyDB state, exact CUDA artifacts, Commonware\nfinality proofs, and unsigned VM admission payloads through the same `EtoRpc`\nclient. Full-width heights and sequences should be passed as `bigint` or a\ncanonical decimal string; unsafe JavaScript numbers are rejected.\n\n```ts\nconst instance = '0x…'; // 32-byte OneBook instance id\nconst abi = await eto.getOneBookAbi();\nconst status = await eto.getOneBookStatus(instance);\nconst block = await eto.getOneBookExecutionBlock(instance, 42n);\nconst proof = await eto.getOneBookFinalityProof(42n);\nif (proof) await eto.verifyOneBookFinalityProof(proof);\n```\n\n| SDK methods | Purpose |\n|---|---|\n| `getOneBookManifest`, `getOneBookMetadata`, `getOneBookAccount`, `getOneBookOrder`, `getOneBookFreePosition`, `getOneBookTransition`, `getOneBookStatus` | Read committed instance and recovery state |\n| `getOneBookAbi`, `encodeOneBookCommand` | Discover the wire contract and encode semantic commands |\n| `getOneBookExecutionBlock`, `getOneBookExecutionArtifact` | Read exact per-height CUDA execution evidence |\n| `getOneBookFinalityProof`, `verifyOneBookFinalityProof` | Read and verify Commonware/SkippyDB finality evidence |\n| `buildOneBookSvmInstruction`, `buildOneBookVmCall` | Build unsigned SVM/EVM/WASM/Move/ZK admission payloads |\n\n### Bombil offline codecs\n\nThe SDK exports strict codecs for the eight-byte lifecycle profile, 40-byte\n`BLC1` lifecycle controls and bounded `BSG1` registered SVM requests. All u64\nfields use `bigint`. The lifecycle tests read the same native CUDA golden\nvectors as Rust; malformed versions, reserved bytes and integer truncation\nare rejected.\n\n```ts\nimport {\n  encodeBombilLifecycleProfile,\n  encodeBombilLifecycleCommand,\n} from '@0xsingularity/web3.js';\n\nconst profile = encodeBombilLifecycleProfile({\n  version: 1,\n  watchSlots: 2,\n  maximumFillCapacity: 64,\n  controlCapacity: 1,\n  maximumFillsPerCommand: 4,\n});\nconst request = encodeBombilLifecycleCommand({\n  kind: 'reserve', account: 0, nonce: 0n, fillCapacity: 8,\n});\n```\n\nThese helpers produce bytes for offline tooling and an explicitly installed\nBombil runtime adapter. The new route is inactive on the network; encoding\ndoes not grant authority, allocate a watch or establish financial durability.\n`BSG1` must not be submitted through the legacy OneBook command builder.\n\n## The whole RPC surface — `SingularityRpc`\n\n`EtoRpc` covers the popular methods with verified result types. The rest of the\nnode — 289 HTTP methods across 13 namespaces, mirrored one for one from the\nnode's dispatch tables — is on `SingularityRpc`. Every method exists as a named\nfunction on its namespace, so your editor completes it and a typo fails at\ncompile time:\n\n```ts\nimport { SingularityRpc } from '@0xsingularity/web3.js';\n\nconst client = new SingularityRpc(); // or SingularityRpc.fromConnection(connect())\n\nawait client.svm.getSlot();                          // getSlot\nawait client.evm.getBalance('0xabc…', 'latest');     // eth_getBalance\nawait client.move.moveView({ /* view request */ });  // eto_moveView\nawait client.wasm.wasmQuery(contract, query);        // eto_wasmQuery\nawait client.onebook.getOrder(orderId);              // eto_oneBookGetOrder\nawait client.hilsa.chainHead('bitcoin');             // hilsa_chainHead\nawait client.agent.a2aListCards();                   // eto_a2aListCards\nawait client.explorer.getStats();                    // eto_getStats\nawait client.admin.validatorSet();                   // eto_validatorSet\nawait client.rpc('eto_brandNewMethod', [1]);         // escape hatch, any wire name\n```\n\n| Namespace | Methods | Covers |\n|---|---|---|\n| `svm` | 49 | Solana-compatible methods, plus `faucet` |\n| `evm` | 46 | `eth_*`, `net_*`, `web3_*`, `txpool_*`, `debug_*` |\n| `explorer` | 7 | the chain's own transaction/account/search reads |\n| `wasm` | 7 | CosmWasm-compatible queries and deploys |\n| `move` | 17 | Move reads, views, simulation, deploys |\n| `admin` | 8 | validator administration and membership |\n| `hilsa` | 50 | cross-chain ingestion: attestations, proofs, anchors, transfers |\n| `cil` | 27 | deprecated `eto_cil*` aliases for `hilsa` (one release) |\n| `token` | 2 | Universal Token reads |\n| `onebook` | 17 | order-book reads and transaction builders |\n| `workflow` | 2 | `eto_buildWorkflow`, `eto_buildDeploy` |\n| `crossvm` | 9 | cross-VM dispatch, canonical state hash, ZK helpers |\n| `agent` | 48 | A2A cards and tasks, MCP tools, agent registry |\n\nTyping is pragmatic: positional params in, `unknown` out (pass a type argument\nwhen you know the shape). For the popular reads with verified shapes, prefer\n`EtoRpc` above or the `Connection` you already know.\n\nThe method list itself is exported as `RPC_MANIFEST` (per namespace),\n`ALL_RPC_METHODS` (flat), and `WS_METHODS` + `ETH_SUBSCRIPTION_TYPES` for the\nWebSocket subscription surface (`eth_subscribe` types `newHeads`,\n`newPendingTransactions`, `logs`, plus the Solana `*Subscribe`/`*Unsubscribe`\npairs). The completeness tests fail if the client and the manifest ever drift.\n\n## Divergences, encoded in code\n\nThe chain docs describe Singularity's differences from Solana as prose you have to remember. These helpers encode them so they either do the right thing automatically or fail loudly.\n\n**Read a token balance — `readUniversalToken`.** This helper decodes the\nowner-gated 84-byte UTH layout without Solana token-account parsing. The format\nrecords one of five VM origins, but that does not mean every VM is production\nenabled or that UTH is a unified native asset:\n\n```ts\nimport { readUniversalToken, VmOrigin } from '@0xsingularity/web3.js';\n\nconst header = await readUniversalToken(connection, tokenAccount);\nif (header) {\n  header.amount;                    // bigint\n  header.vmOrigin === VmOrigin.SVM; // 0 SVM, 1 EVM, 2 WASM, 3 Move, 4 ZK\n}\n```\n\n`readUniversalToken` is the safe path. The header starts with the magic `55 54 48 00 01 E7 0F A5` (`UNIVERSAL_TOKEN_MAGIC`), which rules out *accidental* type confusion — under the earlier magic-less 76-byte layout, a recorded WASM program account decoded with its module bytes in the `mint` field. But the magic is structural, not proof of authenticity: any account can write those bytes into its own data. `readUniversalToken` therefore also gates on the account's owning program (`UNIVERSAL_TOKEN_PROGRAM_ID`) before decoding, so a non-token account returns `null`. The lower-level `decodeUniversalTokenHeader(bytes)` verifies the magic and rejects anything without it, but does not check the owner — use it only on bytes you already know came from a genuine token account. An unrecognised `vmOrigin` byte makes `vmOriginName` return `'unknown'` rather than throw.\n\n**Pack big batches — `packInstructions`.** Repository protocol constants do not\nset a per-block compute-unit limit. Blocks remain bounded by payload bytes (15\nMiB) and count, while transactions use a 1 MiB cap (`SVM_MAX_TX_BYTES`). This is\na source-level technical-preview constraint, not public throughput evidence.\n`packInstructions` splits instruction lists against the transaction limit.\n\n```ts\nimport { packInstructions, serializeUnchecked } from '@0xsingularity/web3.js';\n\nconst { transactions, maxSerializedBytes } = packInstructions(instructions, { feePayer });\n```\n\nOne honest limit: upstream `Transaction.serialize()` refuses anything over Solana's 1,232-byte packet cap, and upstream `Message.serialize()` writes the instruction section into a fixed 1,232-byte buffer while indexing accounts with a single byte (max 256 keys). So a packed transaction **does** exceed Solana's 1,232-byte total-wire cap — account keys and signatures live outside that buffer — but tops out around a couple of KB in practice, **not** 1 MiB. Reaching further means hand-encoding the message and bypassing the upstream codec, which this package does only for its own envelopes (below). `serializeUnchecked` produces the wire bytes upstream `serialize()` would reject. Submit them only as an explicitly authorized SVM preview test on a controlled endpoint.\n\n**WASM/Move envelope encoders are unsupported internals.**\n`buildWasmDeploy`, `buildMoveDeploy`, and `buildMoveExecute` remain only for\ntest-fixture construction and protocol analysis. The public WASM and Move\ndeploy/execute products are disabled. Applications must not submit these\nenvelopes as a customer workflow. `eto_deployMove` always rejects and therefore\nhas no server-built message for a client to reproduce. WASM still lacks its\nrequired deterministic bounded profile, while Move lacks a pinned\ncompiler/framework/native migration and production package conformance.\n\n**Repository fee model — `estimateFee`.** The executor code debits `5,000\nlamports per signature + 1 lamport per compute unit`\n(`LAMPORTS_PER_SIGNATURE`, `LAMPORTS_PER_COMPUTE_UNIT`) from the fee payer.\n`getFeeForMessage` reports only the signature term, so `estimateFee` also runs\n`simulateTransaction` and adds `unitsConsumed`. This is technical-preview\nbehavior, not a current public fee quote.\n\n**Poll a receipt — `sendAndConfirm`.** This helper targets the one-hop model\nobserved in prior private runs. It sends once and polls `getSignatureStatuses`.\nThe node reports `confirmationStatus: 'finalized'` for a landed transaction, so\nthat field alone is not independent finality evidence:\n\n```ts\nimport { sendAndConfirm } from '@0xsingularity/web3.js';\n\nconst sig = await sendAndConfirm(connection, tx, [payer], { pollIntervalMs: 100 });\n```\n\nIn a historical endpoint measurement, the first confirmation in a process was\nabout 311 ms with `sendAndConfirmTransaction` and 138 ms with this helper. The\nmeasurement has no current deployed-SHA artifact and must not be presented as\ncurrent latency. On a reachable private endpoint, tune `pollIntervalMs` for\nthat environment.\n\n**429 backoff, on by default.** Earlier endpoint behavior included per-IP HTTP\n429 responses. This is historical, not a current public rate-limit guarantee.\n`connect()` wraps fetch with exponential backoff and jitter and honors\n`Retry-After`. Opt out with `connect({ retryOn429: false })`, or tune it with\n`connect({ retryOn429: { maxRetries: 3 } })`.\n\n**Machine-readable caveats.** The RPC divergences and absent instructions are exported as typed constants so a linter or preflight check can consult them instead of trusting a human to have read the docs: `SINGULARITY_PLACEHOLDER_METHODS`, `SINGULARITY_DIVERGENT_METHODS`, `SINGULARITY_SILENT_TRUNCATION` (with `checkSilentTruncation` / `warnIfSilentlyTruncated` for the only two truncations a client cannot otherwise detect), and `SINGULARITY_ABSENT_INSTRUCTIONS`.\n\n## What this package adds\n\n| Export | Purpose |\n|---|---|\n| `connect(config?)` / `SingularityConnection` | Preconfigured `Connection` |\n| `checkCompat(connection, opts?)` | Verifies `getGenesisHash`; warns, or throws with `{ throwOnMismatch: true }` |\n| `createWallet` / `loadWallet` / `loadOrCreateWallet` / `saveWallet` / `defaultWalletPath` | Keypair files the CLI also reads |\n| `requestAirdrop` / `getBalanceSing` | SVM PREVIEW faucet helper and balance read, in SING, with typed errors |\n| `LAMPORTS_PER_SING` / `singToLamports` / `lamportsToSing` / `formatSing` | SING amounts (`singToLamports` rejects sub-lamport dust) |\n| `EtoRpc` | Typed client for the `eto_*` namespace |\n| OneBook command, ABI, proof, page, and RPC types/helpers from `onebook` | CUDA OneBook admission, committed-state reads, recovery, and proof verification |\n| `readUniversalToken` / `decodeUniversalTokenHeader` / `vmOriginName` / `VmOrigin` / `UNIVERSAL_TOKEN_PROGRAM_ID` | Universal Token Header: owner-gated safe read + raw decoder |\n| `packInstructions` / `serializeUnchecked` | Pack instructions past Solana's 1232-byte cap |\n| `sendAndConfirm` / `confirmSignature` | SVM PREVIEW polling helper for the prior one-hop model |\n| `buildWasmDeploy` / `buildMoveDeploy` / `buildMoveExecute` | Unsupported test-fixture encoders. Public WASM/Move deploy and execution are disabled |\n| `estimateFee` | Repository fee estimate from `getFeeForMessage` plus simulated compute units |\n| `signEnvelope` / `sendEnvelope` / `withRecentBlockhash` / `unsignedEnvelopeBytes` | Low-level envelope primitives. Disabled VM workflows must not submit them |\n| `wasmDeployRent` / `minimumBalance` / `LAMPORTS_PER_SIGNATURE` / `LAMPORTS_PER_COMPUTE_UNIT` | Rent and fee arithmetic, mirrored from the runtime |\n| `WASM_PROGRAM_ID` / `MOVE_PROGRAM_ID` / `WORKFLOW_ROUTER_PROGRAM_ID` / `WASM_DEPLOY_MAGIC` | Program ids and markers of the other runtimes |\n| `withRateLimitBackoff` | The 429 backoff `connect()` installs |\n| `SINGULARITY_PLACEHOLDER_METHODS` / `SINGULARITY_DIVERGENT_METHODS` / `SINGULARITY_SILENT_TRUNCATION` / `SINGULARITY_ABSENT_INSTRUCTIONS` | Machine-readable divergence caveats |\n| `SINGULARITY_MAINNET` | Cluster descriptor (endpoints, genesis hash, chain id, epoch length) |\n| `SINGULARITY_RPC_URL` / `SINGULARITY_WS_URL` | `https://rpc.entropytoorder.xyz` / `wss://rpc.entropytoorder.xyz/` |\n| `SINGULARITY_GENESIS_HASH` | `48e8a6FHB3CANQetLYE83frAu5zUy12uBiE75bdq5tYo` |\n| `SINGULARITY_CHAIN_ID` | `0x454f` (17743) |\n| `SINGULARITY_SLOTS_PER_EPOCH` | `432000` (release schedule; protocol v8 halts before the first boundary) |\n| `SINGULARITY_LIMITS` | Repository request and transaction limit constants |\n| `SINGULARITY_SUPPORTED_SUBSCRIPTIONS` | Declared WebSocket methods. Current public availability is unverified |\n| `SINGULARITY_ACCEPTED_ELF_FLAGS` | `[0x0, 0x20]` — see below |\n\n## What differs from Solana\n\nRead this section once. It is short on purpose; consult the chain docs for the full detail.\n\n**SVM deployment is a technical preview.** Repository tests accept ELF\n`e_flags` of `0x0` (v1) or the legacy `0x20` marker and reject plain version\nencodings (`1`, `2`, `3`). Earlier end-to-end evidence found that a program\nbuilt with a modern default toolchain deployed but did not execute. This is not\ncurrent public deployment evidence. Verify a file before any private test:\n\n```bash\nreadelf -h target/deploy/my_program.so    # want: Flags: 0x0\n```\n\nor use `singularity check-program my_program.so` from the companion `singularity-cli` package. This is chain issue **#763** and it is the single most expensive mistake you can make here.\n\n**No TPU / QUIC.** Repository behavior returns `null` TPU addresses from\n`getClusterNodes`. An explicitly authorized SVM preview submission uses RPC.\n`solana program deploy` may need `--use-rpc` on that controlled endpoint.\n\n**Repository nodes always run preflight.** They accept `skipPreflight`,\n`preflightCommitment`, and `maxRetries` from the client but ignore them. Do not\nrely on skipping simulation in a controlled preview.\n\n**The repository transaction cap is 1 MiB**, not Solana's 1,232 bytes.\n\n**Repository request caps:** 100 addresses per `getMultipleAccounts`, 256 calls\nper JSON-RPC batch.\n\n**`voteSubscribe` is not implemented.** `blockSubscribe` is operator-gated.\nEarlier endpoint observations covered `signatureSubscribe`, `logsSubscribe`,\n`accountSubscribe`, `programSubscribe`, `slotSubscribe`, and `rootSubscribe`.\nTheir current public availability is unverified.\n\n**`Clock.unix_timestamp` is real unix seconds, but derived from the slot** (genesis + slot × 230 ms). Deadline and duration checks behave correctly; the value drifts from wall-clock time across chain halts. Do not use it as a trusted wall clock.\n\n**The base unit is SING.** Anything re-exported from upstream labels amounts\n\"SOL\", because the Solana codebase has no deployment ticker. `LAMPORTS_PER_SOL`\nis still numerically correct. Use `LAMPORTS_PER_SING`, `formatSing`, and\n`getBalanceSing` when the label matters. This naming does not resolve the UTH\nidentity and supply gap.\n\n## Bombil owner-request accounting\n\n```ts\nimport {\n  bombilRequestRecordAddress, decodeBombilRequestRecord, readBombilRequestRecord,\n} from '@0xsingularity/web3.js';\n\nconst record = decodeBombilRequestRecord(accountData);\nconst address = bombilRequestRecordAddress(record);\nconst observation = await readBombilRequestRecord(connection, address);\n```\n\n`decodeBombilRequestRecord` validates the exact BRQ1 version-1 record from\n`runtime/src/programs/bombil_candidate/requests.rs`: a 252-byte header with up to\n1,024 returned bytes. Every u64 remains a `bigint`; `transactionIndex` is a u32\nnumber. Identity and returned byte arrays are copied. Invalid reserved fields,\nlengths, nonzero-identity requirements, height/deadline/retention order and\ncompute bounds throw `BombilCodecError`.\n\n`terminal` is either `{ kind: 'returned', output }` or\n`{ kind: 'reverted', code, financialReason }`. `BOMBIL_REQUEST_FAILURE_NAMES`\nmaps local codes 1–12 to the exact Rust accounting variants: `DomainBusy`,\n`CandidatePoisoned`, `InvalidConfiguration`, `InactiveScope`, `ScopeFailed`,\n`StaleHandle`, `StaticMutation`, `BudgetExceeded`, `FinancialRejected`,\n`InvalidArtifact`, `Journal`, `Participant`. The financial reason is an\nuninterpreted byte; only code 9 may carry a nonzero value. These codes are\nseparate from the guest error ABI.\n\n`bombilRequestRecordAddress` derives the owner-scoped PDA under\n`ONEBOOK_PROGRAM_ID`. `readBombilRequestRecord` performs one standard\n`getAccountInfo` read via `Connection.getAccountInfoAndContext`, checks the owner,\nnon-executable metadata, canonical record and derived address, then returns\n`{ address, slot, record }`. Missing accounts return `null`; malformed/foreign\naccounts and RPC failures throw. An optional commitment is passed to the\nconnection; the server's ordinary account response is not an independent\ndurability proof.\n\nActual consumed compute includes failed execution, but the record does not\nitself charge fees. `retainUntil` is a retention bound; pruning is not implemented.\nReplay status is not encoded. These helpers do not sign, submit or activate a\nnetwork route. The shared SDK golden fixture is also checked by the production\nRust encoder, decoder and PDA derivation in `request_tests.rs`.\n\n## Bombil local representation inspection\n\n```ts\nimport {\n  decodeBombilConversionRequest, decodeBombilRepresentationRecord,\n  bombilRepresentationBindingFingerprint, bombilRepresentationAddresses,\n  readBombilRepresentation,\n} from '@0xsingularity/web3.js';\n\nconst request = decodeBombilConversionRequest(blm1Bytes);\nconst record = decodeBombilRepresentationRecord(brp1Bytes);\nconst addresses = bombilRepresentationAddresses(approvedBinding);\nconst observation = await readBombilRepresentation(connection, approvedBinding, 'finalized');\n```\n\nThese helpers match `runtime/src/programs/bombil_conversion.rs`. BLM1 is a\n96-byte retained-call **request**, with operation 1 (`deposit`) or 2 (`redeem`),\nbig-endian u64 nonce/amount, actor and recipient addresses, and a classic SPL\ntoken-account public key. It is not a stored binding or proof of authority.\nBRP1 is a 96-byte version-1 accounting record with a binding hash, little-endian\nu64 `nextNonce`, `accountedCollateral`, `retiredLockedFloor`, and big-endian U256\n`unallocatedSurplus`. Both decoders enforce exact lengths and canonical fields,\ncopy byte arrays, and preserve all u64/U256 values as `bigint`.\n\n`BombilRepresentationBindingV1` is an expected policy supplied by the caller:\n`chainDomain`, `evmChainId`, `instanceId`, `administrator`, `vault`,\n`vaultSha256`, `token`, `tokenKeccak256`, `tokenBalanceMappingSlot`, `route`,\n`mint`, and `decimals`. Public keys are `PublicKey`, EVM addresses are 20-byte\narrays, hashes/domains/slots are 32-byte arrays, `evmChainId` is a u64 `bigint`,\nand `decimals` is a u8 number. Its fingerprint binds every field. The accounting\nPDA is a singleton per instance and mint under `ONEBOOK_PROGRAM_ID`; changing\nthe expected vault changes the fingerprint, not that singleton address.\n\n`readBombilRepresentation` reads six accounts in one standard\n`getMultipleAccounts` response: the derived BRP1 row, mint, ERC-20 collateral\nstorage, vault accounting storage, vault code, and token code. It verifies the\nrecord's OneBook owner/non-executable metadata and supplied binding hash; exact\nclassic SPL mint layout, decimals, initialization, absent freeze authority and\nderived mint-authority PDA; EVM storage owner/layout; and bounded code hashes.\nMissing BRP1 returns `null`. Missing backing, malformed or foreign rows, policy\nmismatches and RPC errors throw. The policy is copied before awaiting RPC.\n\nAll amounts are raw base units. The result separates recorded accounting from\nobservations:\n\n- `lastReconciledSupply` is recorded collateral minus the recorded retirement floor.\n- `mintSupply` is the observed current SPL supply. A later direct SPL burn can\n  increase `observedRetiredLocked` and `pendingRetirement`; it creates no credit.\n- `actualCollateral` and `observedUnallocatedSurplus` reflect the observed ERC-20\n  balance. Donations may make surplus differ from the last recorded U256 value.\n- `checks` explicitly reports vault-counter agreement, preservation of the\n  retirement floor, and collateral coverage. Impossible derived amounts are\n  `null`; a successful read can still contain failed checks.\n\nThe v1 adapter has no route to decrease or recover the retired locked floor.\nSurplus is not redeemable credit. Results verify observations against the\n**supplied** policy, not an independently attested deployment. The returned RPC\ncontext `slot` is not an independent atomic snapshot, QMDB durability proof or\nauthorization to convert. These helpers do not fund, sign, submit or activate\nthe inactive dispatcher.\n\n## Develop\n\n```bash\nnpm install\nnpm run typecheck   # tsc --noEmit, strict\nnpm run build       # emits dist/ with .d.ts\nnpm test            # vitest, 222 tests, no network access\n```\n\nTests cover the constants, the drop-in re-export surface, `connect()` (including the WebSocket-endpoint regression and 429 backoff), `checkCompat()`, wallet round-trips through a temporary directory, the SING conversion maths (including sub-lamport dust rejection), the faucet error mapping, the exact JSON-RPC envelope `EtoRpc` builds, the Universal Token Header decoder (against a recorded account fixture) and its owner-gated read, instruction packing, `sendAndConfirm`, and the WASM/Move envelopes (hand-derived byte fixtures for both encodings, a cross-check of the Solana encoding against upstream's own codec and signature verification, and `estimateFee` against a stub RPC). None of them touch the network.\n\n## Registered Bombil peer calls\n\n`encodeBombilWasmPeerRequest`, `encodeBombilEvmPeerRequest`, and\n`encodeBombilMovePeerRequest` build the BWP1, BEP1, and BMP1 payloads for the\nregistered guest `call_peer` import. Persisted owner-signed grants select the\nactual target, code, selector, access, and limits. These helpers do not install\nor activate a network route.\n\n```ts\nimport { encodeBombilEvmPeerRequest, encodeBombilWasmPeerRequest } from '@0xsingularity/web3.js';\n\nconst evmCall = encodeBombilEvmPeerRequest({ grant: peerGrant, calldata });\nconst wasmCall = encodeBombilWasmPeerRequest({ peerGrant, tradeGrant, input });\n```\n\nEVM calldata includes the four-byte selector; its actual return bytes are\npassed through. WASM returns BWO1 accounting, decoded by\n`decodeBombilWasmPeerResult`. Move returns BMO1 accounting and actual return\nvalues, decoded by `decodeBombilMovePeerResult`. The Move request encodes\nnon-generic resource tags as `{ address, type: { address, module, name } }`;\narguments are already encoded Move values. The current native profile permits\none self-contained module, at most 16 arguments and eight existing resources,\nand no type arguments, signer construction, native functions or events.\n\n`encodeBombilZkRequest` builds BRZ1 operations: `verify` supplies an existing\naction grant and a 128-byte compressed BN254 Groth16 proof; `request` supplies\na grant and a nonzero 32-byte public-input commitment; `consume` supplies an\nexisting job and a proof. `decodeBombilZkRequest` validates only framing, while\nthe native verifier checks the proof against the registered statement.\n`decodeBombilZkResult` decodes BZO1 nullifiers, pending job keys and completion\nkeys. It does not prove cryptographic validity, finality or durability.\n\nAll result decoders describe tentative guest-call results. An ancestor may\nstill revert the complete invocation. Shared Rust/TypeScript encoding vectors\nlive in `test/fixtures/bombil-{peer,zk}-dispatch-v1.json`.\n","readmeFilename":"README.md"}