@roochnetwork/rooch-sdk
Version:
539 lines (538 loc) • 17.4 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var client_exports = {};
__export(client_exports, {
RoochClient: () => RoochClient,
isRoochClient: () => isRoochClient
});
module.exports = __toCommonJS(client_exports);
var import_bcs = require("../bcs/index.js");
var import_session = require("../session/index.js");
var import_address = require("../address/index.js");
var import_utils = require("../utils/index.js");
var import_httpTransport = require("./httpTransport.js");
var import_transactions = require("../transactions/index.js");
var import_balance = require("../utils/balance.js");
const DEFAULT_GAS = 5e7;
const ROOCH_CLIENT_BRAND = Symbol.for("@roochnetwork/RoochClient");
function isRoochClient(client) {
return typeof client === "object" && client !== null && client[ROOCH_CLIENT_BRAND] === true;
}
class RoochClient {
get [ROOCH_CLIENT_BRAND]() {
return true;
}
getTransport() {
return this.transport;
}
/**
* Establish a connection to a rooch RPC endpoint
*
* @param options configuration options for the API Client
*/
constructor(options) {
this.transport = options.transport ?? new import_httpTransport.RoochHTTPTransport({ url: options.url });
}
async getRpcApiVersion() {
const resp = await this.transport.request({
method: "rpc.discover",
params: []
});
return resp.info.version;
}
async getChainId() {
if (this.chainID) {
return this.chainID;
}
return this.transport.request({
method: "rooch_getChainID",
params: []
});
}
async executeViewFunction(input) {
const callFunction = new import_transactions.CallFunction(input);
return await this.transport.request({
method: "rooch_executeViewFunction",
params: [
{
function_id: callFunction.functionId(),
args: callFunction.encodeArgs(),
ty_args: callFunction.typeArgs
}
]
});
}
async dryrun(input) {
return await this.transport.request({
method: "rooch_dryRunRawTransaction",
params: [input.txBcsHex]
});
}
async signAndExecuteTransaction({
transaction,
signer,
option = { withOutput: true }
}) {
let transactionHex;
if (transaction instanceof Uint8Array) {
transactionHex = (0, import_utils.str)("hex", transaction);
} else {
let sender = signer.getRoochAddress().toHexAddress();
transaction.setChainId(await this.getChainId());
transaction.setSeqNumber(await this.getSequenceNumber(sender));
transaction.setSender(sender);
if (!transaction.getMaxGas()) {
transaction.setMaxGas(DEFAULT_GAS);
}
const auth = await signer.signTransaction(transaction);
transaction.setAuth(auth);
transactionHex = `0x${transaction.encode().toHex()}`;
}
return await this.transport.request({
method: "rooch_executeRawTransaction",
params: [transactionHex, option]
});
}
async repairIndexer(input) {
await this.transport.request({
method: "rooch_repairIndexer",
params: [input.repairType, input.repairParams]
});
}
async syncStates(input) {
const opt = input.queryOption || {
decode: true,
showDisplay: true
};
return await this.transport.request({
method: "rooch_syncStates",
params: [input.filter, input.cursor, input.limit, opt]
});
}
// Get the states by access_path
async getStates(input) {
const opt = input.stateOption || {
decode: true,
showDisplay: true
};
const result = await this.transport.request({
method: "rooch_getStates",
params: [input.accessPath, opt]
});
const typedResult = result;
return typedResult[0] === null ? [] : typedResult;
}
async listStates(input) {
const opt = input.stateOption || {
decode: true,
showDisplay: true
};
return await this.transport.request({
method: "rooch_listStates",
params: [input.accessPath, input.cursor, input.limit, opt]
});
}
async getModuleAbi(input) {
return await this.transport.request({
method: "rooch_getModuleABI",
params: [input.moduleAddr, input.moduleName]
});
}
async getEvents(input) {
const opt = input.eventOptions || {
decode: true
};
return await this.transport.request({
method: "rooch_getEventsByEventHandle",
params: [input.eventHandle, input.cursor, input.limit, input.descendingOrder, opt]
});
}
async queryEvents(input) {
if (typeof input.filter === "object" && "sender" in input.filter) {
if (input.filter.sender === "") {
throw Error("Invalid Address");
}
}
if (typeof input.filter === "object" && "event_type_with_sender" in input.filter) {
if (input.filter.event_type_with_sender.sender === "") {
throw Error("Invalid Address");
}
}
const opt = input.queryOption || {
decode: true,
showDisplay: true
};
return await this.transport.request({
method: "rooch_queryEvents",
params: [input.filter, input.cursor, input.limit, opt]
});
}
async queryInscriptions(input) {
if (typeof input.filter !== "string" && "owner" in input.filter) {
if (input.filter.owner === "") {
throw Error("Invalid Address");
}
}
return await this.transport.request({
method: "btc_queryInscriptions",
params: [input.filter, input.cursor, input.limit, input.descendingOrder]
});
}
async queryUTXO(input) {
if (typeof input.filter !== "string" && "owner" in input.filter) {
if (input.filter.owner === "") {
throw Error("Invalid Address");
}
}
return this.transport.request({
method: "btc_queryUTXOs",
params: [input.filter, input.cursor, input.limit, input.descendingOrder]
});
}
async broadcastBitcoinTX(input) {
return this.transport.request({
method: "btc_broadcastTX",
params: [input.hex, input.maxfeerate, input.maxburnamount]
});
}
async getObjectStates(input) {
const idsStr = input.ids.join(",");
const opt = input.stateOption || {
decode: true,
showDisplay: true
};
return this.transport.request({
method: "rooch_getObjectStates",
params: [idsStr, opt]
});
}
async getFieldStates(input) {
const opt = input.stateOption || {
decode: true,
showDisplay: true
};
return this.transport.request({
method: "rooch_getFieldStates",
params: [input.objectId, input.fieldKey, opt]
});
}
async listFieldStates(input) {
const opt = input.stateOption || {
decode: true,
showDisplay: true
};
return this.transport.request({
method: "rooch_listFieldStates",
params: [input.objectId, input.cursor, input.limit, opt]
});
}
async queryObjectStates(input) {
if ("owner" in input.filter) {
if (input.filter.owner === "") {
throw Error("Invalid Address");
}
}
if ("object_type_with_owner" in input.filter) {
if (input.filter.object_type_with_owner.owner === "") {
throw Error("Invalid Address");
}
}
const opt = input.queryOption || {
decode: true,
showDisplay: true
};
return this.transport.request({
method: "rooch_queryObjectStates",
params: [input.filter, input.cursor, input.limit, opt]
});
}
async getTransactionsByHash(input) {
return this.transport.request({
method: "rooch_getTransactionsByHash",
params: [input.txHashes]
});
}
async getTransactionsByOrder(input) {
return this.transport.request({
method: "rooch_queryTransactions",
params: [input.cursor, input.limit, input.descendingOrder]
});
}
async queryTransactions(input) {
if (typeof input.filter === "object" && "sender" in input.filter) {
if (input.filter.sender === "") {
throw Error("Invalid Address");
}
}
const opt = input.queryOption || {
decode: true,
showDisplay: true
};
return this.transport.request({
method: "rooch_queryTransactions",
params: [input.filter, input.cursor, input.limit, opt]
});
}
// helper fn
async getSequenceNumber(address2) {
const resp = await this.executeViewFunction({
target: "0x2::account::sequence_number",
args: [import_bcs.Args.address(address2)]
});
if (resp && resp.return_values) {
return BigInt(resp.return_values?.[0]?.decoded_value);
}
return BigInt(0);
}
/**
* Get the total coin balance for one coin type, owned by the address owner.
*/
async getBalance(input) {
const owner = (0, import_address.decodeToRoochAddressStr)(input.owner);
let balanceInfoView = await this.transport.request({
method: "rooch_getBalance",
params: [owner, input.coinType]
});
balanceInfoView.fixedBalance = (0, import_balance.fixedBalance)(balanceInfoView.balance, balanceInfoView.decimals);
return balanceInfoView;
}
async getBalances(input) {
const owner = (0, import_address.decodeToRoochAddressStr)(input.owner);
const result = await this.transport.request({
method: "rooch_getBalances",
params: [owner, input.cursor, input.limit]
});
result.data.forEach((item) => {
item.fixedBalance = (0, import_balance.fixedBalance)(item.balance, item.decimals);
});
return result;
}
async transfer(input) {
const recipient = (0, import_address.decodeToRoochAddressStr)(input.recipient);
const tx = new import_transactions.Transaction();
tx.callFunction({
target: "0x3::transfer::transfer_coin",
args: [import_bcs.Args.address(recipient), import_bcs.Args.u256(BigInt(input.amount))],
typeArgs: [(0, import_transactions.normalizeTypeArgsToStr)(input.coinType)]
});
return await this.signAndExecuteTransaction({
transaction: tx,
signer: input.signer
});
}
async transferObject(input) {
const recipient = (0, import_address.decodeToRoochAddressStr)(input.recipient);
const tx = new import_transactions.Transaction();
tx.callFunction({
target: "0x3::transfer::transfer_object",
args: [import_bcs.Args.address(recipient), import_bcs.Args.objectId(input.objectId)],
typeArgs: [(0, import_transactions.normalizeTypeArgsToStr)(input.objectType)]
});
return await this.signAndExecuteTransaction({
transaction: tx,
signer: input.signer
});
}
async resolveBTCAddress(input) {
const address2 = (0, import_address.decodeToRoochAddressStr)(input.roochAddress);
const result = await this.executeViewFunction({
target: "0x3::address_mapping::resolve_bitcoin",
args: [import_bcs.Args.address(address2)]
});
if (result.vm_status === "Executed" && result.return_values) {
const value = (result.return_values?.[0]?.decoded_value).value;
const address3 = value && value.vec ? (
//compatible with old option version
value.vec.value[0][0]
) : value.bytes;
return new import_address.BitcoinAddress(address3, input.network);
}
return void 0;
}
async createSession({ sessionArgs, signer }) {
return import_session.Session.CREATE({
...sessionArgs,
client: this,
signer
});
}
async removeSession({ authKey, signer }) {
const tx = new import_transactions.Transaction();
tx.callFunction({
target: "0x3::session_key::remove_session_key_entry",
args: [import_bcs.Args.vec("u8", Array.from((0, import_utils.fromHEX)(authKey)))]
});
return (await this.signAndExecuteTransaction({
transaction: tx,
signer
})).execution_info.status.type === "executed";
}
async sessionIsExpired({
address: address2,
authKey
}) {
const _address = (0, import_address.decodeToRoochAddressStr)(address2);
const result = await this.executeViewFunction({
target: "0x3::session_key::is_expired_session_key",
args: [import_bcs.Args.address(_address), import_bcs.Args.vec("u8", Array.from((0, import_utils.fromHEX)(authKey)))]
});
if (result.vm_status !== "Executed") {
throw new Error("view 0x3::session_key::is_expired_session_key fail");
}
return result.return_values[0]?.decoded_value;
}
async getAllModules({
package_address,
limit,
cursor
}) {
const packageObjectID = `0x14481947570f6c2f50d190f9a13bf549ab2f0c9debc41296cd4d506002379659${(0, import_address.decodeToPackageAddressStr)(package_address)}`;
const result = await this.transport.request({
method: "rooch_listFieldStates",
params: [packageObjectID, cursor, limit, { decode: true }]
});
const moduleInfo = result;
const moduleMap = /* @__PURE__ */ new Map();
if (moduleInfo && typeof moduleInfo === "object" && "data" in moduleInfo) {
const { data } = moduleInfo;
if (Array.isArray(data)) {
for (const item of data) {
const decodedValue = item?.state?.decoded_value;
if (decodedValue) {
const name = decodedValue?.value?.name;
const byte_codes = decodedValue?.value?.value?.value?.byte_codes;
if (name && byte_codes) {
moduleMap.set(name, byte_codes);
}
}
}
}
}
return moduleMap;
}
async getSessionKeys({
address: address2,
limit,
cursor
}) {
const _address = (0, import_address.decodeToRoochAddressStr)(address2);
const accessPath = `/resource/${_address}/0x3::session_key::SessionKeys`;
const states = await this.getStates({
accessPath,
stateOption: {
decode: true,
showDisplay: true
}
});
if (states.length === 0) {
return {
data: [],
hasNextPage: false
};
}
const tableId = (states?.[0]?.decoded_value).value["value"].value["keys"].value["handle"].value["id"];
const tablePath = `/table/${tableId}`;
const statePage = await this.listStates({
accessPath: tablePath,
cursor,
limit: limit?.toString(),
stateOption: {
decode: true,
showDisplay: true
}
});
const parseScopes = (data) => {
const result = new Array();
for (const scope of data) {
const [pkg, mod, fn] = [scope[0], scope[1], scope[2]];
result.push(`${pkg}::${mod}::${fn}`);
}
return result;
};
const parseStateToSessionInfo = () => {
const result = new Array();
for (const state of statePage.data) {
const moveValue = state?.state?.decoded_value;
if (moveValue) {
const val = moveValue.value.value.value;
result.push({
appName: val.app_name,
appUrl: val.app_url,
authenticationKey: val.authentication_key,
scopes: parseScopes(val.scopes.value),
createTime: parseInt(val.create_time),
lastActiveTime: parseInt(val.last_active_time),
maxInactiveInterval: parseInt(val.max_inactive_interval)
});
}
}
return result.sort((a, b) => b.createTime - a.createTime);
};
return {
data: parseStateToSessionInfo(),
cursor: statePage.next_cursor,
hasNextPage: statePage.has_next_page
};
}
async subscribeEventWithSSE(input) {
const params = input.filter ? input.filter : "all";
return this.transport.subscribeWithSSE({
method: "/subscribe/sse/events",
params,
onMessage: input.onMessage,
onError: input.onError,
signal: input.signal
});
}
async subscribeTransactionWithSSE(input) {
const params = input.filter ? input.filter : "all";
return this.transport.subscribeWithSSE({
method: "/subscribe/sse/transactions",
params,
onMessage: input.onMessage,
onError: input.onError,
signal: input.signal
});
}
async subscribeEvent(input) {
const params = input.filter ? [input.filter] : ["all"];
return this.transport.subscribe({
method: "rooch_subscribeEvents",
params,
onMessage: input.onMessage,
signal: input.signal
});
}
async subscribeTransaction(input) {
const params = input.filter ? [input.filter] : ["all"];
return this.transport.subscribe({
method: "rooch_subscribeTransactions",
params,
onMessage: input.onMessage,
signal: input.signal
});
}
events() {
throw new Error("Method not implemented. Use getEvents() or queryEvents() instead.");
}
destroy() {
this.transport.destroy();
}
}
//# sourceMappingURL=client.js.map