Skip to main content
Glama
flow.connector.ts3.83 kB
import * as fcl from "@onflow/fcl"; import type { ArgsFn } from "@onflow/fcl-core/types/exec/args"; import type { Account, TransactionStatus } from "@onflow/typedefs"; import type { Network } from "../config"; import type { Authz, IFlowScriptExecutor } from "../types"; export class FlowConnector implements IFlowScriptExecutor { private isInited = false; private locallyInitedPromise: Promise<void> | null = null; /** * Initialize the Flow SDK */ constructor( private readonly flowJSON: object, public readonly network: Network, private readonly defaultRpcEndpoint: string | undefined = undefined, ) {} /** * Get the RPC endpoint */ get rpcEndpoint() { switch (this.network) { case "mainnet": return this.defaultRpcEndpoint ?? "https://mainnet.onflow.org"; case "testnet": return this.defaultRpcEndpoint ?? "https://testnet.onflow.org"; default: throw new Error(`Network type ${this.network} is not supported`); } } get fcl() { return fcl; } /** * Initialize the Flow SDK */ async onModuleInit() { if (this.isInited) return; const cfg = fcl.config(); // Required cfg.put("flow.network", this.network); // Set soft finality cfg.put("fcl.experimental.softFinality", true); // Set the maximum of gas limit cfg.put("fcl.limit", 9999); // Set the RPC endpoint cfg.put("accessNode.api", this.rpcEndpoint); await cfg.load({ flowJSON: this.flowJSON as Record<string, unknown> }, { ignoreConflicts: true }); this.isInited = true; } /** * Ensure the Flow SDK is initialized */ private async ensureInited() { if (this.isInited) return; if (!this.locallyInitedPromise) { this.locallyInitedPromise = this.onModuleInit(); } return await this.locallyInitedPromise; } /** * Get account information */ async getAccount(addr: string): Promise<Account> { await this.ensureInited(); return await fcl.send([fcl.getAccount(addr)]).then(fcl.decode); } /** * General method of sending transaction */ async sendTransaction(code: string, args: ArgsFn, mainAuthz: Authz) { await this.ensureInited(); if (typeof mainAuthz !== "undefined") { return await fcl.mutate({ cadence: code, args: args, proposer: mainAuthz, payer: mainAuthz, authorizations: [mainAuthz], }); } return await fcl.mutate({ cadence: code, args: args, }); } /** * Get chain id */ async getChainId() { await this.ensureInited(); return await fcl.getChainId(); } /** * Get transaction status */ async getTransactionStatus(transactionId: string): Promise<TransactionStatus> { await this.ensureInited(); return await fcl.tx(transactionId).onceExecuted(); } async onceTransactionSealed(transactionId: string): Promise<TransactionStatus> { await this.ensureInited(); return fcl.tx(transactionId).onceSealed(); } async onceTransactionExecuted(transactionId: string): Promise<TransactionStatus> { await this.ensureInited(); return fcl.tx(transactionId).onceExecuted(); } /** * Get block object * @param blockId */ async getBlockHeaderObject(blockId: string) { await this.ensureInited(); return await fcl.send([fcl.getBlockHeader(), fcl.atBlockId(blockId)]).then(fcl.decode); } /** * Send script */ async executeScript<T>(code: string, args: ArgsFn, defaultValue: T): Promise<T> { await this.ensureInited(); try { const queryResult = await fcl.query({ cadence: code, args, }); return (queryResult as T) ?? defaultValue; } catch (e) { console.error(e); return defaultValue; } } } export default FlowConnector;

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Outblock/flow-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server