由于我正在搭建的测试网络属于私有链,在这两天的开发中,我发现使用 bitshares-ws
中的 Apis
进行初始化的时候,一直有下面截图中的问题
我的代码是官方文档示例中的
1 2 3 4 5 import {Apis} from 'bitsharesjs-ws'; const apiUrl = 'wss://api-testnet.61bts.com'; Apis.instance(apiUrl, true).init_promise.then((res) => { console.log(res); });
即返回值的第一个值一直是 undefined
,目前还不确定这个会导致什么问题,不过有个 undefined
肯定是不对的。
去看了下 Apis.instance().init_promise
的代码,我摘了关键部分如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 const newApis = () => ({ connect: ( cs, connectTimeout, optionalApis = { enableCrypto: false, enableOrders: false } ) => { ...... Apis.init_promise = Apis.ws_rpc .login(rpc_user, rpc_password) .then(() => { //console.log("Connected to API node:", cs); Apis._db = new GrapheneApi(Apis.ws_rpc, "database"); Apis._net = new GrapheneApi(Apis.ws_rpc, "network_broadcast"); Apis._hist = new GrapheneApi(Apis.ws_rpc, "history"); if (optionalApis.enableOrders) Apis._orders = new GrapheneApi(Apis.ws_rpc, "orders"); if (optionalApis.enableCrypto) Apis._crypt = new GrapheneApi(Apis.ws_rpc, "crypto"); var db_promise = Apis._db.init().then(() => { //https://github.com/cryptonomex/graphene/wiki/chain-locked-tx return Apis._db.exec("get_chain_id", []).then(_chain_id => { Apis.chain_id = _chain_id; return ChainConfig.setChainId(_chain_id); //DEBUG console.log("chain_id1",this.chain_id) }); }); ...... let initPromises = [db_promise, Apis._net.init(), Apis._hist.init()]; if (optionalApis.enableOrders) initPromises.push(Apis._orders.init()); if (optionalApis.enableCrypto) initPromises.push(Apis._crypt.init()); return Promise.all(initPromises); }) ...... }, ...... });
可以看到 Apis.init_promise
最终是返回了一个 Promise.all()
,其中索引 0
的值是 db_promise
。
再看了一下,db_promise
的结果由 ChainConfig.setChainId()
来决定。
再找出 ChainConfig
的代码,这个文件代码不长,我就全部贴出来了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 var config = { core_asset: "CORE", address_prefix: "GPH", expire_in_secs: 15, expire_in_secs_proposal: 24 * 60 * 60, review_in_secs_committee: 24 * 60 * 60, networks: { BitShares: { core_asset: "BTS", address_prefix: "BTS", chain_id: "4018d7844c78f6a6c41c6a552b898022310fc5dec06da467ee7905a8dad512c8" }, Muse: { core_asset: "MUSE", address_prefix: "MUSE", chain_id: "45ad2d3f9ef92a49b55c2227eb06123f613bb35dd08bd876f2aea21925a67a67" }, Test: { core_asset: "TEST", address_prefix: "TEST", chain_id: "39f5e2ede1f8bc1a3a54a7914414e3779e33193f1f5693510e73cb7a87617447" }, Obelisk: { core_asset: "GOV", address_prefix: "FEW", chain_id: "1cfde7c388b9e8ac06462d68aadbd966b58f88797637d9af805b4560b0e9661e" } }, /** Set a few properties for known chain IDs. */ setChainId: chain_id => { let result = Object.entries(config.networks).find( ([network_name, network]) => { if (network.chain_id === chain_id) { config.network_name = network_name; if (network.address_prefix) { config.address_prefix = network.address_prefix; } return true; } } ); if (result) return { network_name: result[0], network: result[1] }; else console.log("Unknown chain id (this may be a testnet)", chain_id); }, reset: () => { config.core_asset = "CORE"; config.address_prefix = "GPH"; config.expire_in_secs = 15; config.expire_in_secs_proposal = 24 * 60 * 60; console.log("Chain config reset"); }, setPrefix: (prefix = "GPH") => (config.address_prefix = prefix) }; export default config;
可以看到在 ChainConfig
对象中有个 networks
的值,在进行 setChainId()
操作的时候,会在这个 networks
里搜索,找不到符合条件的结果,就会进入 else
,也就是这个 setChainId()
会返回 undefined
。
好了找到了问题所在,那么我们只需要在 Apis.instance().init_promise
之前,先配置下 ChainConfig
。
但是 ChainConfig
在 init_promise
中,我们怎么配置呢?
结合上一篇文章 https://akawa.ink/2019/12/12/bitshares-ws-api-url-confuse.html ,我们知道使用 import
可以引入库的引用,那么我们在调用前,先 import ChainConfig
配置好就OK了。
最终代码如下:
1 2 3 4 5 6 7 8 9 10 import {Apis, ChainConfig} from 'bitsharesjs-ws'; const apiUrl = 'wss://api-testnet.61bts.com'; ChainConfig.networks['LiuyeTest'] = { core_asset: 'TEST', address_prefix: 'TEST', chain_id: 'd5dfe0da7cda9426dc4761752d889d44401c5f04f76c17970e90437b02c038d4', }; Apis.instance(apiUrl, true).init_promise.then((res) => { console.log(res); });