{"_id":"@canopynetwork/canopy-ts","_rev":"6-c177c25a88f29555fb95f591ed35877d","name":"@canopynetwork/canopy-ts","dist-tags":{"latest":"0.8.0"},"versions":{"0.3.0":{"name":"@canopynetwork/canopy-ts","version":"0.3.0","_id":"@canopynetwork/canopy-ts@0.3.0","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"homepage":"https://github.com/canopy-network/canopy-ts#readme","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"dist":{"shasum":"c5d54975e9941a707cbdae75515d4e2e15db0dc4","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.3.0.tgz","fileCount":36,"integrity":"sha512-XmAtMx3JTm21fM23SqFXNw14Cr/wJ0xCNfmgXNY6V4Z/nRNGqPW2XdLrfjvxnk7X/KHN2DqPFY0Q5v4y4Jzp2g==","signatures":[{"sig":"MEYCIQDA5cUyILj4u9vAtPewaq+9BzFDJ3CKQkbYuXKpU3/AYQIhALKeazmhXQpcwPyR9XWD+c/ue6WksEzr5xzApRNjA2b1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":57588},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"}},"gitHead":"f5ccbbf3744a88791cdd034c9826390046bc27cd","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","prepare":"tsc"},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"repository":{"url":"git+https://github.com/canopy-network/canopy-ts.git","type":"git"},"_npmVersion":"11.13.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^4.4.3","protobufjs":"^7.4.0","@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.0.0"},"_npmOperationalInternal":{"tmp":"tmp/canopy-ts_0.3.0_1780748130365_0.0033977928542505698","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@canopynetwork/canopy-ts","version":"0.4.0","_id":"@canopynetwork/canopy-ts@0.4.0","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"homepage":"https://github.com/canopy-network/canopy-ts#readme","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"dist":{"shasum":"033cc7d29f387c15e20698f1c2b5dd3950fca855","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.4.0.tgz","fileCount":43,"integrity":"sha512-9ziICSCNLxfCJNdN7TJy5q/ik6JyfPpL7wXs2uGkofwQWCWUX8K4POH7xqblyb4CuPF56WTR/1a6I+hdG/K7Gw==","signatures":[{"sig":"MEUCIGG1vkPFpYVYPa4wF13IqfHR6D4I+GU6PNc/1k/EYNANAiEA32SMlzihbnKbi7dYgYIVD1DF89Dm38ocK7MPiz4Irnk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78252},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./proto":{"default":"./dist/proto/"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"}},"gitHead":"f5ccbbf3744a88791cdd034c9826390046bc27cd","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc && npm run postbuild","prepare":"tsc && npm run postbuild","postbuild":"node scripts/copy-ws-protos.cjs"},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"repository":{"url":"git+https://github.com/canopy-network/canopy-ts.git","type":"git"},"_npmVersion":"11.13.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^4.4.3","protobufjs":"^7.4.0","@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.0.0"},"publishedWsProtos":["ws_frame.proto","dice_ws.proto","plinko_ws.proto","market_ws.proto","account.proto"],"_npmOperationalInternal":{"tmp":"tmp/canopy-ts_0.4.0_1780814510711_0.5578224655789674","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@canopynetwork/canopy-ts","version":"0.4.1","_id":"@canopynetwork/canopy-ts@0.4.1","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"homepage":"https://github.com/canopy-network/canopy-ts#readme","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"dist":{"shasum":"5df53c1c70a57298ec7b82d0845da0572b7f7508","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.4.1.tgz","fileCount":43,"integrity":"sha512-60fKBOfxKS10oKaBCKtQh5OOaaLwlvQYZOk7eSJm86HQ1AocGzNsy4lFi/2NEBDXBZZ23tN4L2BY07k88rjL/Q==","signatures":[{"sig":"MEUCIE2oH3t7iPLU9OECX6fZcOJrbPQvmEE8bYrPsvn39PZXAiEAzvBS3r0jgmmHSZhZXSKGNnYzG63HQJk+fNF/dEhRNNE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78262},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./proto":{"default":"./dist/proto/"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"}},"gitHead":"f5ccbbf3744a88791cdd034c9826390046bc27cd","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc && npm run postbuild","prepare":"tsc && npm run postbuild","postbuild":"node scripts/copy-ws-protos.cjs"},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"repository":{"url":"git+https://github.com/canopy-network/canopy-ts.git","type":"git"},"_npmVersion":"11.13.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^4.4.3","protobufjs":"^7.4.0","@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.0.0"},"publishedWsProtos":["ws_frame.proto","dice_ws.proto","plinko_ws.proto","market_ws.proto","account.proto"],"_npmOperationalInternal":{"tmp":"tmp/canopy-ts_0.4.1_1780814729981_0.24202584759793444","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@canopynetwork/canopy-ts","version":"0.4.2","_id":"@canopynetwork/canopy-ts@0.4.2","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"homepage":"https://github.com/canopy-network/canopy-ts#readme","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"dist":{"shasum":"5a3927f720b1466bd5dedde9e24bc03051e47173","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.4.2.tgz","fileCount":43,"integrity":"sha512-VnZKBPlIJOn4giMMZw9/uDz7eqp/ihOvlTV2JUhiCIc6i4Wn1AMWttK6UadTjt813AP10Dl+lR0oL4QBj3vxDQ==","signatures":[{"sig":"MEYCIQDAlEhQrNUU57QMnq7qLwiPCUivTWtF3ki0k4vsBjafNgIhAKJ5f4PXotzrCeqEkgziQBnCqMyGgCiWCKSmRbAlXNx/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":78272},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./proto":{"default":"./dist/proto/"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"}},"gitHead":"f5ccbbf3744a88791cdd034c9826390046bc27cd","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc && npm run postbuild","prepare":"tsc && npm run postbuild","postbuild":"node scripts/copy-ws-protos.cjs"},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"repository":{"url":"git+https://github.com/canopy-network/canopy-ts.git","type":"git"},"_npmVersion":"11.13.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^4.4.3","protobufjs":"^7.4.0","@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.0.0"},"publishedWsProtos":["ws_frame.proto","dice_ws.proto","plinko_ws.proto","market_ws.proto","account.proto"],"_npmOperationalInternal":{"tmp":"tmp/canopy-ts_0.4.2_1780815157346_0.5810678643100864","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@canopynetwork/canopy-ts","version":"0.6.0","_id":"@canopynetwork/canopy-ts@0.6.0","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"homepage":"https://github.com/canopy-network/canopy-ts#readme","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"dist":{"shasum":"6979c659ee518b1cf4b7d7597e80eb02abf8a02e","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.6.0.tgz","fileCount":43,"integrity":"sha512-C92Ex0pNcuXpTp/+KICyN8B3BYs0RZ3rVc6rzBlsWer7AYvjfZ4KpbBKOcq1n59K+eN2GPyYglaocxPbnL73ig==","signatures":[{"sig":"MEYCIQD5bCFyTZ3QolQgNLYltwzXzIq+W24TDDq1+zjwH5Sg1QIhAMFKM/C9m+GbFwW3Krt0FyH0FGEdgIZIgXkzI4EKnbn+","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":86520},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./proto":{"default":"./dist/proto/"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"}},"gitHead":"3f3caf2d3a4df44926d5d780f3a745bf9e007d41","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc && npm run postbuild","prepare":"tsc && npm run postbuild","postbuild":"node scripts/copy-ws-protos.cjs"},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"repository":{"url":"git+https://github.com/canopy-network/canopy-ts.git","type":"git"},"_npmVersion":"11.13.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","directories":{},"_nodeVersion":"25.9.0","dependencies":{"zod":"^4.4.3","protobufjs":"^7.4.0","@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^1.0.0","typescript":"^5.0.0"},"publishedWsProtos":["ws_frame.proto","dice_ws.proto","plinko_ws.proto","market_ws.proto","account.proto"],"_npmOperationalInternal":{"tmp":"tmp/canopy-ts_0.6.0_1781078729256_0.7549002514569305","host":"s3://npm-registry-packages-npm-production"}},"0.8.0":{"name":"@canopynetwork/canopy-ts","version":"0.8.0","description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./crypto":{"types":"./dist/crypto.d.ts","import":"./dist/crypto.js"},"./rpc":{"types":"./dist/rpc.d.ts","import":"./dist/rpc.js"},"./ws":{"types":"./dist/ws.d.ts","import":"./dist/ws.js"},"./errors":{"types":"./dist/errors.d.ts","import":"./dist/errors.js"},"./keystore":{"types":"./dist/keystore.d.ts","import":"./dist/keystore.js"},"./wallet-manager":{"types":"./dist/wallet-manager.d.ts","import":"./dist/wallet-manager.js"},"./node-pool":{"types":"./dist/node-pool.d.ts","import":"./dist/node-pool.js"},"./transaction":{"types":"./dist/transaction.d.ts","import":"./dist/transaction.js"},"./proto/*":"./dist/proto/*"},"sideEffects":false,"publishedWsProtos":["ws_frame.proto","dice_ws.proto","plinko_ws.proto","market_ws.proto","account.proto"],"repository":{"type":"git","url":"git+https://github.com/canopy-network/canopy-ts.git"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc && npm run postbuild","postbuild":"node scripts/copy-ws-protos.cjs","dev":"tsc --watch","prepare":"tsc && npm run postbuild","test":"vitest run","test:e2e":"vitest run --config vitest.config.e2e.ts"},"dependencies":{"@noble/curves":"^2.0.1","@noble/hashes":"^2.0.1","protobufjs":"^7.4.0","zod":"^4.4.3"},"devDependencies":{"typescript":"^5.0.0","vitest":"^1.0.0"},"gitHead":"7dd3ef3c9b1b495bca729c3cd08fb24d85fbee87","_id":"@canopynetwork/canopy-ts@0.8.0","bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"homepage":"https://github.com/canopy-network/canopy-ts#readme","_nodeVersion":"26.4.0","_npmVersion":"12.0.2","dist":{"integrity":"sha512-9fINWCEUxntkOZRN0TwZzJjQyS64bmQtjYvKw4IMj1f/j4zCCtuDBhxG4FtrzfpbsrHXrRAViyuy88WvuXdmRQ==","shasum":"859294dfd74f178b1ba5a6361e62f0bbf89a9f55","tarball":"https://registry.npmjs.org/@canopynetwork/canopy-ts/-/canopy-ts-0.8.0.tgz","fileCount":48,"unpackedSize":182421,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDycH2/LL65MbbNvEsinpv4n5bNkSVDDM8NZJEejpvj+AIhAMCvyV2/qhq9Z/A+JmuxNv0MUT8tsHjcEoPHTJT8CRsa"}]},"_npmUser":{"name":"ezeike","email":"tiny.dove7572@fastmail.com"},"directories":{},"maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/canopy-ts_0.8.0_1786458208602_0.22080771480109895"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-06T12:15:30.262Z","modified":"2026-08-11T14:23:28.965Z","0.3.0":"2026-06-06T12:15:30.512Z","0.4.0":"2026-06-07T06:41:50.850Z","0.4.1":"2026-06-07T06:45:30.113Z","0.4.2":"2026-06-07T06:52:37.498Z","0.6.0":"2026-06-10T08:05:29.389Z","0.8.0":"2026-08-11T14:23:28.746Z"},"bugs":{"url":"https://github.com/canopy-network/canopy-ts/issues"},"homepage":"https://github.com/canopy-network/canopy-ts#readme","repository":{"type":"git","url":"git+https://github.com/canopy-network/canopy-ts.git"},"description":"TypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport","maintainers":[{"name":"ezeike","email":"tiny.dove7572@fastmail.com"}],"readme":"# @canopynetwork/canopy-ts\n\nTypeScript SDK for Canopy blockchain plugin frontends — signing, keystore, RPC, and WebSocket transport.\n\nScoped for **plugin frontends**: browser/UI code that signs transactions, manages a local keystore, and talks to a Canopy node over RPC/WebSocket, without a backend in between.\n\n## Install\n\n```bash\nnpm install @canopynetwork/canopy-ts\n```\n\nESM only. Node ≥ 18 or any modern bundler (Vite, webpack, esbuild, Rollup).\n\n## Importing\n\nPrefer subpath imports — they keep your bundle to only what you use:\n\n```ts\nimport { generateKeyPair } from \"@canopynetwork/canopy-ts/crypto\";\nimport { fetchHeight } from \"@canopynetwork/canopy-ts/rpc\";\n```\n\nImporting from the package root works too, but pulls in every subpath's\ndependencies (protobufjs, zod, noble-curves, the WS transport) even if you\nonly need one of them:\n\n```ts\nimport { generateKeyPair, fetchHeight } from \"@canopynetwork/canopy-ts\";\n```\n\n| Subpath | Covers |\n|---|---|\n| `./crypto` | Key generation, signing, address derivation, keystore encryption, transaction builders |\n| `./rpc` | Node RPC query methods (accounts, blocks, transactions, validators, ...) |\n| `./ws` | WebSocket transport + per-channel protobuf routing |\n| `./errors` | `CanopyError` hierarchy |\n| `./keystore` | Go-keystore-compatible import/export |\n| `./wallet-manager` | `WalletManager` — multi-account wallet with injectable storage |\n| `./node-pool` | `NodePool` — multi-node RPC client with automatic failover |\n| `./transaction` | Transaction builders (`createAndSignTransaction`) |\n| `./proto/*` | Raw `.proto` schema files for the WebSocket protocol |\n\n## Quick start\n\n### Generate a key pair and derive an address\n\n```ts\nimport { generateKeyPair, deriveAddress, CurveType } from \"@canopynetwork/canopy-ts/crypto\";\n\nconst { privateKey, publicKey } = generateKeyPair();\nconst address = deriveAddress(publicKey, CurveType.ED25519);\n```\n\n### Encrypted keystore (Go-keystore compatible)\n\n```ts\nimport { encryptPrivateKeyHex, decryptPrivateKeyHex } from \"@canopynetwork/canopy-ts/crypto\";\n\nconst { encrypted, salt } = await encryptPrivateKeyHex(privateKey, \"correct horse battery staple\");\nconst recovered = await decryptPrivateKeyHex(encrypted, salt, \"correct horse battery staple\");\n```\n\n### WalletManager — multi-account wallet\n\n```ts\nimport { WalletManager } from \"@canopynetwork/canopy-ts/wallet-manager\";\n\n// storage is injectable — implement KeystoreStorage against localStorage,\n// IndexedDB, or whatever the host app already uses.\nconst wallet = new WalletManager({ storage: myStorage });\n\nconst accounts = await wallet.loadAccounts({ baseUrl: \"https://node.example.com\" });\nconst unlocked = await wallet.unlock(accounts[0].address, \"password\");\n```\n\n### RPC queries\n\n```ts\nimport { fetchHeight } from \"@canopynetwork/canopy-ts/rpc\";\n\nconst height = await fetchHeight({ baseUrl: \"https://node.example.com\" });\n```\n\nList endpoints (`validators`, `committee`, `orders`, `txsByHeight`,\n`eventsByAddress`, ...) are async generators — `for await...of` the whole\nlist, no manual page-by-page calls:\n\n```ts\nimport { validators, eventsByAddress } from \"@canopynetwork/canopy-ts/rpc\";\n\nfor await (const v of validators()) {\n  console.log(v);\n}\n\n// tune page size / sort order with pageParams; still just iterate\nfor await (const e of eventsByAddress(address, { pageParams: { per_page: 50 } })) {\n  console.log(e);\n}\n```\n\n### Multi-node failover\n\n```ts\nimport { NodePool } from \"@canopynetwork/canopy-ts/node-pool\";\nimport { fetchHeight } from \"@canopynetwork/canopy-ts/rpc\";\n\nconst pool = new NodePool([\n  { name: \"primary\", rpc: \"https://node-1.example.com\" },\n  { name: \"backup\", rpc: \"https://node-2.example.com\" },\n]);\n\n// Rotates to the next enabled node on connection/timeout/5xx errors;\n// propagates 4xx immediately without rotating (it's not a node-health signal).\nconst height = await pool.withFailover((opts) => fetchHeight(opts));\n```\n\n### WebSocket transport\n\n```ts\nimport { DirectTransport, ChannelRouter, makeFrameCodec, makeSystemCodec } from \"@canopynetwork/canopy-ts/ws\";\n\nconst root = /* load your .proto schemas — see ./proto/* exports */;\nconst transport = new DirectTransport({\n  publicKeyHex: publicKey,\n  privateKeyHex: privateKey,\n  curveType: CurveType.ED25519,\n  wsUrl: \"wss://node.example.com/ws\",\n  frameCodec: makeFrameCodec(root),\n  systemCodec: makeSystemCodec(root),\n});\n\nconst router = new ChannelRouter(transport, root);\nrouter.registerChannel(\"mychannel\", \"MyEnvelopeType\");\nrouter.on(\"mychannel\", (msg) => console.log(msg));\n```\n\n### Building and signing a transaction\n\n```ts\nimport { createAndSignTransaction } from \"@canopynetwork/canopy-ts/transaction\";\n\n// Plugin format (default) — msgTypeUrl/msgBytes:\nconst tx = createAndSignTransaction(\n  { type: \"send\", msg: { /* message fields */ }, fee: 10000, networkID: 1, chainID: 1, height: height },\n  privateKey,\n  publicKey,\n  CurveType.ED25519,\n);\n\n// Core format — for registered on-chain types (send, stake, unstake, ...),\n// which the node requires as a protojson `msg` field instead:\nconst coreTx = createAndSignTransaction(\n  { type: \"send\", msg: { /* message fields */ }, fee: 10000, networkID: 1, chainID: 1, height: height },\n  privateKey,\n  publicKey,\n  CurveType.ED25519,\n  { format: \"core\" },\n);\n```\n\n## Error handling\n\nEvery error the SDK throws extends `CanopyError`, so you can catch broadly\nor narrow to a specific failure mode:\n\n```ts\nimport { CanopyError, RpcError, TimeoutError } from \"@canopynetwork/canopy-ts/errors\";\n\ntry {\n  await fetchHeight({ baseUrl });\n} catch (e) {\n  if (e instanceof TimeoutError) {\n    // e.timeoutMs\n  } else if (e instanceof RpcError) {\n    // e.status, e.requestId, e.body\n  } else if (e instanceof CanopyError) {\n    // any other SDK error\n  }\n}\n```\n\nRPC calls retry transient failures (network errors, 5xx) with exponential\nbackoff and jitter by default (3 attempts). Disable per-call with\n`{ retry: false }`, or tune `{ retry: { maxAttempts, baseDelayMs, maxDelayMs } }`.\n\n## Versioning\n\nThis package follows [Semantic Versioning](https://semver.org/). Type\nchanges are treated as part of the public API — see\n[CHANGELOG.md](./CHANGELOG.md) for a full history, including breaking\nchanges.\n\n## License\n\nSee the repository for license details.\n","readmeFilename":"README.md"}