UNPKG

@yubing744/rooch-sdk

Version:
263 lines (228 loc) 7.28 kB
// Copyright (c) RoochNetwork // SPDX-License-Identifier: Apache-2.0 import fetch from 'isomorphic-fetch' import { HTTPTransport, RequestManager } from '@open-rpc/client-js' import { JsonRpcClient } from '../generated/client' import { ChainInfo, Network, DevNetwork } from '../constants' import { AnnotatedFunctionResultView, bcsTypes, Bytes, EventOptions, EventPageView, GlobalStateView, InscriptionStatePageView, StateOptions, StatePageView, StateView, TableStateView, TransactionWithInfoPageView, TransactionWithInfoView, UTXOStatePageView, } from '../types' import { addressToSeqNumber, encodeArg, functionIdToStirng, toHexString, typeTagToString, } from '../utils' import { IClient } from './interface' import { ExecuteViewFunctionParams, GetEventsParams, GetTransactionsParams, QueryGlobalStatesParams, QueryInscriptionsParams, QueryTableStatesParams, QueryUTXOsParams, ResoleRoochAddressParams, ListStatesParams, } from './types.ts' export const ROOCH_CLIENT_BRAND = Symbol.for('@roochnetwork/rooch-sdk') export function isRoochClient(client: unknown): client is RoochClient { return ( typeof client === 'object' && client !== null && (client as { [ROOCH_CLIENT_BRAND]: unknown })[ROOCH_CLIENT_BRAND] === true ) } /** * Configuration options for the JsonRpcProvider. If the value of a field is not provided, * value in `DEFAULT_OPTIONS` for that field will be used */ export type RpcProviderOptions = { /** * Cache timeout in seconds for the RPC API Version */ versionCacheTimeoutInSeconds?: number /** Allow defining a custom RPC client to use */ fetcher?: typeof fetch } const DEFAULT_OPTIONS: RpcProviderOptions = { versionCacheTimeoutInSeconds: 600, } export class RoochClient implements IClient { public network: Network private client: JsonRpcClient private rpcApiVersion: string | undefined private cacheExpiry: number | undefined constructor(network: Network = DevNetwork, public options: RpcProviderOptions = DEFAULT_OPTIONS) { this.network = network const opts = { ...DEFAULT_OPTIONS, ...options } this.options = opts this.client = new JsonRpcClient( new RequestManager([ new HTTPTransport(network.url, { headers: { 'Content-Type': 'application/json', }, fetcher: opts.fetcher, }), ]), ) } switchChain(network: Network) { this.client.close() this.network = network this.client = new JsonRpcClient( new RequestManager([ new HTTPTransport(network.url, { headers: { 'Content-Type': 'application/json', }, fetcher: this.options.fetcher, }), ]), ) } ChainInfo(): ChainInfo { return this.network.info } getChainId(): number { return this.network.id } async getRpcApiVersion(): Promise<string | undefined> { if (this.rpcApiVersion && this.cacheExpiry && this.cacheExpiry <= Date.now()) { return this.rpcApiVersion } try { this.rpcApiVersion = await this.client.getRpcApiVersion() this.cacheExpiry = // Date.now() is in milliseconds, but the timeout is in seconds Date.now() + (this.options.versionCacheTimeoutInSeconds ?? 0) * 1000 return this.rpcApiVersion } catch (err) { return undefined } } // Execute a read-only function call The function do not change the state of Application async executeViewFunction( params: ExecuteViewFunctionParams, ): Promise<AnnotatedFunctionResultView> { const tyStrArgs = params.tyArgs?.map((v) => typeTagToString(v)) const bcsArgs = params.args?.map((arg) => toHexString(encodeArg(arg))) as any return this.client.rooch_executeViewFunction({ function_id: functionIdToStirng(params.funcId), ty_args: tyStrArgs ?? [], args: bcsArgs ?? [], }) } // Send the signed transaction in bcs hex format // This method does not block waiting for the transaction to be executed. async sendRawTransaction(playload: Bytes): Promise<string> { return this.client.rooch_sendRawTransaction(playload) } async getTransactionsByHashes(tx_hashes: string[]): Promise<TransactionWithInfoView | null[]> { return await this.client.rooch_getTransactionsByHash(tx_hashes) } async getTransactions(params: GetTransactionsParams): Promise<TransactionWithInfoPageView> { return this.client.rooch_getTransactionsByOrder( params.cursor.toString(), params.limit.toString(), ) } // Get the events by event handle id async getEvents(params: GetEventsParams): Promise<EventPageView> { return await this.client.rooch_getEventsByEventHandle( params.eventHandleType, params.cursor.toString(), params.limit.toString(), { decode: true } as EventOptions, ) } // Get the states by access_path async getStates(access_path: string): Promise<StateView | null[]> { return await this.client.rooch_getStates(access_path, { decode: true } as StateOptions) } // TODO: bug? next_cursor The true type is string async listStates(params: ListStatesParams): Promise<StatePageView> { return await this.client.rooch_listStates( params.accessPath, params.cursor as any, params.limit.toString(), { decode: true, } as StateOptions, ) } async queryGlobalStates(params: QueryGlobalStatesParams): Promise<GlobalStateView> { return await this.client.rooch_queryGlobalStates( params.filter, params.cursor as any, params.limit.toString(), params.descending_order, ) } async queryTableStates(params: QueryTableStatesParams): Promise<TableStateView> { return await this.client.rooch_queryTableStates( params.filter, params.cursor as any, params.limit.toString(), params.descending_order, ) } async queryInscriptions(params: QueryInscriptionsParams): Promise<InscriptionStatePageView> { return await this.client.btc_queryInscriptions( params.filter as any, params.cursor as any, params.limit.toString(), params.descending_order, ) } async queryUTXOs(params: QueryUTXOsParams): Promise<UTXOStatePageView> { return await this.client.btc_queryUTXOs( params.filter as any, params.cursor as any, params.limit.toString(), params.descending_order, ) } // Resolve the rooch address async resoleRoochAddress(params: ResoleRoochAddressParams): Promise<string> { const ma = new bcsTypes.MultiChainAddress( BigInt(params.multiChainID), addressToSeqNumber(params.address), ) const result = await this.executeViewFunction({ funcId: '0x3::address_mapping::resolve_or_generate', tyArgs: [], args: [ { type: { Struct: { address: '0x3', module: 'address_mapping', name: 'MultiChainAddress', }, }, value: ma, }, ], }) if (result && result.vm_status === 'Executed' && result.return_values) { return result.return_values[0].decoded_value as string } throw new Error('resolve rooch address fail') } }