From 40a39f7cd250a43aefdbf633444aa46c2f290964 Mon Sep 17 00:00:00 2001 From: Aleksandr Kraiz Date: Sat, 4 Jun 2022 18:17:16 +0400 Subject: [PATCH] Fix issue #12 --- README.md | 58 ++++--------- package.json | 2 +- src/services/OrionAggregator/ws/index.ts | 87 +++++++++++++------ .../PriceFeed/ws/PriceFeedSubscription.ts | 2 +- 4 files changed, 80 insertions(+), 69 deletions(-) diff --git a/README.md b/README.md index e833a47..3546d35 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,6 @@ Orion’s SDK is free to use and does not require an API key or registration. Re - [Remove all liquidity](#remove-all-liquidity) - [Low level methods](#low-level-methods) - [Get historical price](#get-historical-price) - - [Using contracts](#using-contracts) - [Get tradable pairs](#get-tradable-pairs) - [Get swap info](#get-swap-info) - [Place order in Orion Aggregator](#place-order-in-orion-aggregator) @@ -35,6 +34,7 @@ Orion’s SDK is free to use and does not require an API key or registration. Re - [Orion Aggregator WS Stream Unsubscribing](#orion-aggregator-ws-stream-unsubscribing) - [Price Feed Websocket Stream](#price-feed-websocket-stream) - [About our fetching system](#about-our-fetching-system) +- [Using contracts](#using-contracts) ## Install @@ -192,31 +192,6 @@ const candles = await simpleFetch(orionUnit.priceFeed.getCandles)( ); ``` -### Using contracts - -```ts -import { - Exchange__factory, - ERC20__factory, - OrionGovernance__factory, - OrionVoting__factory, -} from "@orionprotocol/contracts"; - -const exchangeContract = Exchange__factory.connect( - exchangeContractAddress, - orionUnit.provider -); -const erc20Contract = ERC20__factory.connect(tokenAddress, orionUnit.provider); -const governanceContract = OrionGovernance__factory.connect( - governanceAddress, - orionUnit.provider -); -const orionVoting = OrionVoting__factory.connect( - votingContractAddress, - orionUnit.provider -); -``` - ### Get tradable pairs ```ts @@ -240,7 +215,7 @@ const swapInfo = await simpleFetch(orionUnit.orionAggregator.getSwapInfo)( ); ``` -Swap info eesponse example: +Swap info response example: ```json { @@ -332,14 +307,11 @@ BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE = 'btasabus', // Ne ### Swap Info ```ts -import { v4 as uuidv4 } from "uuid"; -const swapRequestId = uuidv4(); -orionUnit.orionAggregator.ws.subscribe( +const swapRequestId = orionUnit.orionAggregator.ws.subscribe( "ss", // SWAP_SUBSCRIBE { payload: { - d: swapRequestId, // generated by client i: assetIn, // asset in o: assetOut, // asset out e: true, // true when type of swap is exactSpend, can be omitted (true by default) @@ -359,6 +331,9 @@ orionUnit.orionAggregator.ws.subscribe( }, } ); + +orionAggregator.ws.unsubscribe(swapRequestId); + ``` ### Balances and order history stream @@ -393,6 +368,10 @@ orionUnit.orionAggregator.ws.subscribe( }, } ); + +orionUnit.orionAggregator.ws.unsubscribe( + "0x0000000000000000000000000000000000000000" +); ``` ### Orderbook stream @@ -405,22 +384,13 @@ orionUnit.orionAggregator.ws.subscribe("aobus", { console.log(`${pairName} orderbook bids`, bids); }, }); + +orionUnit.orionAggregator.ws.unsubscribe("ORN-USDT"); ``` ### Orion Aggregator WS Stream Unsubscribing ```ts -// Swap request unsubscribe -orionAggregator.ws.unsubscribe(swapRequestId); // Pass here id that you generate when subscribe - -// Address update (balances / order history) unsubscribe -orionUnit.orionAggregator.ws.unsubscribe( - "0x0000000000000000000000000000000000000000" -); - -// Pair orderbook unsubscribe -orionUnit.orionAggregator.ws.unsubscribe("ORN-USDT"); - // Asset pairs config updates unsubscribe orionUnit.orionAggregator.ws.unsubscribe("apcu"); @@ -511,3 +481,7 @@ const { candles, timeStart, timeEnd } = await simpleFetch( // Here we can handle response data ``` + +## Using contracts + +Use package [@prionprotocol/contracts](https://github.com/orionprotocol/contracts) diff --git a/package.json b/package.json index 57f2a8f..17f16f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.11.5", + "version": "0.12.0", "description": "Orion Protocol SDK", "main": "./lib/esm/index.js", "module": "./lib/esm/index.js", diff --git a/src/services/OrionAggregator/ws/index.ts b/src/services/OrionAggregator/ws/index.ts index 3abb05b..913dfe7 100644 --- a/src/services/OrionAggregator/ws/index.ts +++ b/src/services/OrionAggregator/ws/index.ts @@ -65,7 +65,7 @@ const UNSUBSCRIBE = 'u'; // https://github.com/orionprotocol/orion-aggregator/tree/feature/OP-1752-symmetric-swap#swap-info-subscribe type SwapSubscriptionRequest = { - d: string, // swap request UUID, set by client side + // d: string, // swap request UUID, set by client side i: string, // asset in o: string, // asset out a: number // amount IN/OUT @@ -133,12 +133,17 @@ type Subscription = { [SubscriptionType.SWAP_SUBSCRIBE]: SwapInfoSubscription } +const exclusiveSubscriptions = [ + SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE, + SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE, +] as const; + type WsMessage = string | ArrayBufferLike | Blob | ArrayBufferView; class OrionAggregatorWS { private ws: WebSocket | undefined; private subscriptions: Partial<{ - [K in keyof Subscription]: Subscription[K] + [K in keyof Subscription]: Partial> }> = {}; public onInit?: () => void; @@ -176,22 +181,40 @@ class OrionAggregatorWS { subscribe( type: T, subscription: Subscription[T], - strict = false, ) { if (!this.ws) this.init(); - const subscriptionExists = type in this.subscriptions; - if (strict && subscriptionExists) throw new Error(`Subscription '${type}' already exists. Please unsubscribe first.`); + const isExclusive = exclusiveSubscriptions.some((t) => t === type); + const subs = this.subscriptions[type]; + if (isExclusive && subs && Object.keys(subs).length > 0) { + throw new Error(`Subscription '${type}' already exists. Please unsubscribe first.`); + } const id = uuidv4(); - this.send({ - T: type, - id, - ...('payload' in subscription) && { - S: subscription.payload, - }, - }); + const subRequest: Partial> = {}; + subRequest.T = type; + subRequest.id = id; - this.subscriptions[type] = subscription; + // TODO Refactor this + if ('payload' in subscription) { + if (typeof subscription.payload === 'string') { + subRequest.S = subscription.payload; + } else { + subRequest.S = { + d: id, + ...subscription.payload, + }; + } + } + + this.send(subRequest); + + const subKey = isExclusive ? 'default' : id; + this.subscriptions[type] = { + ...this.subscriptions[type], + [subKey]: subscription, + }; + + return id; } unsubscribe(subscription: keyof typeof UnsubscriptionType | string) { @@ -201,16 +224,30 @@ class OrionAggregatorWS { }); if (subscription.includes('0x')) { // is wallet address (ADDRESS_UPDATE) - delete this.subscriptions[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]; + const auSubscriptions = this.subscriptions[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]; + if (auSubscriptions) { + const targetAuSub = Object.entries(auSubscriptions).find(([, value]) => value?.payload === subscription); + if (targetAuSub) { + const [key] = targetAuSub; + delete this.subscriptions[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]?.[key]; + } + } } else if (uuidValidate(subscription)) { // is swap info subscription (contains hyphen) - delete this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]; + delete this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[subscription]; // !!! swap info subscription is uuid that contains hyphen } else if (subscription.includes('-') && subscription.split('-').length === 2) { // is pair name(AGGREGATED_ORDER_BOOK_UPDATE) - delete this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]; + const aobSubscriptions = this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]; + if (aobSubscriptions) { + const targetAobSub = Object.entries(aobSubscriptions).find(([, value]) => value?.payload === subscription); + if (targetAobSub) { + const [key] = targetAobSub; + delete this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]?.[key]; + } + } } else if (subscription === UnsubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_UNSUBSCRIBE) { - delete this.subscriptions[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]; + delete this.subscriptions[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]?.default; } else if (subscription === UnsubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_UNSUBSCRIBE) { - delete this.subscriptions[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]; + delete this.subscriptions[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]?.default; } } @@ -292,7 +329,7 @@ class OrionAggregatorWS { switch (json.k) { // kind case 'exactSpend': - this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.callback({ + this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({ kind: json.k, marketAmountOut: json.mo, availableAmountIn: json.aa, @@ -301,7 +338,7 @@ class OrionAggregatorWS { break; case 'exactReceive': - this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.callback({ + this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[json.S]?.callback({ kind: json.k, ...baseSwapInfo, marketAmountIn: json.mi, @@ -340,7 +377,7 @@ class OrionAggregatorWS { }, []); this.subscriptions[ SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE - ]?.callback( + ]?.[json.id]?.callback( mapOrderbookItems(ob.a), mapOrderbookItems(ob.b), S, @@ -358,7 +395,7 @@ class OrionAggregatorWS { }), {}); this.subscriptions[ SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE - ]?.callback({ + ]?.default?.callback({ kind: json.k === 'i' ? 'initial' : 'update', data: priceUpdates, }); @@ -392,7 +429,7 @@ class OrionAggregatorWS { this.subscriptions[ SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE - ]?.callback({ + ]?.[json.id]?.callback({ kind: 'initial', orders: fullOrders, balances, @@ -410,7 +447,7 @@ class OrionAggregatorWS { this.subscriptions[ SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE - ]?.callback({ + ]?.[json.id]?.callback({ kind: 'update', order: orderUpdate, balances, @@ -430,7 +467,7 @@ class OrionAggregatorWS { this.subscriptions[ SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE - ]?.callback(brokerBalances); + ]?.default?.callback(brokerBalances); } break; default: diff --git a/src/services/PriceFeed/ws/PriceFeedSubscription.ts b/src/services/PriceFeed/ws/PriceFeedSubscription.ts index c7371fe..39d8516 100644 --- a/src/services/PriceFeed/ws/PriceFeedSubscription.ts +++ b/src/services/PriceFeed/ws/PriceFeedSubscription.ts @@ -100,7 +100,7 @@ export default class PriceFeedSubscription error.message).join(', '); + const errorsMessage = parseResult.error.errors.map((error) => `[${error.path.join('.')}] ${error.message}`).join(', '); throw new Error(`Can't recognize PriceFeed "${type}" subscription message "${e.data.toString()}": ${errorsMessage}`); } this.callback(parseResult.data);