UNPKG

@nomad-xyz/sdk-bridge

Version:
222 lines (220 loc) 7.18 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GoldSkyBridgeBackend = void 0; const sdk_1 = require("@nomad-xyz/sdk"); const graphql_request_1 = require("graphql-request"); const utils_1 = require("@nomad-xyz/sdk/src/messageBackend/utils"); /** * Abstract class required for operation of NomadMessage */ class BridgeMessageBackend extends sdk_1.MessageBackend { } exports.default = BridgeMessageBackend; /** * GoldSky bridge backend for NomadMessage */ class GoldSkyBridgeBackend extends sdk_1.GoldSkyBackend { constructor(env, secret, context) { super(env, secret, context); this.messageCache = new Map(); this.context = context; } /** * Checks whether an environment is supported by the backend. Throws on unsupported * @param environment environment to check */ static checkEnvironment(environment) { sdk_1.GoldSkyBackend.checkEnvironment(environment); } /** * Returns default secret for Goldsky * @returns secret as a string */ static defaultSecret() { return sdk_1.GoldSkyBackend.defaultSecret(); } /** * Creates a default GoldSky backend for an environment * @param environment environment to create the backend for * @returns backend */ static default(environment = 'development', context) { const environmentString = typeof environment === 'string' ? environment : environment.environment; GoldSkyBridgeBackend.checkEnvironment(environmentString); const secret = process.env.GOLDSKY_SECRET || GoldSkyBridgeBackend.defaultSecret(); if (!secret) throw new Error(`GOLDSKY_SECRET not found in env`); return new GoldSkyBridgeBackend(environmentString, secret, context); } /** * Stores message into internal cache */ storeMessage(m) { this.messageCache.set(m.message_hash, m); const messageHashes = this.dispatchTxToMessageHash.get(m.dispatch_tx); if (!messageHashes) { this.dispatchTxToMessageHash.set(m.dispatch_tx, [m.message_hash]); } else { if (!messageHashes.includes(m.message_hash)) messageHashes.push(m.message_hash); } } /** * Get the message representation associated with this message (if any) * by message hash * * @returns A message representation (if any) */ async getMessage(messageHash, forceFetch = false) { let m = this.messageCache.get(messageHash); if (!m || forceFetch) { m = (await this.fetchMessages({ messageHash, }, 1))?.[0]; if (m) { this.storeMessage(m); } } return m; } /** * Get the message representation associated with this message (if any) * by dispatch transaction * * @returns A message representation (if any) */ async getMessagesByTx(tx, limit, forceFetch = true) { let ms; const messageHashes = this.dispatchTxToMessageHash.get(tx); const enoughMessages = limit && messageHashes && limit <= messageHashes.length; if (!enoughMessages || forceFetch) { ms = await this.fetchMessages({ transactionHash: tx, }); if (ms && ms.length) { ms.forEach((m) => this.storeMessage(m)); } } else { // messageHashes! are there as they are already tested in `enoughHashes` above // getMessage(hash)! is also there as in order to get into `messageHashes` a message needs to get fetched if (!messageHashes) throw new Error('MessageHashes are unexpectedly not existing'); ms = await Promise.all(messageHashes.map(async (hash) => { const message = await this.getMessage(hash); if (!message) throw new Error("Couldn't get a message from existing messages."); // Message must be in messageHashes return message; })); } return ms; } /** * Gets an original sender of the message * @param messageHash * @returns sender's address */ async sender(messageHash) { let m = await this.getMessage(messageHash); if (!m?.original_sender) m = await this.getMessage(messageHash, true); return m?.original_sender; } /** * Gets a transaction related to Received event * @param messageHash * @returns transaction hash */ async receivedTx(messageHash) { let m = await this.getMessage(messageHash); if (!m?.receive_tx) m = await this.getMessage(messageHash, true); return m?.receive_tx; } /** * Fetches internal message from backend * * @returns Internal message representation (if any) */ async fetchMessages(f, limit) { const eventsTable = `${this.env}_views_bridge_events`; const query = (0, graphql_request_1.gql) ` query Query( $committedRoot: String $messageHash: String $transactionHash: String $limit: Int ) { ${eventsTable}( where: { _or: [ { dispatch_tx: { _eq: $transactionHash } } { message_hash: { _eq: $messageHash } } { old_root: { _eq: $committedRoot } } ] } limit: $limit ) { committed_root destination_and_nonce destination_domain_id destination_domain_name dispatch_block dispatch_tx dispatched_at id leaf_index message message__action__amount message__action__details_hash message__action__to message__action__type message__token__domain message__token__id message_body message_hash message_type new_root nonce old_root origin_domain_id origin_domain_name process_block process_tx processed_at recipient_address relay_block relay_chain_id relay_tx relayed_at sender_address signature update_block update_chain_id update_tx updated_at send_tx sent_at send_block original_sender receive_tx origin_and_nonce receive_block received_at } } `; const filter = { ...sdk_1.GoldSkyBackend.fillFilter(f), limit: limit || null, }; const response = await (0, graphql_request_1.request)(this.uri, query, filter, this.headers); const events = (0, utils_1.nulls2undefined)(response[eventsTable]); if (!events || events.length <= 0) return undefined; return events; } } exports.GoldSkyBridgeBackend = GoldSkyBridgeBackend; //# sourceMappingURL=backend.js.map