UNPKG

@0xobelisk/rooch-client

Version:
688 lines (676 loc) 22.5 kB
"use strict"; 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 __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var __accessCheck = (obj, member, msg) => { if (!member.has(obj)) throw TypeError("Cannot " + msg); }; var __privateGet = (obj, member, getter) => { __accessCheck(obj, member, "read from private field"); return getter ? getter.call(obj) : member.get(obj); }; var __privateAdd = (obj, member, value) => { if (member.has(obj)) throw TypeError("Cannot add the same private member more than once"); member instanceof WeakSet ? member.add(obj) : member.set(obj, value); }; // src/index.ts var src_exports = {}; __export(src_exports, { Dubhe: () => Dubhe, RoochAccountManager: () => RoochAccountManager, RoochContractFactory: () => RoochContractFactory, RoochInteractor: () => RoochInteractor, loadMetadata: () => loadMetadata }); module.exports = __toCommonJS(src_exports); __reExport(src_exports, require("@roochnetwork/rooch-sdk"), module.exports); // src/dubhe.ts var import_rooch_sdk4 = require("@roochnetwork/rooch-sdk"); // src/libs/roochAccountManager/index.ts var import_rooch_sdk2 = require("@roochnetwork/rooch-sdk"); // src/libs/roochAccountManager/keypair.ts var import_rooch_sdk = require("@roochnetwork/rooch-sdk"); var getDerivePathForROOCH = (derivePathParams = {}) => { const { accountIndex = 0, isExternal = false, addressIndex = 0 } = derivePathParams; return `m/54'/784'/${accountIndex}'/${isExternal ? 1 : 0}'/${addressIndex}'`; }; var getKeyPair = (mnemonics, derivePathParams = {}) => { const derivePath = getDerivePathForROOCH(derivePathParams); return import_rooch_sdk.Secp256k1Keypair.deriveKeypair(mnemonics, derivePath); }; // src/libs/roochAccountManager/crypto.ts var import_bip39 = require("@scure/bip39"); var import_english = require("@scure/bip39/wordlists/english"); var generateMnemonic = (numberOfWords = 24) => { const strength = numberOfWords === 12 ? 128 : 256; return (0, import_bip39.generateMnemonic)(import_english.wordlist, strength); }; // src/libs/roochAccountManager/index.ts var RoochAccountManager = class { /** * Support the following ways to init the SuiToolkit: * 1. mnemonics * 2. secretKey (base64 or hex) * If none of them is provided, will generate a random mnemonics with 24 words. * * @param mnemonics, 12 or 24 mnemonics words, separated by space * @param secretKey, base64 or hex string, when mnemonics is provided, secretKey will be ignored */ constructor({ mnemonics, secretKey } = {}) { this.mnemonics = mnemonics || ""; this.secretKey = secretKey || ""; if (!this.mnemonics && !this.secretKey) { this.mnemonics = generateMnemonic(24); } this.currentKeyPair = this.secretKey ? import_rooch_sdk2.Secp256k1Keypair.fromSecretKey(secretKey) : getKeyPair(this.mnemonics); this.currentAddress = this.currentKeyPair.getRoochAddress(); this.currentBitcoinAddress = this.currentKeyPair.getBitcoinAddress(); } /** * if derivePathParams is not provided or mnemonics is empty, it will return the currentKeyPair. * else: * it will generate keyPair from the mnemonic with the given derivePathParams. */ getKeyPair(derivePathParams) { if (!derivePathParams || !this.mnemonics) return this.currentKeyPair; return getKeyPair(this.mnemonics, derivePathParams); } /** * if derivePathParams is not provided or mnemonics is empty, it will return the currentAddress. * else: * it will generate address from the mnemonic with the given derivePathParams. */ getAddress(derivePathParams) { if (!derivePathParams || !this.mnemonics) return this.currentAddress; return getKeyPair(this.mnemonics, derivePathParams).getRoochAddress(); } getBitcoinAddress(derivePathParams) { if (!derivePathParams || !this.mnemonics) return this.currentBitcoinAddress; return getKeyPair(this.mnemonics, derivePathParams).getBitcoinAddress(); } /** * Switch the current account with the given derivePathParams. * This is only useful when the mnemonics is provided. For secretKey mode, it will always use the same account. */ switchAccount(derivePathParams) { if (this.mnemonics) { this.currentKeyPair = getKeyPair(this.mnemonics, derivePathParams); this.currentAddress = this.currentKeyPair.getRoochAddress(); this.currentBitcoinAddress = this.currentKeyPair.getBitcoinAddress(); } } }; // src/libs/roochInteractor/roochInteractor.ts var import_rooch_sdk3 = require("@roochnetwork/rooch-sdk"); // src/libs/roochInteractor/util.ts var delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); // src/libs/roochInteractor/roochInteractor.ts var RoochInteractor = class { constructor(fullNodeUrls, network) { if (fullNodeUrls.length === 0) throw new Error("fullNodeUrls must not be empty"); this.clients = fullNodeUrls.map((url) => new import_rooch_sdk3.RoochClient({ url })); this.currentClient = this.clients[0]; this.fullNodes = fullNodeUrls; this.currentFullNode = fullNodeUrls[0]; this.network = network; } switchToNextProvider() { const currentClientIdx = this.clients.indexOf(this.currentClient); this.currentClient = this.clients[(currentClientIdx + 1) % this.clients.length]; this.currentFullNode = this.fullNodes[(currentClientIdx + 1) % this.clients.length]; } async createSession(sessionArgs, signer) { for (const client of this.clients) { try { const session = await client.createSession({ sessionArgs, signer }); return session; } catch (err) { console.warn(`Failed to create session: ${err}`); await delay(2e3); } } throw new Error("Failed to create session with all fullnodes"); } async signAndExecuteTransaction(transaction, signer, option) { for (const client of this.clients) { try { const txnResponse = await client.signAndExecuteTransaction({ transaction, signer, option }); return txnResponse; } catch (err) { console.warn(`Failed to send transaction: ${err}`); await delay(2e3); } } throw new Error("Failed to send transaction with all fullnodes"); } async executeViewFunction(contractAddress, moduleName, funcName, typeArguments = [], args = []) { for (const client of this.clients) { try { const input = { address: contractAddress, module: moduleName, function: funcName, typeArgs: typeArguments, args }; const result = await client.executeViewFunction(input); return result; } catch (err) { await delay(2e3); console.warn(`Failed to execute view function: ${err}`); } } throw new Error("Failed to execute view function with all fullnodes"); } async getModuleAbi(accountAddress, moduleName) { for (const client of this.clients) { try { const result = await client.getModuleAbi({ moduleAddr: accountAddress, moduleName }); return result; } catch (err) { await delay(2e3); console.warn( `Failed to get ModuleAbi ${accountAddress} ${moduleName}: ${err}` ); } } throw new Error( `Failed to get ModuleAbi ${accountAddress} ${moduleName} with all fullnodes` ); } async getModuleAbis(accountAddress, modules) { for (const client of this.clients) { try { const result = []; for (const moduleName of modules) { const moduleAbi = await client.getModuleAbi({ moduleAddr: accountAddress, moduleName }); result.push(moduleAbi); } return result; } catch (err) { await delay(2e3); console.warn( `Failed to get ModuleAbi ${accountAddress} ${modules.join( "," )}: ${err}` ); } } throw new Error( `Failed to get ModuleAbi ${accountAddress} ${modules.join( "," )} with all fullnodes` ); } async getBalance(address3, coinType) { for (const client of this.clients) { try { const result = await client.getBalance({ owner: address3, coinType }); return result; } catch (err) { await delay(2e3); console.warn(`Failed to get balance: ${err}`); } } throw new Error(`Failed to get balance with all fullnodes`); } async getRpcApiVersion() { for (const client of this.clients) { try { const result = await client.getRpcApiVersion(); return result; } catch (err) { await delay(2e3); console.warn(`Failed to get RPC API version: ${err}`); } } throw new Error("Failed to get RPC API version with all fullnodes"); } async getChainId() { for (const client of this.clients) { try { const result = await client.getChainId(); return result; } catch (err) { await delay(2e3); console.warn(`Failed to get chain ID: ${err}`); } } throw new Error("Failed to get chain ID with all fullnodes"); } async getStates(params) { for (const client of this.clients) { try { const result = await client.getStates(params); return result; } catch (err) { await delay(2e3); console.warn(`Failed to get states: ${err}`); } } throw new Error("Failed to get states with all fullnodes"); } async listStates(params) { for (const client of this.clients) { try { const result = await client.listStates(params); return result; } catch (err) { await delay(2e3); console.warn(`Failed to list states: ${err}`); } } throw new Error("Failed to list states with all fullnodes"); } async getEvents(input) { for (const client of this.clients) { try { const result = await client.getEvents(input); return result; } catch (err) { await delay(2e3); console.warn(`Failed to get events: ${err}`); } } throw new Error("Failed to get events with all fullnodes"); } async transfer(input) { for (const client of this.clients) { try { const result = await client.transfer(input); return result; } catch (err) { await delay(2e3); console.warn(`Failed to transfer: ${err}`); } } throw new Error("Failed to transfer with all fullnodes"); } async transferObject(input) { for (const client of this.clients) { try { const result = await client.transferObject(input); return result; } catch (err) { await delay(2e3); console.warn(`Failed to transfer object: ${err}`); } } throw new Error("Failed to transfer object with all fullnodes"); } }; // src/libs/roochContractFactory/index.ts var RoochContractFactory = class { /** * @param packageId * @param metadata */ constructor({ packageId, metadata } = {}) { this.packageId = packageId || ""; this.metadata = metadata || void 0; } }; // src/dubhe.ts function isUndefined(value) { return value === void 0; } function withMeta(meta, creator) { creator.meta = meta; return creator; } function createQuery(meta, fn) { return withMeta( meta, async ({ params, typeArguments } = {}) => { const result = await fn(params, typeArguments); return result; } ); } function createTx(meta, fn) { return withMeta( meta, async ({ tx, signer, params, typeArguments, isRaw }) => { const result = await fn(tx, signer, params, typeArguments, isRaw); return result; } ); } var _query, _tx, _exec, _read; var Dubhe = class { /** * Support the following ways to init the DubheClient: * 1. mnemonics * 2. secretKey (base64 or hex) * If none of them is provided, will generate a random mnemonics with 24 words. * * @param mnemonics, 12 or 24 mnemonics words, separated by space * @param secretKey, base64 or hex string, when mnemonics is provided, secretKey will be ignored * @param networkType, 'testnet' | 'mainnet' | 'devnet' | 'localnet', default is 'devnet' * @param fullnodeUrl, the fullnode url, default is the preconfig fullnode url for the given network type * @param packageId */ constructor({ mnemonics, secretKey, networkType, fullnodeUrls, packageId, metadata } = {}) { __privateAdd(this, _query, {}); __privateAdd(this, _tx, {}); __privateAdd(this, _exec, async (meta, tx, signer, params, typeArguments, isRaw) => { if (isRaw === true) { return tx.callFunction({ target: `${this.contractFactory.packageId}::${meta.moduleName}::${meta.funcName}`, args: params, typeArgs: typeArguments }); } tx.callFunction({ target: `${this.contractFactory.packageId}::${meta.moduleName}::${meta.funcName}`, args: params, typeArgs: typeArguments }); return await this.signAndExecuteTransaction(tx, signer); }); __privateAdd(this, _read, async (meta, params, typeArguments) => { return this.roochInteractor.executeViewFunction( meta.contractAddress, meta.moduleName, meta.funcName, typeArguments, params ); }); this.accountManager = new RoochAccountManager({ mnemonics, secretKey }); fullnodeUrls = fullnodeUrls || [(0, import_rooch_sdk4.getRoochNodeUrl)(networkType ?? "mainnet")]; this.roochInteractor = new RoochInteractor(fullnodeUrls); this.packageId = packageId; if (metadata !== void 0) { this.metadata = metadata; Object.values(metadata).forEach((metadataRes) => { let contractAddress = metadataRes.address; let moduleName = metadataRes.name; Object.values(metadataRes.functions).forEach((value) => { const meta = { contractAddress, moduleName, funcName: value.name, isEntry: value.is_entry, typeParams: value.type_params, params: value.params, return: value.return }; if (isUndefined(__privateGet(this, _query)[moduleName])) { __privateGet(this, _query)[moduleName] = {}; } if (isUndefined(__privateGet(this, _query)[moduleName][value.name])) { __privateGet(this, _query)[moduleName][value.name] = createQuery( meta, (p, type_p) => __privateGet(this, _read).call(this, meta, p, type_p) ); } if (isUndefined(__privateGet(this, _tx)[moduleName])) { __privateGet(this, _tx)[moduleName] = {}; } if (isUndefined(__privateGet(this, _tx)[moduleName][value.name])) { __privateGet(this, _tx)[moduleName][value.name] = createTx( meta, (tx, s, p, type_p, isRaw) => __privateGet(this, _exec).call(this, meta, tx, s, p, type_p, isRaw) ); } }); }); } this.contractFactory = new RoochContractFactory({ packageId, metadata }); } get query() { return __privateGet(this, _query); } get tx() { return __privateGet(this, _tx); } /** * if derivePathParams is not provided or mnemonics is empty, it will return the keypair. * else: * it will generate signer from the mnemonic with the given derivePathParams. * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard */ getKeypair(derivePathParams) { return this.accountManager.getKeyPair(derivePathParams); } /** * if derivePathParams is not provided or mnemonics is empty, it will return the currentSigner. * else: * it will generate signer from the mnemonic with the given derivePathParams. * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard */ getSigner(derivePathParams) { const keyPair = this.accountManager.getKeyPair(derivePathParams); return keyPair; } /** * @description Switch the current account with the given derivePathParams * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard */ switchAccount(derivePathParams) { this.accountManager.switchAccount(derivePathParams); } /** * @description Get the address of the account for the given derivePathParams * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard */ getBech32Address(derivePathParams) { return this.accountManager.getAddress(derivePathParams).toBech32Address(); } getRoochAddress(derivePathParams) { return this.accountManager.getAddress(derivePathParams); } getHexAddress(derivePathParams) { return this.accountManager.getAddress(derivePathParams).toHexAddress(); } getBitcoinAddress(derivePathParams) { return this.accountManager.getBitcoinAddress(derivePathParams); } currentAddress() { return this.accountManager.currentAddress; } client() { return this.roochInteractor.currentClient; } getPackageId() { return this.contractFactory.packageId; } getMetadata() { return this.contractFactory.metadata; } getNetwork() { return this.roochInteractor.network; } getFullNodeUrl() { return this.roochInteractor.currentFullNode; } async getRpcApiVersion() { return this.roochInteractor.getRpcApiVersion(); } async getChainId() { return this.roochInteractor.getChainId(); } async getBalance(accountAddress, coinType, outputOnly) { try { if (accountAddress === void 0) { accountAddress = this.getBech32Address(); } if (coinType === void 0) { coinType = "0x3::gas_coin::RGas"; } const resource = await this.roochInteractor.getBalance( accountAddress, coinType ); return outputOnly ? resource : resource.balance; } catch (err) { const errorMessage = err instanceof Error ? err.message : String(err); throw new Error( `Failed to get ${coinType} balance for address ${accountAddress}: ${errorMessage}` ); } } async signAndExecuteTransaction(transaction, signer, derivePathParams) { if (signer === void 0) { signer = this.getSigner(derivePathParams); } return this.roochInteractor.signAndExecuteTransaction(transaction, signer, { withOutput: true }); } async signAndSendTransaction(tx, derivePathParams) { const sender = this.getSigner(derivePathParams); return this.signAndExecuteTransaction(tx, sender); } async createSession(sessionArgs, signer, derivePathParams) { if (signer === void 0) { signer = this.getSigner(derivePathParams); } return this.roochInteractor.createSession(sessionArgs, signer); } async moveCall(callParams) { const { target, params = [], typeArguments = [], signer, derivePathParams } = callParams; const effectiveSigner = signer ?? this.getSigner(derivePathParams); console.log("effectiveSigner", effectiveSigner.getRoochAddress().toStr()); const tx = new import_rooch_sdk4.Transaction(); tx.callFunction({ target, args: params, typeArgs: typeArguments }); return this.signAndExecuteTransaction( tx, effectiveSigner, derivePathParams ); } async publishPackage(callParams) { const { packageBytes, signer, derivePathParams } = callParams; return this.moveCall({ target: `0x2::module_store::publish_package_entry`, params: [import_rooch_sdk4.Args.vec("u8", Array.from(packageBytes))], signer, derivePathParams }); } async getStates(params) { return this.roochInteractor.getStates(params); } async listStates(params) { return this.roochInteractor.listStates(params); } async getEvents(input) { return this.roochInteractor.getEvents(input); } async transfer(input, signer, derivePathParams) { if (signer === void 0) { signer = this.getSigner(derivePathParams); } return this.roochInteractor.transfer({ ...input, signer }); } async transferObject(input, signer, derivePathParams) { if (signer === void 0) { signer = this.getSigner(derivePathParams); } return this.roochInteractor.transferObject({ ...input, signer }); } }; _query = new WeakMap(); _tx = new WeakMap(); _exec = new WeakMap(); _read = new WeakMap(); // src/metadata/index.ts var import_rooch_sdk5 = require("@roochnetwork/rooch-sdk"); async function loadMetadata(networkType, packageId, modules, fullnodeUrls) { fullnodeUrls = fullnodeUrls ?? [(0, import_rooch_sdk5.getRoochNodeUrl)(networkType)]; const roochInteractor = new RoochInteractor(fullnodeUrls); if (packageId !== void 0) { const jsonData = await roochInteractor.getModuleAbis(packageId, modules); return jsonData; } else { console.error("please set your package id."); } } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { Dubhe, RoochAccountManager, RoochContractFactory, RoochInteractor, loadMetadata, ...require("@roochnetwork/rooch-sdk") }); //# sourceMappingURL=index.js.map