From de955b044a287bc65d9f7e937e5cc18998c4f531 Mon Sep 17 00:00:00 2001 From: 0xp3gasus <0xp3gasus@proton.me> Date: Tue, 23 Jul 2024 18:45:13 +0200 Subject: [PATCH] Trade apis --- .../responses/thornode/tradeAssetAccount.json | 114 ++++++++ .../thornode/tradeAssetAccounts.json | 72 +++++ .../responses/thornode/tradeAssetUnit.json | 5 + .../responses/thornode/tradeAssetUnits.json | 247 ++++++++++++++++++ .../__mocks__/thornode-api.ts | 16 ++ .../__tests__/thornode.test.ts | 29 ++ .../src/utils/thornode.ts | 87 ++++++ 7 files changed, 570 insertions(+) create mode 100644 packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccount.json create mode 100644 packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccounts.json create mode 100644 packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnit.json create mode 100644 packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnits.json diff --git a/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccount.json b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccount.json new file mode 100644 index 000000000..725e85cac --- /dev/null +++ b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccount.json @@ -0,0 +1,114 @@ +[ + { + "asset": "AVAX~AVAX", + "units": "47632915497", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949652, + "last_withdraw_height": 16949626 + }, + { + "asset": "AVAX~USDC-0XB97EF9EF8734C71904D8002F8B6BC66DD9C48A6E", + "units": "552670139895", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949518, + "last_withdraw_height": 16949396 + }, + { + "asset": "AVAX~USDT-0X9702230A8EA53601F5CD2DC00FDBC13D4DF4A8C7", + "units": "254020119655", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16947724, + "last_withdraw_height": 16947725 + }, + { + "asset": "BCH~BCH", + "units": "3335481666", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949656, + "last_withdraw_height": 16949734 + }, + { + "asset": "BSC~BNB", + "units": "16905304", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949665, + "last_withdraw_height": 16949726 + }, + { + "asset": "BSC~USDC-0X8AC76A51CC950D9822D68B83FE1AD97B32CD580D", + "units": "275727299843", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16948802, + "last_withdraw_height": 16949042 + }, + { + "asset": "BSC~USDT-0X55D398326F99059FF775485246999027B3197955", + "units": "29375159216", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949345, + "last_withdraw_height": 16949654 + }, + { + "asset": "BTC~BTC", + "units": "359979303", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949720, + "last_withdraw_height": 16949725 + }, + { + "asset": "DOGE~DOGE", + "units": "26999229468117", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949578, + "last_withdraw_height": 16949693 + }, + { + "asset": "ETH~DAI-0X6B175474E89094C44DA98B954EEDEAC495271D0F", + "units": "11034918304", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16945547, + "last_withdraw_height": 16949042 + }, + { + "asset": "ETH~ETH", + "units": "3655053689", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949714, + "last_withdraw_height": 16949730 + }, + { + "asset": "ETH~USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48", + "units": "6505859409337", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949730, + "last_withdraw_height": 16949669 + }, + { + "asset": "ETH~USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7", + "units": "5832622922140", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949726, + "last_withdraw_height": 16949713 + }, + { + "asset": "ETH~WBTC-0X2260FAC5E5542A773AA44FBCFEDF7C193BC2C599", + "units": "122081", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16946818, + "last_withdraw_height": 16947704 + }, + { + "asset": "GAIA~ATOM", + "units": "143742309997", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16948803, + "last_withdraw_height": 16949345 + }, + { + "asset": "LTC~LTC", + "units": "143174314", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949713, + "last_withdraw_height": 16949714 + } +] \ No newline at end of file diff --git a/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccounts.json b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccounts.json new file mode 100644 index 000000000..a503342f3 --- /dev/null +++ b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetAccounts.json @@ -0,0 +1,72 @@ +[ + { + "asset": "BTC~BTC", + "units": "359979303", + "owner": "thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55", + "last_add_height": 16949720, + "last_withdraw_height": 16949725 + }, + { + "asset": "BTC~BTC", + "units": "1390", + "owner": "thor1547pg8p3tm2cu23sud0vuatpz0pttucvch03ll", + "last_add_height": 16894785, + "last_withdraw_height": 0 + }, + { + "asset": "BTC~BTC", + "units": "3127498814", + "owner": "thor166n4w5039meulfa3p6ydg60ve6ueac7tlt0jws", + "last_add_height": 16949650, + "last_withdraw_height": 16949554 + }, + { + "asset": "BTC~BTC", + "units": "113801049", + "owner": "thor17hwqt302e5f2xm4h95ma8wuggqkvfzgvsnh5z9", + "last_add_height": 16949730, + "last_withdraw_height": 16949733 + }, + { + "asset": "BTC~BTC", + "units": "45000", + "owner": "thor17unftkdeuwcyqrsx32wpzqsmjjyl7ym5na5fqf", + "last_add_height": 16358552, + "last_withdraw_height": 0 + }, + { + "asset": "BTC~BTC", + "units": "225443863", + "owner": "thor19emplkuphjk2y9gkkv06m8vcstc0ufn4pevv5u", + "last_add_height": 16948468, + "last_withdraw_height": 16948049 + }, + { + "asset": "BTC~BTC", + "units": "27994", + "owner": "thor1ppjxcc0yn6kq94j99hzny38hd40frvnkq4fpg6", + "last_add_height": 16943874, + "last_withdraw_height": 0 + }, + { + "asset": "BTC~BTC", + "units": "126229", + "owner": "thor1qefmyzkgkvu2kz57yv5x5r6k9tvr65v3uany68", + "last_add_height": 16476640, + "last_withdraw_height": 0 + }, + { + "asset": "BTC~BTC", + "units": "54645", + "owner": "thor1ua9ff625w4d8jtm8ngdmfm9m2tnwyjg23sjqz0", + "last_add_height": 16603836, + "last_withdraw_height": 0 + }, + { + "asset": "BTC~BTC", + "units": "8294717414", + "owner": "thor1ukwhpglu7yh2g2rw8h7jvee2r0fv0e90nyxv6v", + "last_add_height": 16949721, + "last_withdraw_height": 16949691 + } +] \ No newline at end of file diff --git a/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnit.json b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnit.json new file mode 100644 index 000000000..d8480ccf3 --- /dev/null +++ b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnit.json @@ -0,0 +1,5 @@ +{ + "asset": "ETH~ETH", + "units": "113795699737", + "depth": "113795699737" +} \ No newline at end of file diff --git a/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnits.json b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnits.json new file mode 100644 index 000000000..ab0507a07 --- /dev/null +++ b/packages/xchain-thorchain-query/__mocks__/responses/thornode/tradeAssetUnits.json @@ -0,0 +1,247 @@ +[ + { + "asset": "AVAX~AVAX", + "units": "328935026564", + "depth": "328935026564" + }, + { + "asset": "AVAX~SOL-0XFE6B19286885A4F7F55ADAD09C3CD1F906D2478F", + "units": "0", + "depth": "0" + }, + { + "asset": "AVAX~USDC", + "units": "0", + "depth": "0" + }, + { + "asset": "AVAX~USDC-0XB97EF9EF8734C71904D8002F8B6BC66DD9C48A6E", + "units": "7102037471973", + "depth": "7102037471973" + }, + { + "asset": "AVAX~USDT-0X9702230A8EA53601F5CD2DC00FDBC13D4DF4A8C7", + "units": "2257304026310", + "depth": "2257304026310" + }, + { + "asset": "BCH~BCH", + "units": "26784125734", + "depth": "26784125734" + }, + { + "asset": "BNB~BNB", + "units": "0", + "depth": "0" + }, + { + "asset": "BSC~BNB", + "units": "90627137262", + "depth": "90627137262" + }, + { + "asset": "BSC~USDC-0X8AC76A51CC950D9822D68B83FE1AD97B32CD580D", + "units": "2012036814702", + "depth": "2012036814702" + }, + { + "asset": "BSC~USDT-0X55D398326F99059FF775485246999027B3197955", + "units": "1600328670160", + "depth": "1600328670160" + }, + { + "asset": "BTC~BTC", + "units": "12294709954", + "depth": "12294709954" + }, + { + "asset": "DOGE~DOGE", + "units": "87463086868160", + "depth": "87463086868160" + }, + { + "asset": "ETH~AAAA", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~AAVE-0X7FC66500C84A76AD7E9C93437BFC5AC33E2DDAE9", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~BUSD-0X4FABB145D64652A948D72533023F6E7A623C7C53", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~CELR-0X4F9254C83EB525F9FCF346490BBB3ED28A81C667", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~DAI-0X6B175474E89094C44DA98B954EEDEAC495271D0F", + "units": "3586322903762", + "depth": "3586322903762" + }, + { + "asset": "ETH~DPI-0X1494CA1F11D487C2BBE4543E90080AEBA4BA3C2B", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~ETH", + "units": "109433998092", + "depth": "109433998092" + }, + { + "asset": "ETH~FLIP-0X826180541412D574CF1336D22C0C0A287822678A", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~FOX-0XC770EEFAD204B5180DF6A14EE197D99D808EE52D", + "units": "33564055436479", + "depth": "33564055436479" + }, + { + "asset": "ETH~GUSD-0X056FD409E1D7A124BD7017459DFEA2F387B6D5CD", + "units": "443853931", + "depth": "443853931" + }, + { + "asset": "ETH~HOT-0X6C6EE5E31D828DE241282B9606C8E98EA48526E2", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~KYL-0X67B6D479C7BB412C54E03DCA8E1BC6740CE6B99C", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~LENDS-0X2C06BA9E7F0DACCBC1F6A33EA67E85BB68FBEE3A", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~LINK-0X514910771AF9CA656AF840DFF83E8264ECF986CA", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~LUSD-0X5F98805A4E8BE255A32880FDEC7F6728C6568BA0", + "units": "80607031790", + "depth": "80607031790" + }, + { + "asset": "ETH~MKR-0X9F8F72AA9304C8B593D555F12EF6589CC3A579A2", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~QWERTY", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~RAZE-0X5EAA69B29F99C84FE5DE8200340B4E9B4AB38EAC", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~SNX-0XC011A73EE8576FB46F5E1C5751CA3B9FE0AF2A6F", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~TGT-0X108A850856DB3F85D0269A2693D896B394C80325", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~THOR-0XA5F2211B9B8170F694421F2046281775E8468044", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~TVK-0XD084B83C305DAFD76AE3E1B4E1F1FE2ECCCB3988", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~UOS-0XD13C7342E1EF687C5AD21B27C2B65D772CAB5C8C", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48", + "units": "85041014313426", + "depth": "85041014313426" + }, + { + "asset": "ETH~USDP-0X8E870D67F660D95D5BE530380D0EC0BD388289E1", + "units": "754421879935", + "depth": "754421879935" + }, + { + "asset": "ETH~USDT-0XDAC17F958D2EE523A2206206994597C13D831EC7", + "units": "63015056172063", + "depth": "63015056172063" + }, + { + "asset": "ETH~VIU-0X519475B31653E46D20CD09F9FDCF3B12BDACB4F5", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~VTHOR-0X815C23ECA83261B6EC689B60CC4A58B54BC24D8D", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~WBTC-0X2260FAC5E5542A773AA44FBCFEDF7C193BC2C599", + "units": "179150355", + "depth": "179150355" + }, + { + "asset": "ETH~WSTETH-0X7F39C581F595B53C5CB19BD0B3F8DA6C935E2CA0", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~XDEFI-0X72B886D09C117654AB7DA13A14D603001DE0B777", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~XRUNE-0X69FA0FEE221AD11012BAB0FDB45D444D3D2CE71C", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~XRUNEE", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~YCURVE-0XDF5E0E81DFF6FAF3A7E52BA697820C5E32D806A8", + "units": "0", + "depth": "0" + }, + { + "asset": "ETH~YFI-0X0BC529C00C6401AEF6D220BE8C6EA1667F6AD93E", + "units": "0", + "depth": "0" + }, + { + "asset": "GAIA~ATOM", + "units": "365587226514", + "depth": "365587226514" + }, + { + "asset": "LTC~LTC", + "units": "96577481689", + "depth": "96577481689" + } +] \ No newline at end of file diff --git a/packages/xchain-thorchain-query/__mocks__/thornode-api.ts b/packages/xchain-thorchain-query/__mocks__/thornode-api.ts index cdf723a1d..5216fc33f 100644 --- a/packages/xchain-thorchain-query/__mocks__/thornode-api.ts +++ b/packages/xchain-thorchain-query/__mocks__/thornode-api.ts @@ -80,5 +80,21 @@ export default { const resp = require('./responses/thornode/mimir.json') return [200, resp] }) + mock.onGet(/\/thorchain\/trade\/units/).reply(function () { + const resp = require('./responses/thornode/tradeAssetUnits.json') + return [200, resp] + }) + mock.onGet(/\/thorchain\/trade\/unit/).reply(function () { + const resp = require('./responses/thornode/tradeAssetUnit.json') + return [200, resp] + }) + mock.onGet(/\/thorchain\/trade\/accounts/).reply(function () { + const resp = require('./responses/thornode/tradeAssetAccounts.json') + return [200, resp] + }) + mock.onGet(/\/thorchain\/trade\/account/).reply(function () { + const resp = require('./responses/thornode/tradeAssetAccount.json') + return [200, resp] + }) }, } diff --git a/packages/xchain-thorchain-query/__tests__/thornode.test.ts b/packages/xchain-thorchain-query/__tests__/thornode.test.ts index 8390893fd..adf39947a 100644 --- a/packages/xchain-thorchain-query/__tests__/thornode.test.ts +++ b/packages/xchain-thorchain-query/__tests__/thornode.test.ts @@ -36,8 +36,37 @@ describe(`Thornode transaction status tests`, () => { expect(val).toBeTruthy() expect(val).toEqual(FullImpLossProtectionBlocks) }) + it(`Should fetch schedule outbound array`, async () => { const scheduledOutbound = await thornode.getscheduledQueue() expect(scheduledOutbound).toBeTruthy() }) + + it('Should get trade asset unit', async () => { + const asset = 'ETH~ETH' + const tradeAssetUnits = await thornode.getTradeAssetUnits(asset) + expect(tradeAssetUnits.asset).toBe(asset) + expect(tradeAssetUnits.units).toBe('113795699737') + expect(tradeAssetUnits.depth).toBe('113795699737') + }) + + it('Should get trade assets units', async () => { + const tradeAssetUnits = await thornode.getTradeAssetsUnits() + expect(tradeAssetUnits.every((traseAssetUnit) => traseAssetUnit.asset.includes('~'))) + expect(tradeAssetUnits.length).toBe(49) + }) + + it('Should get trade asset account', async () => { + const address = 'thor14mh37ua4vkyur0l5ra297a4la6tmf95mt96a55' + const tradeAssetAccounts = await thornode.getTradeAssetAccount(address) + console.log(tradeAssetAccounts.every((tradeAssetAccount) => tradeAssetAccount.owner === address)) + console.log(tradeAssetAccounts.every((tradeAssetAccount) => tradeAssetAccount.asset.includes('~'))) + }) + + it('Should get trade asset list of accounts', async () => { + const asset = 'BTC~BTC' + const tradeAssetAccounts = await thornode.getTradeAssetAccounts(asset) + expect(tradeAssetAccounts.every((tradeAssetAccount) => tradeAssetAccount.asset === 'BTC~BTC')) + expect(tradeAssetAccounts.length).toBe(10) + }) }) diff --git a/packages/xchain-thorchain-query/src/utils/thornode.ts b/packages/xchain-thorchain-query/src/utils/thornode.ts index 723d8e741..7219f63cd 100644 --- a/packages/xchain-thorchain-query/src/utils/thornode.ts +++ b/packages/xchain-thorchain-query/src/utils/thornode.ts @@ -23,11 +23,19 @@ import { SaversResponse, Thorname, ThornamesApi, + TradeAccountApi, + TradeAccountsApi, + TradeAccountsResponse, + TradeUnitApi, + TradeUnitResponse, + TradeUnitsApi, + TradeUnitsResponse, TransactionsApi, TxDetailsResponse, TxOutItem, TxResponse, } from '@xchainjs/xchain-thornode' +import { Address } from '@xchainjs/xchain-util' import axios from 'axios' import axiosRetry from 'axios-retry' @@ -64,6 +72,10 @@ export class Thornode { private saversApi: SaversApi[] private quoteApi: QuoteApi[] private mimirApi: MimirApi[] + private tradeUnitApi: TradeUnitApi[] + private tradeUnitsApi: TradeUnitsApi[] + private tradeAccountApi: TradeAccountApi[] + private tradeAccountsApi: TradeAccountsApi[] private thornamesApi: ThornamesApi[] constructor(network: Network = Network.Mainnet, config?: ThornodeConfig) { @@ -85,6 +97,18 @@ export class Thornode { this.thornamesApi = this.config.thornodeBaseUrls.map( (url) => new ThornamesApi(new Configuration({ basePath: url })), ) + this.tradeUnitApi = this.config.thornodeBaseUrls.map( + (url) => new TradeUnitApi(new Configuration({ basePath: url })), + ) + this.tradeUnitsApi = this.config.thornodeBaseUrls.map( + (url) => new TradeUnitsApi(new Configuration({ basePath: url })), + ) + this.tradeAccountApi = this.config.thornodeBaseUrls.map( + (url) => new TradeAccountApi(new Configuration({ basePath: url })), + ) + this.tradeAccountsApi = this.config.thornodeBaseUrls.map( + (url) => new TradeAccountsApi(new Configuration({ basePath: url })), + ) } /** @@ -509,4 +533,67 @@ export class Thornode { } throw new Error(`THORNode is not responding`) } + + /** + * Returns the total units and depth of a trade asset + * @param {string} asset Trade asset + * @param {number} height Optional - Block height + * @returns Returns the total units and depth of a trade asset + */ + public async getTradeAssetUnits(asset: string, height?: number): Promise { + for (const api of this.tradeUnitApi) { + try { + const resp = (await api.tradeUnit(asset, height)).data + return resp + } catch (e) {} + } + throw new Error(`THORNode is not responding. Can not get asset trade units`) + } + + /** + * Returns the total units and depth for each trade asset + * @param {number} height Block height + * @returns Returns the total units and depth for each trade asset + */ + public async getTradeAssetsUnits(height?: number): Promise { + for (const api of this.tradeUnitsApi) { + try { + const resp = (await api.tradeUnits(height)).data + return resp + } catch (e) {} + } + throw new Error(`THORNode is not responding. Can not get trade units`) + } + + /** + * Returns the units and depth of a trade account address + * @param {Address} address Thorchain address + * @param {number} height Optional - Block height + * @returns Returns the units and depth of a trade account + */ + public async getTradeAssetAccount(address: Address, height?: number): Promise { + for (const api of this.tradeAccountApi) { + try { + const resp = (await api.tradeAccount(address, height)).data + return resp as unknown as TradeAccountsResponse + } catch (e) {} + } + throw new Error(`THORNode is not responding. Can not get trade asset account`) + } + + /** + * Returns all trade accounts for an asset + * @param {Address} address Thorchain address + * @param {number} height Optional - Block height + * @returns Returns all trade accounts for an asset + */ + public async getTradeAssetAccounts(asset: string, height?: number): Promise { + for (const api of this.tradeAccountsApi) { + try { + const resp = (await api.tradeAccounts(asset, height)).data + return resp + } catch (e) {} + } + throw new Error(`THORNode is not responding. Can not get trade asset accounts`) + } }