扩展 erdjs
原文:https://docs.elrond.com/sdk-and-tools/erdjs/extending-erdjs
##### 重要
本节中的文档是初步的,可能会更改。
本教程将引导您完成从 erdjs 扩展和裁剪某些模块的过程。
延伸网络提供商
从@elrondnetwork/erdjs-network-providers
开始的默认类应该只作为一个起点。随着你的 dApp 成熟,确保你切换到使用你自己的网络提供商,根据你的需求定制(无论是从默认的衍生还是从头编写一个新的),直接与Elrond API(或网关)交互。
从头开始执行 HTTP 请求
通过使用axios
实用程序执行简单的 HTTP 请求,可以广播交易并从Elrond API(或网关)获取资源。以下是几个例子:
广播交易:
import axios, { AxiosResponse } from "axios";
let tx = new Transaction({ /* provide the fields */ });
// ... sign the transaction using a dApp / signing provider
let data = tx.toSendable();
let url = "https://devnet-api.elrond.com/transactions";
let response: AxiosResponse = await axios.post(url, data, {
headers: {
"Content-Type": "application/json",
}
});
let txHash = response.data.txHash;
提取交易:
let url = `https://devnet-api.elrond.com/transactions/${txHash}`;
let response = await axios.get(url);
let transactionOnNetwork = TransactionOnNetwork.fromApiHttpResponse(txHash, response.data);
查询智能合约(解析结果):
let query = contract.createQuery({
func: new ContractFunction("foobar"),
args: [new AddressValue(addressOfAlice)],
caller: new Address("erd1...")
});
let url = "https://devnet-api.elrond.com/query";
let data = {
scAddress: query.address.bech32(),
caller: query.caller?.bech32() ? query.caller.bech32() : undefined,
funcName: query.func.toString(),
value: query.value ? query.value.toString() : undefined,
args: query.getEncodedArguments()
};
let response: AxiosResponse = await axios.post(url, data, {
headers: {
"Content-Type": "application/json",
}
});
let queryResponse = {
returnCode: response.data.returnCode,
returnMessage: response.data.returnMessage,
getReturnDataParts: () => response.data.returnData.map((item) => Buffer.from(item || "", "base64"));
};
let endpointDefinition = contract.getEndpoint("foobar");
let { firstValue, secondValue, returnCode } = resultsParser.parseQueryResponse(queryResponse, endpointDefinition);
扩展默认网络提供商
您还可以从默认的网络提供商(ApiNetworkProvider
和ProxyNetworkProvider
)派生,并利用doGetGeneric()
和doPostGeneric()
覆盖/添加额外的方法。
export class MyTailoredNetworkProvider extends ApiNetworkProvider {
async getEconomics(): Promise<{totalSupply: number, marketCap: number}> {
let response = await this.doGetGeneric("economics");
return { totalSupply: response.totalSupply, marketCap: response.marketCap }
}
// ... other methods
}
定制待处理交易
如果出于某种原因, erdjs 提供的默认交易完成检测算法不能满足您的要求,您可能希望对交易等待使用不同的策略,例如:
await transactionWatcher.awaitAllEvents(transaction, ["mySpecialEventFoo", "mySpecialEventBar"]);
await transactionWatcher.awaitAnyEvents(transaction, ["mySpecialEventFoo", "mySpecialEventBar"]);
扩展合约结果解析器
如果由于某种原因(例如一个错误),由 erdjs 提供的默认ResultsParser
不能满足您的需求,您可能想要扩展它并覆盖方法createBundleWithCustomHeuristics()
:
export class MyTailoredResultsParser extends ResultsParser {
protected createBundleWithCustomHeuristics(transaction: ITransactionOnNetwork, transactionMetadata: TransactionMetadata): UntypedOutcomeBundle | null {
let returnMessage: string = "<< extract the message from the input transaction object >>";
let values: Buffer[] = [
Buffer.from("<< extract 1st result from the input transaction object >>"),
Buffer.from("<< extract 2nd result from the input transaction object >>"),
Buffer.from("<< extract 3rd result from the input transaction object >>"),
// ...
]
return {
returnCode: ReturnCode.Ok,
returnMessage: returnMessage,
values: values
};
}
}
重要
当默认ResultsParser
行为不当时,请在 GitHub 上打开一个问题,并且也提供尽可能多的关于不可解析结果的细节(例如,如果可能的话提供交易对象的转储——确保删除任何敏感信息)。