{"_id":"@caict-bif/bif-typescript-sdk","_rev":"4-ec7833d8f8f7f82530b318e0c71a0464","name":"@caict-bif/bif-typescript-sdk","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@caict-bif/bif-typescript-sdk","version":"0.1.0","keywords":["caict","bif","blockchain","sdk"],"license":"Apache-2.0","_id":"@caict-bif/bif-typescript-sdk@0.1.0","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"dist":{"shasum":"5bfeb6ddcd727e134a8102c5a6748c166e6893d9","tarball":"https://registry.npmjs.org/@caict-bif/bif-typescript-sdk/-/bif-typescript-sdk-0.1.0.tgz","fileCount":100,"integrity":"sha512-9F8FzTffWP40S4I4VzRfHYS7IFwqHckYkj32uH0/vykczpMO+OLIVaZNXsl1/tIq0oOu/7vGLnZS7mlzWzvcHw==","signatures":[{"sig":"MEYCIQCiarLRUdG45f98/efBzdH1uDO8Bipb146V1iW1JXCCzwIhANNCsutbyGvzyFe7YXe/LM5ArRoJecxutPiUtDGjXlSg","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":337213},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"3fb3ea544e5954ed7a52bb148cba518ed9dec7d3","scripts":{"test":"npm run test:compile && mocha --recursive dist/**/test/**/*.js -c --exit --timeout 30000","build":"npm run clean && tsc --project tsconfig.json","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","test:compile":"npm run clean && tsc --project tsconfig.json"},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"_npmVersion":"10.8.2","description":"BIF 底层链对外开放接口 TypeScript SDK (直连链节点)","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.21.0","ethers":"^6.17.0","undici":"^6.28.0","@noble/hashes":"^1.8.0","@caict-bif/bif-encryption":"^1.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"chai":"4.2.0","mocha":"^11.0.1","@types/ws":"^8.5.0","typescript":"~5.0.0","@types/chai":"^4.2.0","@types/node":"^18.0.0","@types/mocha":">=9.1.0"},"_npmOperationalInternal":{"tmp":"tmp/bif-typescript-sdk_0.1.0_1786860169739_0.2092141876261333","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@caict-bif/bif-typescript-sdk","version":"0.1.1","keywords":["caict","bif","blockchain","sdk"],"license":"Apache-2.0","_id":"@caict-bif/bif-typescript-sdk@0.1.1","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"dist":{"shasum":"ba4d7f60fb326437fb386f1a6ee9a2f83d3d12b1","tarball":"https://registry.npmjs.org/@caict-bif/bif-typescript-sdk/-/bif-typescript-sdk-0.1.1.tgz","fileCount":104,"integrity":"sha512-8qfy5e0vTDwfoPuKZtMNEUwQBsHvV9F8GqYVhpYVG037UQvWJjae3p1OrKu+eKJYmVfeTeci76ekd9oa8/Y2ag==","signatures":[{"sig":"MEUCIQCGbJNuTeTOWhiUPTd+2tanlJSUDzpom8j1KVd1NAw1yAIgNgeKovEePu4cfDwwPALS3KLbc4tiM7qaBXBzi2fB1kc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":345078},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"3fb3ea544e5954ed7a52bb148cba518ed9dec7d3","scripts":{"test":"npm run test:compile && mocha --recursive dist/**/test/**/*.js -c --exit --timeout 30000","build":"npm run clean && tsc --project tsconfig.json","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","test:compile":"npm run clean && tsc --project tsconfig.json"},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"_npmVersion":"10.8.2","description":"BIF 底层链对外开放接口 TypeScript SDK (直连链节点)","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.21.0","ethers":"^6.17.0","undici":"^6.28.0","@noble/hashes":"^1.8.0","@caict-bif/bif-encryption":"^1.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"chai":"4.2.0","mocha":"^11.0.1","@types/ws":"^8.5.0","typescript":"~5.0.0","@types/chai":"^4.2.0","@types/node":"^18.0.0","@types/mocha":">=9.1.0"},"_npmOperationalInternal":{"tmp":"tmp/bif-typescript-sdk_0.1.1_1786902633038_0.6543553964508269","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@caict-bif/bif-typescript-sdk","version":"0.1.2","keywords":["caict","bif","blockchain","sdk"],"license":"Apache-2.0","_id":"@caict-bif/bif-typescript-sdk@0.1.2","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"dist":{"shasum":"ea529ab2f74b5a8a5cdf5045d3004af443f35f5f","tarball":"https://registry.npmjs.org/@caict-bif/bif-typescript-sdk/-/bif-typescript-sdk-0.1.2.tgz","fileCount":108,"integrity":"sha512-BkafhBFtXf8uh0D6oabWLN2VqWw9mPiyoBWlv7u4aMFl4S9UlcqF8O1wLolarCECwOpYGff3GnOrdcJvAGJ9Rw==","signatures":[{"sig":"MEQCIB+AgATIux/hczLao5XVtrCbBPQ5b6PDx0a/D0un7ka2AiAI857rrwcTld6u0cIDG8VuJuBO9y0QN0C2WtcEcCBvXg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":364397},"main":"dist/index.js","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"0e8d01d6fcb2b201ec685729f506bcd12e9bf1c0","scripts":{"test":"npm run test:compile && mocha --recursive dist/**/test/**/*.js -c --exit --timeout 30000","build":"npm run clean && tsc --project tsconfig.json","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","sample":"npm run build && node sample/run-all.js","test:compile":"npm run clean && tsc --project tsconfig.json"},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"_npmVersion":"10.8.2","description":"BIF 底层链对外开放接口 TypeScript SDK (直连链节点)","directories":{},"_nodeVersion":"20.20.2","dependencies":{"ws":"^8.21.0","ethers":"^6.17.0","undici":"^6.28.0","@noble/hashes":"^1.8.0","@caict-bif/bif-encryption":"^1.2.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"chai":"4.2.0","mocha":"^11.0.1","@types/ws":"^8.5.0","typescript":"~5.0.0","@types/chai":"^4.2.0","@types/node":"^18.0.0","@types/mocha":">=9.1.0"},"_npmOperationalInternal":{"tmp":"tmp/bif-typescript-sdk_0.1.2_1786941298963_0.6311449113897938","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@caict-bif/bif-typescript-sdk","version":"0.2.0","description":"BIF 底层链对外开放接口 TypeScript SDK (直连链节点)","main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"npm run clean && tsc --project tsconfig.json","test:compile":"npm run clean && tsc --project tsconfig.json","test":"npm run test:compile && mocha --recursive dist/**/test/**/*.js -c --exit --timeout 30000","clean":"node -e \"require('fs').rmSync('dist', { recursive: true, force: true })\"","sample":"npm run build && node sample/run-all.js"},"keywords":["caict","bif","blockchain","sdk"],"license":"Apache-2.0","engines":{"node":">=18.0.0"},"publishConfig":{"access":"public"},"dependencies":{"@caict-bif/bif-encryption":"^1.3.0","@noble/hashes":"^1.8.0","ethers":"^6.17.0","undici":"^6.28.0","ws":"^8.21.0"},"devDependencies":{"@types/chai":"^4.2.0","@types/mocha":">=9.1.0","@types/node":"^18.0.0","@types/ws":"^8.5.0","chai":"4.2.0","mocha":"^11.0.1","typescript":"~5.0.0"},"_id":"@caict-bif/bif-typescript-sdk@0.2.0","gitHead":"e63c32d88b6cf407b360f575e2b364f221583144","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-knMwDCJsKJN1lL4y96/tKAilo/Dm+XAnM181WyaCPxumnz4B2MYaM6AliJ8PlBpbPtxyIpVA8lLTLqSqfLlHNg==","shasum":"aea775709989a28c54e6227342ef2f9e60fc7798","tarball":"https://registry.npmjs.org/@caict-bif/bif-typescript-sdk/-/bif-typescript-sdk-0.2.0.tgz","fileCount":116,"unpackedSize":403782,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHNnrlYdZu/V157slq+QjD6WAluoEbLRNB3PbSTok695AiEA0RmK1/G9gWltfiW9o6Wl7tmgmQDarvOXPFHVFwiJdsI="}]},"_npmUser":{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"},"directories":{},"maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/bif-typescript-sdk_0.2.0_1786956738519_0.6545840603999555"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-16T06:02:49.580Z","modified":"2026-08-17T08:52:19.050Z","0.1.0":"2026-08-16T06:02:49.896Z","0.1.1":"2026-08-16T17:50:33.181Z","0.1.2":"2026-08-17T04:34:59.400Z","0.2.0":"2026-08-17T08:52:18.679Z"},"license":"Apache-2.0","keywords":["caict","bif","blockchain","sdk"],"description":"BIF 底层链对外开放接口 TypeScript SDK (直连链节点)","maintainers":[{"name":"zhangbo3","email":"zhangbo3@caict.ac.cn"}],"readme":"# @caict-bif/bif-typescript-sdk\r\n\r\n直连 BIF 底层链节点的 TypeScript SDK（CommonJS）。\r\n\r\n> 接口范围以链对外公开的 HTTP/WebSocket 接口为准，仅包含本 SDK 实际提供的方法。\r\n\r\n## 项目结构\r\n\r\n```\r\nsrc/\r\n├── bif-core/            # 传输层：HTTP 客户端（BifHttpClient）、WebSocket 订阅客户端、订阅协议\r\n├── bif-sdk/             # SDK 层\r\n│   ├── provider.ts      # BifProvider 入口：聚合五个域服务\r\n│   └── interface/\r\n│       ├── signer.ts    # BifSigner（账户 + 交易签名）\r\n│       ├── service/     # 域服务：chain / account / ledger / transaction / contract\r\n│       └── builder/     # 离线交易构造：buildPayCoin / buildTransaction / ...\r\n├── abi/                 # Solidity ABI 工具（ethers 封装）\r\n└── proto/               # 链 protobuf wire 编解码\r\n```\r\n\r\n## 安装\r\n\r\n```bash\r\nnpm install @caict-bif/bif-typescript-sdk\r\n```\r\n\r\n## 快速开始\r\n\r\n```ts\r\nimport { BifProvider, BifSigner, generateKeyPair } from \"@caict-bif/bif-typescript-sdk\";\r\n\r\nconst provider = new BifProvider({\r\n  baseUrl: \"https://your-bif-node.example\", // 替换为你的 BIF 节点地址\r\n  allowInsecureTls: true, // 测试网 TLS 证书链不完整时使用；生产环境不要开启\r\n});\r\n\r\n(async () => {\r\n  // 链信息\r\n  console.log(await provider.chain.hello());\r\n\r\n  // 账户查询\r\n  const account = await provider.account.getAccountBase(\"did:bid:ef...\");\r\n  console.log(account);\r\n\r\n  // 区块查询\r\n  console.log(await provider.ledger.getLedger({ seq: 1 }));\r\n})();\r\n```\r\n\r\n## 签名器（Signer）\r\n\r\n签名器可通过 `connect(provider)` 绑定后直接获得在线能力。\r\n\r\n```ts\r\nimport { BifProvider, BifSigner, generateKeyPair } from \"@caict-bif/bif-typescript-sdk\";\r\n\r\nconst provider = new BifProvider({ baseUrl: \"https://your-bif-node.example\" });\r\nconst pair = generateKeyPair();\r\nconst signer = new BifSigner(pair.privateKey).connect(provider);\r\n\r\n// 离线能力\r\nconst sig = signer.sign(\"aabb...\");                        // 交易 blob → hex 签名\r\nconst ok = signer.verify(\"aabb...\", \"sighex\");             // 验签\r\n\r\n// 在线能力（connect 后）\r\nawait signer.getAccount();          // 查自己账户\r\nawait signer.getAccountBalance();   // 查自己余额\r\nawait signer.getLedgerNumber();     // 最新区块高度\r\nawait signer.estimateGas({ operations, gasPrice });  // 费用评估\r\n\r\n// 绑定后的签名者可直接用于交易\r\nawait provider.transaction.sendTransaction({ signer, tx: {...} });\r\n```\r\n\r\n## 交易\r\n\r\n交易支持两种流程，均与底层链 `chain.proto` 对齐：\r\n\r\n### 1. 本地构造 + 签名 + 提交（推荐，零额外步骤）\r\n\r\n```ts\r\nimport { BifProvider, OperationType, buildPayCoin, buildSetMetadata } from \"@caict-bif/bif-typescript-sdk\";\r\n\r\nconst provider = new BifProvider({ baseUrl: \"https://your-bif-node.example\" });\r\nconst signer = new BifSigner(\"你的编码私钥\");\r\n\r\nconst result = await provider.transaction.sendTransaction({\r\n  signer,\r\n  tx: {\r\n    sourceAddress: signer.address,\r\n    nonce: 1, // INCREASE_NONCE 模式填账户当前 nonce；RANDOM_NONCE 模式填任意\r\n    feeLimit: 10_000_000,\r\n    gasPrice: 1000,\r\n    operations: [\r\n      buildPayCoin({ destAddress: \"did:bid:ef...\", amount: 1000, input: \"\" }),\r\n      buildSetMetadata({ key: \"k\", value: \"v\" }),\r\n    ],\r\n  },\r\n});\r\nconsole.log(result); // { hash, error_code, error_desc }\r\n```\r\n\r\n本地序列化使用 SDK 自带的手写 protobuf wire 编码器，`hash = SHA256(序列化字节)`，\r\n与链端 `HashWrapper::Crypto`（`hash_type=0` 时）一致。\r\n\r\n### 2. 链端生成 blob（getTransactionBlob）\r\n\r\n```ts\r\nconst tx = buildTransaction({ sourceAddress: signer.address, nonce: 1, operations: [...] });\r\nconst blob = await provider.transaction.getTransactionBlob(tx); // { transactionBlob, hash }\r\nconst signature = signer.signTransaction(blob.transactionBlob);\r\nconst results = await provider.transaction.submitTransaction([{ transaction_blob: blob.transactionBlob, signatures: [signature] }]);\r\n```\r\n\r\n## 离线交易构造接口\r\n\r\n离线 operation 构造器（可与 `sendTransaction` / `buildTransaction` 组合）：\r\n\r\n| 构造器 | 底层 Operation |\r\n|---|---|\r\n| `buildPayCoin({destAddress, amount, input?})` | PAY_COIN |\r\n| `buildContractInvoke({contractAddress, amount?, input?})` | PAY_COIN → 合约 |\r\n| `buildSetMetadata({key, value, version?, deleteFlag?})` | SET_METADATA |\r\n| `buildCreateAccount({destAddress, initBalance?, contract?, priv?, ...})` | CREATE_ACCOUNT |\r\n| `buildActivateAccount(destAddress, initBalance?)` | CREATE_ACCOUNT + 默认权限 |\r\n| `buildSetPrivilege({masterWeight?, signers?, txThreshold?, typeThresholds?})` | SET_PRIVILEGE |\r\n| `buildBatchGasSend(items[])` | 批量 PAY_COIN |\r\n| `buildBatchContractInvoke(items[])` | 批量合约调用 |\r\n\r\n多签离线签名（无需网络）：\r\n\r\n```ts\r\nconst { transactionBlob, hash, signatures } = provider.transaction.buildSignedBlob(\r\n  { sourceAddress, nonce: 1, operations: [...] },\r\n  [signerA, signerB],        // 多签者\r\n  { dissPubkey: false },\r\n);\r\n// signatures[].sign_data / .public_key 可直接提交 provider.transaction.submitTransaction\r\n```\r\n\r\n## 对外接口清单\r\n\r\n### chain（链信息）\r\n\r\n| 方法 | 对应链接口 | 说明 |\r\n|---|---|---|\r\n| `provider.chain.hello()` | GET /hello | 链基础信息 |\r\n| `provider.chain.getNetworkId()` / `getChainVersion()` | GET /hello | 网络 ID / 节点版本 |\r\n\r\n### account（账户）\r\n\r\n| 方法 | 对应链接口 | 说明 |\r\n|---|---|---|\r\n| `provider.account.getAccount(address, opts?)` | GET /getAccount | 账户信息 |\r\n| `provider.account.getAccountBase(address)` | GET /getAccountBase | 账户基础信息 |\r\n| `provider.account.getAccountMetaData(address, key?)` | GET /getAccountMetaData | 账户 metadata |\r\n| `provider.account.getAccountNonce(address)` | GET /getAccountBase | 账户 nonce |\r\n| `provider.account.getAccountBalance(address)` | GET /getAccountBase | 账户余额 |\r\n| `provider.account.getAccountPriv(address)` | GET /getAccountBase | 账户权限 |\r\n\r\n### ledger（账本）\r\n\r\n| 方法 | 对应链接口 | 说明 |\r\n|---|---|---|\r\n| `provider.ledger.getLedgerNumber()` | GET /getLedger | 最新区块高度 |\r\n| `provider.ledger.getLedger(opts?)` | GET /getLedger | 区块信息（seq/withFee/withValidator/withConsvalue/withLeader） |\r\n| `provider.ledger.getLedgerTransactions(seq)` | GET /getLedger | 区块内交易列表 |\r\n\r\n### transaction（交易）\r\n\r\n| 方法 | 对应链接口 | 说明 |\r\n|---|---|---|\r\n| `provider.transaction.getTxCacheSize()` | GET /getTxCacheSize | 交易池条数 |\r\n| `provider.transaction.getTransactionCache(opts?)` | GET /getTransactionCache | 交易池缓存 |\r\n| `provider.transaction.getTransactionHistory(opts?)` | GET /getTransactionHistory | 链上交易 |\r\n| `provider.transaction.getTransactionBlob(tx)` | POST /getTransactionBlob | 交易转 blob |\r\n| `provider.transaction.submitTransaction(items)` | POST /submitTransaction | 提交交易 |\r\n| `provider.transaction.testTransaction(item)` | POST /testTransaction | 节点内测试交易（不上链） |\r\n| `provider.transaction.sendTransaction({tx, signer})` | 本地构造+签名+提交 | 一键交易 |\r\n| `provider.transaction.buildBlob(params)` / `buildSignedBlob(...)` | 本地 | 离线构造 / 多签离线签名 |\r\n\r\n### contract（合约）\r\n\r\n| 方法 | 对应链接口 | 说明 |\r\n|---|---|---|\r\n| `provider.contract.callContract(params)` | POST /callContract | 合约只读调用 |\r\n| `provider.contract.getContractInfo(address)` | GET /getAccountBase | 合约账户信息 |\r\n| `provider.contract.getContractAddress(hash)` | GET /getTransactionHistory | 合约创建交易 hash → 合约地址列表 |\r\n\r\n### WebSocket 订阅\r\n\r\n```ts\r\nimport { BifWsClient, MessageType, chainTxStatusCodec, ledgerHeaderCodec } from \"@caict-bif/bif-typescript-sdk\";\r\n\r\nconst ws = new BifWsClient({ url: \"wss://your-bif-node.example/ws\", });\r\n```\r\n\r\n- `MessageType.CHAIN_LEDGER_HEADER`(16) 订阅区块头 → `ledgerHeaderCodec`\r\n- `MessageType.CHAIN_LEDGER_TXS`(18) 订阅完整区块\r\n- `MessageType.CHAIN_CONTRACT_LOG`(17) 订阅合约 TLOG → `tlogSubscribeResponseCodec`\r\n- `MessageType.CHAIN_SUBSCRIBE_TX`(19) 订阅指定地址交易\r\n- `MessageType.SUBSCIBE_TXS`(21) 订阅交易丢弃状态 → `txSubscribeResponseCodec`\r\n- `MessageType.CHAIN_TX_STATUS`(11) 交易执行状态推送 → `chainTxStatusCodec`\r\n- `MessageType.CHAIN_HELLO`(10) 连接握手，链端默认开启区块/区块头/交易状态推送\r\n\r\n## Solidity ABI 工具（EVM 合约，基于 ethers v6）\r\n\r\n提供 Solidity 合约的 ABI 编解码能力，仅服务 EVM 合约\r\n（原生 JS 合约 input 为 JSON 字符串，不走本工具）。\r\n\r\n```ts\r\nimport { encodeFunctionInput, decodeFunctionOutput, getEventTopic, getFunctionSelector, encodeAbiTypes } from \"@caict-bif/bif-typescript-sdk\";\r\n\r\nconst abi = [\r\n  \"function transfer(address to, uint256 amount) returns (bool)\",\r\n  \"function balanceOf(address account) view returns (uint256)\",\r\n  \"event Transfer(address indexed from, address indexed to, uint256 value)\",\r\n];\r\n\r\nconst input = encodeFunctionInput({ abi, name: \"transfer\", args: [to, 1000n] }); // 0x + selector + 参数，可直接作 contractInvoke 的 input\r\nconst returns = decodeFunctionOutput({ abi, name: \"balanceOf\", data: rawResult }); // [42n]\r\nconst topic = getEventTopic({ abi, name: \"Transfer\" }); // 事件 topicHash\r\nconst selector = getFunctionSelector(\"transfer(address,uint256)\"); // 0xa9059cbb\r\n```\r\n\r\n## 扩展能力\r\n\r\n| 方法 | 说明 |\r\n|---|---|\r\n| `provider.transaction.parseBlob(blobHex)` | 本地反序列化交易 blob → `{transaction, hash}`，无需网络 |\r\n| `provider.contract.getContractAddress(hash)` | 合约创建交易 hash → 合约地址列表（解析交易 `error_desc`） |\r\n| `provider.transaction.evaluateFee({sourceAddress, operations, nonceType?, feeLimit?, gasPrice?, remarks?})` | 费用评估：nonceType=0 自动取账户 nonce+1；=1 本地随机 nonce + maxLedgerSeq，底层走 `/testTransaction` |\r\n\r\n```ts\r\nconst fee = await provider.transaction.evaluateFee({\r\n  sourceAddress: \"did:bid:ef...\",\r\n  operations: [buildContractInvoke({ contractAddress: \"did:bid:efContract\", input: \"{}\" })],\r\n  gasPrice: 1000,\r\n});\r\n```\r\n\r\n## Sample\r\n\r\n仓库提供 `sample/` 目录，覆盖基础查询、交易构造/提交、签名器、ABI/合约与 WebSocket 订阅场景。\r\n提交到 git 的示例只包含占位连接地址和占位账户，不包含真实节点、私钥或 API Key。\r\n\r\n```bash\r\nnpm run build\r\nnode sample/run-all.js --list\r\n```\r\n\r\n需要跑联网或写交易场景时，在本地复制配置文件并填写真实值：\r\n\r\n```bash\r\ncp sample/config.example.js sample/config.local.js\r\n```\r\n\r\n`sample/config.local.js` 已被 `.gitignore` 忽略，用来填写本地敏感信息：\r\n\r\n- `baseUrl`：HTTP 节点地址（查询、费用评估、testTransaction 使用）\r\n- `wsUrl`：WebSocket 订阅地址\r\n- `readerAddress`：只读查询账户地址\r\n- `contractAddress` / `contractDeployHash`：合约在线示例需要时填写\r\n- `writerPrivateKey`：写交易账户编码私钥，仅保存在本地\r\n- `enableWriteRuns`：写交易总开关，必须显式设为 `true` 才会发送交易\r\n\r\n也可以用环境变量临时覆盖：`BIF_BASE_URL`、`BIF_WS_URL`、`BIF_READER_ADDRESS`、`BIF_WRITER_PRIVATE_KEY`。\r\n\r\n```bash\r\nnpm run sample -- --list\r\nnpm run sample\r\nnpm run sample -- --only=tx-offline-builders\r\n```\r\n\r\n默认占位配置下，离线场景会运行；联网、WebSocket 和写交易场景会跳过并提示需要填写的本地配置。\r\n\r\n## 开发\r\n\r\n```bash\r\nnpm install\r\nnpm test          # tsc 编译 + mocha（33 个用例：wire/编解码/签名/交易构造/ABI/扩展能力）\r\nnpm run build\r\n```\r\n\r\n## 说明\r\n\r\n- `allowInsecureTls: true` 仅用于测试网联调（节点 TLS 证书链不完整）。\r\n- int64 字段内部用 BigInt 处理，响应解码时安全范围内的值返回 `number`。\r\n- 交易 JSON（`getTransactionBlob`）中 bytes 字段以 hex 字符串表示（与链端 `Json2Proto` 一致）。\r\n","readmeFilename":"README.md"}