Orion, Orion Unit, Configuration (#40)

* Refactoring

* Better docs

* Bump

* ESLint standard

* Fix

* Bumo

* VerboseOrionUnitConfig to types

* Docs improvements

* Docs improvements. Orion default env
This commit is contained in:
Aleksandr Kraiz
2023-02-08 14:51:58 +04:00
committed by GitHub
parent bf33fbe4f0
commit b2f3cdf5fb
31 changed files with 4386 additions and 2816 deletions

View File

@@ -9,22 +9,36 @@ import errorSchema from './schemas/errorSchema';
import placeAtomicSwapSchema from './schemas/placeAtomicSwapSchema';
import { OrionAggregatorWS } from './ws';
import { atomicSwapHistorySchema } from './schemas/atomicSwapHistorySchema';
import {Exchange, SignedCancelOrderRequest, SignedCFDOrder, SignedOrder} from '../../types';
import { Exchange, SignedCancelOrderRequest, SignedCFDOrder, SignedOrder } from '../../types';
import { pairConfigSchema } from './schemas';
import {
aggregatedOrderbookSchema, exchangeOrderbookSchema, poolReservesSchema,
} from './schemas/aggregatedOrderbookSchema';
import networkCodes from '../../constants/networkCodes';
import toUpperCase from '../../utils/toUpperCase';
import httpToWS from '../../utils/httpToWS';
class OrionAggregator {
private readonly apiUrl: string;
readonly ws: OrionAggregatorWS;
constructor(apiUrl: string, apiWsUrl: string) {
this.apiUrl = apiUrl;
this.ws = new OrionAggregatorWS(apiWsUrl);
get api() {
return this.apiUrl;
}
constructor(
httpAPIUrl: string,
wsAPIUrl: string,
) {
// const oaUrl = new URL(apiUrl);
// const oaWsProtocol = oaUrl.protocol === 'https:' ? 'wss' : 'ws';
// const orionAggregatorWsUrl = `${oaWsProtocol}://${oaUrl.host + (oaUrl.pathname === '/'
// ? ''
// : oaUrl.pathname)}/v1`;
this.apiUrl = httpAPIUrl;
this.ws = new OrionAggregatorWS(httpToWS(wsAPIUrl));
this.getHistoryAtomicSwaps = this.getHistoryAtomicSwaps.bind(this);
this.getPairConfig = this.getPairConfig.bind(this);

View File

@@ -68,10 +68,10 @@ type SwapInfoSubscription = {
type AddressUpdateUpdate = {
kind: 'update',
balances: Partial<
Record<
string,
Balance
>
Record<
string,
Balance
>
>,
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
}
@@ -79,10 +79,10 @@ type AddressUpdateUpdate = {
type AddressUpdateInitial = {
kind: 'initial',
balances: Partial<
Record<
string,
Balance
>
Record<
string,
Balance
>
>,
orders?: z.infer<typeof fullOrderSchema>[] // The field is not defined if the user has no orders
}
@@ -124,7 +124,23 @@ const exclusiveSubscriptions = [
SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE,
] as const;
type WsMessage = string | ArrayBufferLike | Blob | ArrayBufferView;
type BufferLike =
| string
| Buffer
| DataView
| number
| ArrayBufferView
| Uint8Array
| ArrayBuffer
| SharedArrayBuffer
| ReadonlyArray<unknown>
| ReadonlyArray<number>
| { valueOf(): ArrayBuffer }
| { valueOf(): SharedArrayBuffer }
| { valueOf(): Uint8Array }
| { valueOf(): ReadonlyArray<number> }
| { valueOf(): string }
| { [Symbol.toPrimitive](hint: string): string };
const isSubType = (subType: string): subType is keyof Subscription => Object.values(SubscriptionType).some((t) => t === subType);
class OrionAggregatorWS {
@@ -148,14 +164,23 @@ class OrionAggregatorWS {
private readonly wsUrl: string;
constructor(wsUrl: string, logger?: (msg: string) => void, onInit?: () => void, onError?: (err: string) => void) {
get api() {
return this.wsUrl;
}
constructor(
wsUrl: string,
logger?: (msg: string) => void,
onInit?: () => void,
onError?: (err: string) => void
) {
this.wsUrl = wsUrl;
this.logger = logger;
this.onInit = onInit;
this.onError = onError;
}
private sendRaw(data: WsMessage) {
private sendRaw(data: BufferLike) {
if (this.ws?.readyState === 1) {
this.ws.send(data);
} else if (this.ws?.readyState === 0) {
@@ -167,7 +192,9 @@ class OrionAggregatorWS {
private send(data: unknown) {
if (this.ws?.readyState === 1) {
this.ws.send(JSON.stringify(data));
const jsonData = JSON.stringify(data);
this.ws.send(jsonData);
this.logger?.(`Sent: ${jsonData}`);
} else {
setTimeout(() => {
this.send(data);
@@ -268,7 +295,7 @@ class OrionAggregatorWS {
delete this.ws;
}
init(isReconnect = false) {
private init(isReconnect = false) {
this.isClosedIntentionally = false;
this.ws = new WebSocket(this.wsUrl);
this.ws.onerror = (err) => {
@@ -455,7 +482,7 @@ class OrionAggregatorWS {
});
}
break;
case MessageType.CFD_ADDRESS_UPDATE: {
case MessageType.CFD_ADDRESS_UPDATE:
switch (json.k) { // message kind
case 'i': { // initial
const fullOrders = json.o
@@ -494,7 +521,6 @@ class OrionAggregatorWS {
default:
break;
}
}
break;
case MessageType.ADDRESS_UPDATE: {
const balances = json.b

View File

@@ -1,8 +1,8 @@
import { z } from "zod";
import { fullOrderSchema, orderUpdateSchema } from "./addressUpdateSchema";
import baseMessageSchema from "./baseMessageSchema";
import MessageType from "../MessageType";
import cfdBalancesSchema from "./cfdBalancesSchema";
import { z } from 'zod';
import { fullOrderSchema, orderUpdateSchema } from './addressUpdateSchema';
import baseMessageSchema from './baseMessageSchema';
import MessageType from '../MessageType';
import cfdBalancesSchema from './cfdBalancesSchema';
const baseCfdAddressUpdate = baseMessageSchema.extend({
id: z.string(),

View File

@@ -1,5 +1,5 @@
import { z } from 'zod';
import positionStatuses from "../../../../constants/positionStatuses";
import positionStatuses from '../../../../constants/positionStatuses';
const cfdBalanceSchema = z
.object({

View File

@@ -10,8 +10,12 @@ export default class OrionAnalytics {
this.getOverview = this.getOverview.bind(this);
}
get api() {
return this.apiUrl;
}
getOverview = () => fetchWithValidation(
`${this.apiUrl}/api/stats/overview`,
`${this.apiUrl}/overview`,
overviewSchema,
);
}

View File

@@ -63,6 +63,10 @@ type CfdHistoryQuery = {
class OrionBlockchain {
private readonly apiUrl: string;
get api() {
return this.apiUrl;
}
constructor(apiUrl: string) {
this.apiUrl = apiUrl;

View File

@@ -9,6 +9,10 @@ class PriceFeed {
readonly ws: PriceFeedWS;
get api() {
return this.apiUrl;
}
constructor(apiUrl: string) {
this.apiUrl = apiUrl;
this.ws = new PriceFeedWS(this.wsUrl);

View File

@@ -1,3 +1,4 @@
import { z } from 'zod';
import fetchWithValidation from '../../fetchWithValidation';
import { errorSchema, miniStatsSchema, rewardsMappingSchema } from './schemas';
import distinctAnalyticsSchema from './schemas/distinctAnalyticsSchema';
@@ -21,8 +22,12 @@ type SignatureType = {
class ReferralSystem {
private apiUrl: string;
constructor(apiUrl: string, env: string) {
this.apiUrl = ReferralSystem.getActualApiUrl(apiUrl, env);
get api() {
return this.apiUrl;
}
constructor(apiUrl: string) {
this.apiUrl = apiUrl;
this.getLink = this.getLink.bind(this);
this.getDistinctAnalytics = this.getDistinctAnalytics.bind(this);
@@ -31,19 +36,6 @@ class ReferralSystem {
this.getMyReferral = this.getMyReferral.bind(this);
}
// ресурсы реферальной системы в тестинг окружении имеют вид
// testing.orionprotocol.io/referral-api вместо обычного
// testing.orionprotocol.io/bsc-testnet/referral-api, поэтому лишняя часть вырезается
static getActualApiUrl = (apiUrl: string, env: string) => {
if (env === 'testing' || env === 'custom') {
const { protocol, hostname } = new URL(apiUrl);
return `${protocol}//${hostname}/referral-api`;
}
return `${apiUrl}/referral-api`;
};
getLink = (refererAddress: string) => fetchWithValidation(`${this.apiUrl}/referer/view/link`, linkSchema, {
headers: {
'referer-address': refererAddress,
@@ -76,6 +68,9 @@ class ReferralSystem {
globalAnalyticsSchema,
);
/**
* @param refererAddress Address without 0x prefix
*/
getMiniStats = (refererAddress: string) => fetchWithValidation(
`${this.apiUrl}/referer/view/mini-latest-stats`,
miniStatsSchema,
@@ -84,6 +79,10 @@ class ReferralSystem {
'referer-address': refererAddress,
},
},
z.object({
status: z.string(),
message: z.string(),
}),
);
getRewardsMapping = (referralAddress: string) => fetchWithValidation(