Welcome to FIXeS on-chain interactions documentation
Overview
In this section, we provide detailed instructions on interacting with the FIXeS contract on the blockchain. To effectively interact with the FIXeS contract, users should possess a basic understanding of blockchain technology, smart contracts, and the Flow blockchain that the FIXeS contract is deployed on.
For front-end or NodeJS projects, we have prepared a more user-friendly way of integration. You can follow this guide to get started.
Requirements
Node version v16.0.0 or higher.
FCL(Flow Client Library) installation: Official Doc
Dependencies Installation
Install FIXeS contracts to your application via npm, yarn, or pnpm
npmi@fixes/contracts
yarnadd@fixes/contracts
pnpmadd@fixes/contracts
Include *.cdc assets for your project
Interacting with the Flow blockchain requires using transactions/scripts, and all necessary ones are included in @fixes/contracts package. However, to use them in your application, you need to make sure that your building tool can recognize this file extension first.
FCL is an all-in-one JS library to interact with Flow blockchain, If you are not familiar with it, you can refer to the code below.
Here is an independent wrapped class of FCL :
/// This is a TypeScript example/// If some type is not found, you can directly change it to anyimport*as fcl from"@onflow/fcl";importtype { Account, TransactionStatus } from"@onflow/typedefs";exporttypeNetworkType="mainnet"|"testnet"|"emulator";let isGloballyInited =false;let globallyPromise =null;exportclassFlowService {publicreadonly network:NetworkType;privatereadonly flowJSON:object;/** * Initialize the Flow SDK */constructor(flowJSON:object) {this.network = (import.meta.env.PUBLIC_FLOW_NETWORKasNetworkType) ??"emulator";this.flowJSON = flowJSON; }asynconModuleInit() {if (isGloballyInited) return;constcfg=fcl.config();// Requiredawaitcfg.put("flow.network",this.network);// Set the maximum of gas limitawaitcfg.put("fcl.limit",9999);// Note: If you don't need to be compatible with an FCL-compatible wallet// you don't need to configure these two parameters.awaitcfg.put("app.detail.title","App Title");awaitcfg.put("app.detail.icon","App Icon URL");switch (this.network) {case"mainnet":// Requiredawaitcfg.put("accessNode.api",import.meta.env.PUBLIC_MAINNET_ENDPOINT??"https://mainnet.onflow.org" );// Note: If you don't need to be compatible with an FCL-compatible wallet// you don't need to configure these two following parameters.awaitcfg.put("discovery.wallet","https://fcl-discovery.onflow.org/authn" );awaitcfg.put("discovery.authn.endpoint","https://fcl-discovery.onflow.org/api/authn" );break;case"testnet":// Requiredawaitcfg.put("accessNode.api","https://testnet.onflow.org");// Note: If you don't need to be compatible with an FCL-compatible wallet// you don't need to configure these two following parameters.awaitcfg.put("discovery.wallet","https://fcl-discovery.onflow.org/testnet/authn" );awaitcfg.put("discovery.authn.endpoint","https://fcl-discovery.onflow.org/api/testnet/authn" );break;case"emulator":// Requiredawaitcfg.put("accessNode.api","http://localhost:8888");// Note: If you don't need to be compatible with an FCL-compatible wallet// you don't need to configure these following parameters.awaitcfg.put("discovery.wallet","http://localhost:8701/fcl/authn");break;default:thrownewError(`Unknown network: ${String(this.network)}`); }// Load Flow JSONawaitcfg.load({ flowJSON:this.flowJSON }); isGloballyInited =true; }/** * Ensure the Flow SDK is initialized */privateasyncensureInited() {if (isGloballyInited) return;if (!globallyPromise) { globallyPromise =this.onModuleInit(); }returnawait globallyPromise; }/** * Authenticate for current user * Only supported on the front-end. */asyncauthenticate() {awaitthis.ensureInited();fcl.authenticate(); }/** * Logout * Only supported on the front-end. */unauthenticate() {fcl.unauthenticate(); }/** * Get the current logged-in * Only supported on the front-end. */getcurrentUser() {returnfcl.currentUser; }/** * Get account information */asyncgetAccount(addr:string):Promise<Account> {awaitthis.ensureInited();returnawaitfcl.send([fcl.getAccount(addr)]).then(fcl.decode); }/** * General method of sending transaction */asyncsendTransaction( code:string, args:fcl.ArgumentFunction, mainAuthz?:fcl.FclAuthorization, extraAuthz?:fcl.FclAuthorization[] ) {awaitthis.ensureInited();if (typeof mainAuthz !=="undefined") {returnawaitfcl.mutate({ cadence: code, args: args, proposer: mainAuthz, payer: mainAuthz, authorizations: (extraAuthz?.length??0) ===0? [mainAuthz]: [mainAuthz,...extraAuthz], }); } else {returnawaitfcl.mutate({ cadence: code, args: args, }); } }/** * Get transaction status */asyncgetTransactionStatus( transactionId:string ):Promise<TransactionStatus> {awaitthis.ensureInited();returnawaitfcl.tx(transactionId).onceExecuted(); }/** * Get chain id */asyncgetChainId() {awaitthis.ensureInited();returnawaitfcl.getChainId(); }/** * Send transaction with single authorization */asynconceTransactionSealed( transactionId:string ):Promise<TransactionStatus> {awaitthis.ensureInited();returnfcl.tx(transactionId).onceSealed(); }/** * Get block object * @param blockId */asyncgetBlockHeaderObject(blockId:string):Promise<fcl.BlockHeaderObject> {awaitthis.ensureInited();returnawait fcl// eslint-disable-next-line @typescript-eslint/no-unsafe-argument.send([fcl.getBlockHeader(),fcl.atBlockId(blockId)]).then(fcl.decode); }/** * Send script */asyncexecuteScript<T>( code:string, args:fcl.ArgumentFunction, defaultValue:T ):Promise<T> {awaitthis.ensureInited();try {constqueryResult=awaitfcl.query({ cadence: code, args, });return (queryResult asT) ?? defaultValue; } catch (e) {console.error(e);return defaultValue; } }}
If you don't need to use an FCL-compatible wallet for on-chain interactions, you can use this Signer class:
In the following documentation, flow means an instence of flowSigner or flowService as the subject of function calls.
// FIXeS configureimport flowJSON from"@fixes/contracts/flow.json"assert { type:"json" };// FIXeS Transactionsimport txHeartbeatStaking from"@fixes/contracts/transactions/staking/heartbeat-staking.cdc?raw";// FIXeS Scriptsimport scResolveName from"@fixes/contracts/scripts/utils/resolve-name.cdc?raw";import { FlowService } from"./flow.service";import FlowSigner from"./Signer";asyncfunctionheartbeat(tickerName:string):Promise<string> {constflowSigner=newFlowSigner(signerAddr, signerPrivKey, signerKeyId);// If you want to directly use FCL-compatible wallets on the frontend,// you can also use flowService here, but you need to connect the wallet // first using flowService.authenticateconsttxid=awaitflowSigner.sendTransaction( txHeartbeatStaking, (arg, t) => [arg(tickerName,t.String)] );return txid;}asyncfunctionresolveAddressName(addr:string):Promise<string> {constflowService=newFlowService(flowJSON);returnawaitflowService.executeScript( scResolveName, (arg, t) => [arg(addr,t.Address)] addr )}