diff --git a/package.json b/package.json index cc0f935..aa07585 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.17.16", + "version": "0.17.17", "description": "Orion Protocol SDK", "main": "./lib/esm/index.js", "module": "./lib/esm/index.js", diff --git a/src/Orion/getBridgeHistory.ts b/src/Orion/getBridgeHistory.ts new file mode 100644 index 0000000..ac651ab --- /dev/null +++ b/src/Orion/getBridgeHistory.ts @@ -0,0 +1,175 @@ +import { ethers } from 'ethers'; +import type OrionUnit from '../OrionUnit'; +import simpleFetch from '../simpleFetch'; +import type { SupportedChainId } from '../types'; +import { isValidChainId } from '../utils'; + +const getBridgeHistory = async (units: OrionUnit[], address: string, limit = 1000) => { + if (!ethers.utils.isAddress(address)) throw new Error(`Invalid address: ${address}`); + const data = await Promise.all(units.map(async ({ orionBlockchain, orionAggregator, chainId }) => { + const sourceNetworkHistory = await simpleFetch(orionBlockchain.getSourceAtomicSwapHistory)({ + limit, + sender: address, + }); + const targetNetworkHistory = await simpleFetch(orionBlockchain.getTargetAtomicSwapHistory)({ + limit, + receiver: address, + }); + const orionAggregatorHistoryAtomicSwaps = await simpleFetch(orionAggregator.getHistoryAtomicSwaps)( + address, + limit + ); + + type SourceNetworkHistoryItem = Omit< + typeof sourceNetworkHistory.data[number], + 'secretHash' + > & { + sourceChainId: SupportedChainId + }; + const sourceNetworkHistoryObj = sourceNetworkHistory.data.reduce< + Partial> + >((acc, cur) => { + const { secretHash } = cur; + const lowercaseSecretHash = secretHash.toLowerCase(); + + acc[lowercaseSecretHash] = { + ...cur, + sourceChainId: chainId, + } + return acc; + }, {}); + + type TargetNetworkHistoryItem = Omit< + typeof targetNetworkHistory.data[number], + 'secretHash' + > & { + targetChainId: SupportedChainId + }; + + const targetNetworkHistoryObj = targetNetworkHistory.data.reduce< + Partial> + >((acc, cur) => { + const { secretHash } = cur; + const lowercaseSecretHash = secretHash.toLowerCase(); + + acc[lowercaseSecretHash] = { + ...cur, + targetChainId: chainId, + } + return acc; + }, {}); + + type OrionAggregatorHistoryAtomicSwapsItem = typeof orionAggregatorHistoryAtomicSwaps[number] & { + chainId: SupportedChainId + } + + const orionAggregatorHistoryAtomicSwapsObj = orionAggregatorHistoryAtomicSwaps.reduce< + Partial> + >((acc, cur) => { + const { secretHash } = cur.lockOrder; + const lowercaseSecretHash = secretHash.toLowerCase(); + acc[lowercaseSecretHash] = { + ...cur, + chainId, + } + return acc; + }, {}); + + return { + sourceNetworkHistory: sourceNetworkHistoryObj, + targetNetworkHistory: targetNetworkHistoryObj, + network: chainId, + orionAggregatorHistoryAtomicSwaps: orionAggregatorHistoryAtomicSwapsObj + }; + })); + + type SourceItems = typeof data[number]['sourceNetworkHistory']; + + const unitedSourceItems = data.reduce((acc, cur) => { + const { sourceNetworkHistory } = cur; + return { + ...acc, + ...sourceNetworkHistory, + } + }, {}); + + type TargetItems = typeof data[number]['targetNetworkHistory']; + + const unitedTargetItems = data.reduce((acc, cur) => { + const { targetNetworkHistory } = cur; + return { + ...acc, + ...targetNetworkHistory, + } + }, {}); + + type AggItems = typeof data[number]['orionAggregatorHistoryAtomicSwaps']; + + const unitedAggregatorHistory = data.reduce((acc, cur) => { + const { orionAggregatorHistoryAtomicSwaps } = cur; + return { + ...acc, + ...orionAggregatorHistoryAtomicSwaps, + } + }, {}); + + // Aggregate data + const aggregatedData = Object.entries(unitedSourceItems).map(([secretHash, item]) => { + if (item === undefined) throw new Error(`Item is undefined for secretHash: ${secretHash}`); + + const targetItem = unitedTargetItems[secretHash]; + // if (targetItem === undefined) { + // console.error(`Target item is undefined for secretHash: ${secretHash}`); + // } + + const aggItem = unitedAggregatorHistory[secretHash]; + // if (aggItem === undefined) { + // console.error(`Aggregator item is undefined for secretHash: ${secretHash}`); + // } + + const targetChainIdFromSource = item.targetChainId.toString(); + if (!isValidChainId(targetChainIdFromSource)) { + throw new Error(`Invalid targetChainId: ${targetChainIdFromSource}`); + } + return { + sourceChainId: item.sourceChainId, + targetChainId: targetItem?.targetChainId ?? targetChainIdFromSource, + // Shared data + used: item.used, + claimed: item.claimed, + isAggApplied: item.isAggApplied, + asset: item.asset, + sender: item.sender, + secretHash, + receiver: item.receiver ?? targetItem?.receiver, + secret: item.secret ?? targetItem?.secret, + + // Combined data + timestamp: { + ...item.timestamp, + ...targetItem?.timestamp, + }, + expiration: { + ...item.expiration, + ...targetItem?.expiration, + }, + transactions: { + ...item.transactions, + ...targetItem?.transactions, + }, + amountToReceive: item.amountToReceive, + amountToSpend: item.amountToSpend, + status: { + source: item.state, + target: targetItem?.state, + aggregator: aggItem?.status, + }, + lockOrder: aggItem?.lockOrder, + redeemOrder: aggItem?.redeemOrder, + } + }); + + return aggregatedData; +} + +export default getBridgeHistory; diff --git a/src/Orion/index.ts b/src/Orion/index.ts index dbc7d51..be6704b 100644 --- a/src/Orion/index.ts +++ b/src/Orion/index.ts @@ -6,6 +6,7 @@ import { ReferralSystem } from '../services/ReferralSystem'; import simpleFetch from '../simpleFetch'; import type { SupportedChainId, DeepPartial, VerboseOrionUnitConfig, KnownEnv } from '../types'; import { isValidChainId } from '../utils'; +import getBridgeHistory from './getBridgeHistory'; type EnvConfig = { analyticsAPI: string @@ -209,4 +210,8 @@ export default class Orion { return result; } + + bridge = { + getHistory: (address: string, limit = 1000) => getBridgeHistory(this.unitsArray, address, limit), + } } diff --git a/src/services/OrionBlockchain/index.ts b/src/services/OrionBlockchain/index.ts index eee1b11..e8eec6c 100644 --- a/src/services/OrionBlockchain/index.ts +++ b/src/services/OrionBlockchain/index.ts @@ -374,7 +374,7 @@ class OrionBlockchain { url.searchParams.append(key, value.toString()); }); - if (query.type !== undefined) url.searchParams.append('type', 'source'); + if (query.type === undefined) url.searchParams.append('type', 'source'); return fetchWithValidation(url.toString(), sourceAtomicHistorySchema); }; @@ -388,7 +388,7 @@ class OrionBlockchain { url.searchParams.append(key, value.toString()); }); - if (query.type !== undefined) url.searchParams.append('type', 'target'); + if (query.type === undefined) url.searchParams.append('type', 'target'); return fetchWithValidation(url.toString(), targetAtomicHistorySchema); };