针对IndexerCollector 抛砖引玉~
- 实现getBalance。根据ckb-indexer,可以直接调用
get_cells_capacity
,输入是script和scrip_type,输出的capacity的单位应该是ckb。
// get capacity by lock script
async getBalance(address: Address): Promise<Amount> {
const data = {
data: {
script: address.toLockScript().serializeJson(),
scrip_type: "lock",
}
};
const res = await axios.post(
`${
this.apiBase
}/get_cells_capacity`,
data
);
/* result data: {
capacity - total capacity
block_hash - indexed tip block hash
block_number - indexed tip block number
}
*/
//PwCollector: return new Amount(res.data.data, AmountUnit.shannon);
return new Amount(res.data.capacity, AmountUnit.ckb);
}
- 实现collect。根据含义应该是get unspent cells。可以根据上面的代码调用rpc的
get_cells
// get unspent cells
async collect(address: Address, options: CollectorOptions): Promise<Cell[]> {
if (!options || !options.neededAmount) {
throw new Error("'neededAmount' in options must be provided");
}
const addressLockScript = address.toLockScript();
const cells: Cell[] = [];
// 怎么把capacity=${options.neededAmount.toHexString()}传进去?
const reqData = {
data: {
script: address.toLockScript().serializeJson(),
scrip_type: "lock",
}
};
const res = await axios.post(
`${
this.apiBase
}/get_cells`,
reqData
);
/* result data: {
objects - live cells
last_cursor - pagination parameter
}
*/
for (let liveCell of res.data.objects) {
// capacity = new Amount(capacity, AmountUnit.shannon);
// outPoint = new OutPoint(outPoint.txHash, outPoint.index);
//cells.push(new Cell(capacity, addressLockScript, null, outPoint));
cells.push(Cell.fromRPC(liveCell)); // 应该可以直接fromRPC吧?
}
return cells;
}
- 浏览时从ckb-js-toolkit中发现了RPC,尝试直接调用rpc.collect如下,最后对数据遍历时,没有找到怎么获取capacity:
constructor(public apiBase: string = "https://mainnet.ckb.dev/indexer") {
super();
this.apiBase = apiBase;
this.rpc = new RPC(this.apiBase);
}
// get unspent cells
async collect(address: Address, options: CollectorOptions): Promise<Cell[]> {
if (!options || !options.neededAmount) {
throw new Error("'neededAmount' in options must be provided");
}
const addressLockScript = address.toLockScript();
const rpcc = new cell_collectors.RPCCollector(this.rpc, addressLockScript.toHash(), {
skipCellWithContent: true,
loadData: true
});
const data = rpcc.collect();
const cells: Cell[] = [];
(async () => {
for await (const x of data) {
// 这里的capacity怎么读取?
const cap= new Amount(capacity, AmountUnit.shannon);
const outPoint = OutPoint.fromRPC(x.data);
cells.push(new Cell(cap, addressLockScript, null, outPoint));
}
})();
return cells;
}
-
找资料时,找到了 CKBRPC in ckb-sdk-core
当前项目中没找到@nervosnetwork/ckb-sdk-core
,尝试安装,失败。
CKBRPC中的getCapacityByLockHash
应该就是IndexerCollector的getBalance需要的方法;没有找到可直接用的通过neededAmount查询的方法。
不知道为什么没有引入@nervosnetwork/ckb-sdk-core
,有了这个库,就不需要通过axios进行查询了。 -
关于如何实现collect的一个思路。
在wile(true)循环中,可以通过第2条或者CKBRPC. getLiveCellsByLockHash获取一个分页的cells,然后比较neededAmount和分页中所有cell的capacity之和:小于,取分页中最小够用的cells集合,跳出循环;大于,继续获取下一个分页的数据。
const resultCells = [];
while(true){
const cells = ..... // 第2条的axios调用,或者CKBRPC. getLiveCellsByLockHash
const totalCapacity = ... // 遍历cells数组计算capacity之和
if(totalCapacity >= neededAmount){
// cells --> resultCells: 可能只需要cells中的一部分而非全部
break;
}
}