UNPKG

@dojima-wallet/connection

Version:

Initialise and connection for layer 1&2 blockchain

319 lines (296 loc) 9.94 kB
import Arweave from "arweave"; import Transaction from "arweave/node/lib/transaction"; import _ from "lodash"; import { ArTxDataResult, ArTxsResult, InnerDataResult, OuterDataResult, } from "./types"; import { GQLResultInterface, GQLTransactionsResultInterface, convertTimestampToDateFormat, convertTimestampToTimeFormat, AR_DECIMAL, } from "./utils"; export interface ReqVariables { ownersFilter: Array<string>; first: number; after?: string; } export default class ArweaveTxClient { ownerHasNextPage: boolean | undefined; recipientHasNextPage: boolean | undefined; ownerCursor: string; recipientCursor: string; constructor() { this.ownerHasNextPage = undefined; this.recipientHasNextPage = undefined; this.ownerCursor = ""; this.recipientCursor = ""; } async getTxData(arweave: Arweave, hash: string): Promise<ArTxDataResult> { const tx: Transaction = await arweave.transactions.get(hash); if (!tx) throw Error(`Failed to get transaction data (tx-hash: ${hash})`); const fromAddress = await arweave.wallets.ownerToAddress(tx.owner); const resultData: ArTxDataResult = { transaction_hash: tx.id, from: fromAddress, to: tx.target, value: Number(tx.quantity) / Math.pow(10, AR_DECIMAL), gas_price: (Number(tx.reward) / Math.pow(10, AR_DECIMAL)).toFixed( AR_DECIMAL ), signature: tx.signature, }; return resultData; } async getTxsHistory(arweave: Arweave, owner: string, limit?: number) { let ownerVariables: ReqVariables; if (this.ownerCursor !== "") { ownerVariables = { ownersFilter: [owner], first: limit ? limit : 100, after: this.ownerCursor, }; } else { ownerVariables = { ownersFilter: [owner], first: limit ? limit : 100, }; } let recipientVariables: ReqVariables; if (this.recipientCursor !== "") { recipientVariables = { ownersFilter: [owner], first: limit ? limit : 100, after: this.recipientCursor, }; } else { recipientVariables = { ownersFilter: [owner], first: limit ? limit : 100, }; } let txs: GQLTransactionsResultInterface; const outerTxsData: OuterDataResult[] = []; const innerTxsData: InnerDataResult[] = []; const txsDataFinal: ArTxsResult = { outer: outerTxsData, inner: innerTxsData, }; if (this.ownerHasNextPage === true || this.ownerHasNextPage === undefined) { txs = await this.getOwnersTxsQueryResult(arweave, ownerVariables); this.ownerHasNextPage = txs.pageInfo.hasNextPage; if (txs.edges.length > 0) { this.ownerCursor = txs.edges[txs.edges.length - 1].cursor; txs.edges.map((res) => { const outerResult: OuterDataResult = { timestamp: res.node.block ? `${res.node.block.timestamp}` : "-", transaction_hash: res.node.id, block: res.node.block ? `${res.node.block.height}` : "-", from: res.node.owner.address, to: res.node.recipient, value: res.node.quantity.ar, gas_price: res.node.fee.ar, date: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToDateFormat(res.node.block.timestamp) : "-", time: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToTimeFormat(res.node.block.timestamp) : "-", }; outerTxsData.push(outerResult); const innerResult: InnerDataResult = { timestamp: res.node.block ? `${res.node.block.timestamp}` : "-", transaction_hash: res.node.id, block: res.node.block ? `${res.node.block.height}` : "-", from: res.node.owner.address, to: res.node.recipient, value: res.node.quantity.ar, gas_price: res.node.fee.ar, date: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToDateFormat(res.node.block.timestamp) : "-", time: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToTimeFormat(res.node.block.timestamp) : "-", signature: res.node.signature, block_hash: res.node.block ? res.node.block.id : "-", }; innerTxsData.push(innerResult); }); } } if ( this.recipientHasNextPage === true || this.recipientHasNextPage === undefined ) { txs = await this.getRecipientsTxsQueryResult(arweave, recipientVariables); this.recipientHasNextPage = txs.pageInfo.hasNextPage; if (txs.edges.length > 0) { this.recipientCursor = txs.edges[txs.edges.length - 1].cursor; txs.edges.map((res) => { const outerResult: OuterDataResult = { timestamp: res.node.block ? `${res.node.block.timestamp}` : "-", transaction_hash: res.node.id, block: res.node.block ? `${res.node.block.height}` : "-", from: res.node.owner.address, to: res.node.recipient, value: res.node.quantity.ar, gas_price: res.node.fee.ar, date: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToDateFormat(res.node.block.timestamp) : "-", time: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToTimeFormat(res.node.block.timestamp) : "-", }; outerTxsData.push(outerResult); const innerResult: InnerDataResult = { timestamp: res.node.block ? `${res.node.block.timestamp}` : "-", transaction_hash: res.node.id, block: res.node.block ? `${res.node.block.height}` : "-", from: res.node.owner.address, to: res.node.recipient, value: res.node.quantity.ar, gas_price: res.node.fee.ar, date: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToDateFormat(res.node.block.timestamp) : "-", time: res.node.block && res.node.block.timestamp !== undefined ? convertTimestampToTimeFormat(res.node.block.timestamp) : "-", signature: res.node.signature, block_hash: res.node.block ? res.node.block.id : "-", }; innerTxsData.push(innerResult); }); } } if (outerTxsData.length !== 0) { const outerLodash: OuterDataResult[] = _.orderBy( outerTxsData, "timestamp", "desc" ); txsDataFinal.outer = outerLodash; } if (innerTxsData.length !== 0) { const innerLodash: InnerDataResult[] = _.orderBy( innerTxsData, "timestamp", "desc" ); txsDataFinal.inner = innerLodash; } return txsDataFinal; } async getOwnersTxsQueryResult( arweave: Arweave, variables: ReqVariables ): Promise<GQLTransactionsResultInterface> { const query = `query Transactions($ownersFilter: [String!], $first: Int!, $after: String) { transactions(owners: $ownersFilter, first: $first, sort: HEIGHT_ASC, after: $after) { pageInfo { hasNextPage } edges { node { id owner { address } recipient block { height id timestamp } fee { ar winston } quantity { ar winston } parent { id } signature } cursor } } }`; const response = await arweave.api.post("graphql", { query, variables, }); if (response.status !== 200) { throw new Error( `Unable to retrieve transactions. Arweave gateway responded with status ${response.status}.` ); } const data: GQLResultInterface = response.data; const txs = data.data.transactions; return txs; } async getRecipientsTxsQueryResult( arweave: Arweave, variables: ReqVariables ): Promise<GQLTransactionsResultInterface> { const query = `query Transactions($ownersFilter: [String!], $first: Int!, $after: String) { transactions(recipients: $ownersFilter, first: $first, sort: HEIGHT_ASC, after: $after) { pageInfo { hasNextPage } edges { node { id owner { address } recipient tags { name value } block { height id timestamp } fee { ar winston } quantity { ar winston } parent { id } signature } cursor } } }`; const response = await arweave.api.post("graphql", { query, variables, }); if (response.status !== 200) { throw new Error( `Unable to retrieve transactions. Arweave gateway responded with status ${response.status}.` ); } const data: GQLResultInterface = response.data; const txs: GQLTransactionsResultInterface = data.data.transactions; return txs; } }