Linter standard (#49)

* Impl

* Fix

* Fix

* Bump

* Bump

* Fix

* Bump
This commit is contained in:
Aleksandr Kraiz
2023-02-14 00:34:37 +04:00
committed by GitHub
parent 7040df6142
commit c12a4e8e7a
48 changed files with 964 additions and 594 deletions

View File

@@ -1,4 +1,4 @@
import BigNumber from 'bignumber.js';
import type BigNumber from 'bignumber.js';
import { z } from 'zod';
import fetchWithValidation from '../../fetchWithValidation';
import swapInfoSchema from './schemas/swapInfoSchema';
@@ -9,12 +9,12 @@ 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 { type Exchange, type SignedCancelOrderRequest, type SignedCFDOrder, type SignedOrder } from '../../types';
import { pairConfigSchema } from './schemas';
import {
aggregatedOrderbookSchema, exchangeOrderbookSchema, poolReservesSchema,
} from './schemas/aggregatedOrderbookSchema';
import networkCodes from '../../constants/networkCodes';
import type networkCodes from '../../constants/networkCodes';
import toUpperCase from '../../utils/toUpperCase';
import httpToWS from '../../utils/httpToWS';
@@ -146,7 +146,7 @@ class OrionAggregator {
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json',
...partnerId && { 'X-Partner-Id': partnerId },
...(partnerId !== undefined) && { 'X-Partner-Id': partnerId },
};
return fetchWithValidation(
@@ -232,7 +232,7 @@ class OrionAggregator {
} else {
url.searchParams.append('amountOut', amount);
}
if (exchanges) {
if (exchanges !== undefined) {
if (Array.isArray(exchanges)) {
exchanges.forEach((exchange) => {
url.searchParams.append('exchanges', exchange);
@@ -241,7 +241,7 @@ class OrionAggregator {
url.searchParams.append('exchanges', exchanges);
}
}
if (instantSettlement) {
if (instantSettlement !== undefined && instantSettlement) {
url.searchParams.append('instantSettlement', 'true');
}

View File

@@ -10,12 +10,12 @@ import {
} from './schemas';
import UnsubscriptionType from './UnsubscriptionType';
import {
SwapInfoBase, AssetPairUpdate, OrderbookItem, Balance,
Exchange, CFDBalance, SwapInfo, FuturesTradeInfo,
type SwapInfoBase, type AssetPairUpdate, type OrderbookItem,
type Balance, type Exchange, type CFDBalance, type FuturesTradeInfo, type SwapInfo,
} from '../../../types';
import unsubscriptionDoneSchema from './schemas/unsubscriptionDoneSchema';
import assetPairConfigSchema from './schemas/assetPairConfigSchema';
import { fullOrderSchema, orderUpdateSchema } from './schemas/addressUpdateSchema';
import { type fullOrderSchema, type orderUpdateSchema } from './schemas/addressUpdateSchema';
import cfdAddressUpdateSchema from './schemas/cfdAddressUpdateSchema';
import futuresTradeInfoSchema from './schemas/futuresTradeInfoSchema';
// import errorSchema from './schemas/errorSchema';
@@ -25,108 +25,108 @@ 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
i: string, // asset in
o: string, // asset out
i: string // asset in
o: string // asset out
a: number // amount IN/OUT
es?: Exchange[] | 'cex' | 'pools', // exchange list of all cex or all pools (ORION_POOL, UNISWAP, PANCAKESWAP etc)
e?: boolean; // is amount IN? Value `false` means a = amount OUT, `true` if omitted
is?: boolean; // instant settlement
es?: Exchange[] | 'cex' | 'pools' // exchange list of all cex or all pools (ORION_POOL, UNISWAP, PANCAKESWAP etc)
e?: boolean // is amount IN? Value `false` means a = amount OUT, `true` if omitted
is?: boolean // instant settlement
}
type BrokerTradableAtomicSwapBalanceSubscription = {
callback: (balances: Partial<Record<string, number>>) => void,
callback: (balances: Partial<Record<string, number>>) => void
}
type PairsConfigSubscription = {
callback: ({ kind, data }: {
kind: 'initial' | 'update',
data: Partial<Record<string, AssetPairUpdate>>,
}) => void,
kind: 'initial' | 'update'
data: Partial<Record<string, AssetPairUpdate>>
}) => void
}
type PairConfigSubscription = {
payload: string,
payload: string
callback: ({ kind, data }: {
kind: 'initial' | 'update',
data: AssetPairUpdate,
}) => void,
kind: 'initial' | 'update'
data: AssetPairUpdate
}) => void
}
type AggregatedOrderbookSubscription = {
payload: string,
payload: string
callback: (
asks: OrderbookItem[],
bids: OrderbookItem[],
pair: string
) => void,
) => void
}
type SwapInfoSubscription = {
payload: SwapSubscriptionRequest,
callback: (swapInfo: SwapInfo) => void,
payload: SwapSubscriptionRequest
callback: (swapInfo: SwapInfo) => void
}
type FuturesTradeInfoSubscription = {
payload: {
s: string,
i: string,
a: number,
p?: number,
},
callback: (futuresTradeInfo: FuturesTradeInfo) => void,
s: string
i: string
a: number
p?: number
}
callback: (futuresTradeInfo: FuturesTradeInfo) => void
}
type AddressUpdateUpdate = {
kind: 'update',
kind: 'update'
balances: Partial<
Record<
string,
Balance
>
>,
Record<
string,
Balance
>
>
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
}
type AddressUpdateInitial = {
kind: 'initial',
kind: 'initial'
balances: Partial<
Record<
string,
Balance
>
>,
orders?: z.infer<typeof fullOrderSchema>[] // The field is not defined if the user has no orders
Record<
string,
Balance
>
>
orders?: Array<z.infer<typeof fullOrderSchema>> // The field is not defined if the user has no orders
}
type CfdAddressUpdateUpdate = {
kind: 'update',
balances?: CFDBalance[],
kind: 'update'
balances?: CFDBalance[]
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema>
}
type CfdAddressUpdateInitial = {
kind: 'initial',
balances: CFDBalance[],
orders?: z.infer<typeof fullOrderSchema>[] // The field is not defined if the user has no orders
kind: 'initial'
balances: CFDBalance[]
orders?: Array<z.infer<typeof fullOrderSchema>> // The field is not defined if the user has no orders
}
type AddressUpdateSubscription = {
payload: string,
callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void,
payload: string
callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void
}
type CfdAddressUpdateSubscription = {
payload: string,
callback: (data: CfdAddressUpdateUpdate | CfdAddressUpdateInitial) => void,
payload: string
callback: (data: CfdAddressUpdateUpdate | CfdAddressUpdateInitial) => void
}
type Subscription = {
[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]: AddressUpdateSubscription,
[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE]: CfdAddressUpdateSubscription,
[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]: AggregatedOrderbookSubscription,
[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]: PairsConfigSubscription,
[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE]: PairConfigSubscription,
[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]: BrokerTradableAtomicSwapBalanceSubscription,
[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]: AddressUpdateSubscription
[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE]: CfdAddressUpdateSubscription
[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]: AggregatedOrderbookSubscription
[SubscriptionType.ASSET_PAIRS_CONFIG_UPDATES_SUBSCRIBE]: PairsConfigSubscription
[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE]: PairConfigSubscription
[SubscriptionType.BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE]: BrokerTradableAtomicSwapBalanceSubscription
[SubscriptionType.SWAP_SUBSCRIBE]: SwapInfoSubscription
[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]: FuturesTradeInfoSubscription
}
@@ -145,14 +145,14 @@ type BufferLike =
| Uint8Array
| ArrayBuffer
| SharedArrayBuffer
| ReadonlyArray<unknown>
| ReadonlyArray<number>
| { valueOf(): ArrayBuffer }
| { valueOf(): SharedArrayBuffer }
| { valueOf(): Uint8Array }
| { valueOf(): ReadonlyArray<number> }
| { valueOf(): string }
| { [Symbol.toPrimitive](hint: string): string };
| readonly unknown[]
| readonly number[]
| { valueOf: () => ArrayBuffer }
| { valueOf: () => SharedArrayBuffer }
| { valueOf: () => Uint8Array }
| { valueOf: () => readonly 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 {
@@ -339,8 +339,9 @@ class OrionAggregatorWS {
};
this.ws.onmessage = (e) => {
const { data } = e;
this.logger?.(`OrionAggregatorWS: received message: ${e.data.toString()}`);
const rawJson: unknown = JSON.parse(data.toString());
if (typeof data !== 'string') throw new Error('OrionAggregatorWS: received non-string message');
this.logger?.(`OrionAggregatorWS: received message: ${data}`);
const rawJson: unknown = JSON.parse(data);
const messageSchema = z.union([
initMessageSchema,
@@ -385,7 +386,7 @@ class OrionAggregatorWS {
path: json.ps,
exchanges: json.e,
poolOptimal: json.po,
...json.oi && {
...(json.oi) && {
orderInfo: {
pair: json.oi.p,
side: json.oi.s,
@@ -511,8 +512,8 @@ class OrionAggregatorWS {
case MessageType.CFD_ADDRESS_UPDATE:
switch (json.k) { // message kind
case 'i': { // initial
const fullOrders = json.o
? json.o.reduce<z.infer<typeof fullOrderSchema>[]>((prev, o) => {
const fullOrders = (json.o)
? json.o.reduce<Array<z.infer<typeof fullOrderSchema>>>((prev, o) => {
prev.push(o);
return prev;
@@ -524,7 +525,7 @@ class OrionAggregatorWS {
]?.[json.id]?.callback({
kind: 'initial',
orders: fullOrders,
balances: json.b ?? [],
balances: json.b,
});
}
break;
@@ -549,7 +550,7 @@ class OrionAggregatorWS {
}
break;
case MessageType.ADDRESS_UPDATE: {
const balances = json.b
const balances = (json.b)
? Object.entries(json.b)
.reduce<Partial<Record<string, Balance>>>((prev, [asset, assetBalances]) => {
if (!assetBalances) return prev;
@@ -565,7 +566,7 @@ class OrionAggregatorWS {
switch (json.k) { // message kind
case 'i': { // initial
const fullOrders = json.o
? json.o.reduce<z.infer<typeof fullOrderSchema>[]>((prev, o) => {
? json.o.reduce<Array<z.infer<typeof fullOrderSchema>>>((prev, o) => {
prev.push(o);
return prev;

View File

@@ -2,7 +2,7 @@ import fetchWithValidation from '../../fetchWithValidation';
import overviewSchema from './schemas/overviewSchema';
export default class OrionAnalytics {
private apiUrl: string;
private readonly apiUrl: string;
constructor(apiUrl: string) {
this.apiUrl = apiUrl;

View File

@@ -3,63 +3,63 @@ import fetchWithValidation from '../../fetchWithValidation';
import {
IDOSchema, atomicHistorySchema,
poolsConfigSchema, poolsInfoSchema, infoSchema, historySchema,
addPoolSchema, adminPoolsListSchema, adminPoolSchema,
type addPoolSchema, adminPoolsListSchema, adminPoolSchema,
atomicSummarySchema,
poolsLpAndStakedSchema,
userVotesSchema,
userEarnedSchema,
PairStatusEnum,
type PairStatusEnum,
pairStatusSchema,
cfdContractsSchema,
cfdHistorySchema,
} from './schemas';
import redeemOrderSchema from '../OrionAggregator/schemas/redeemOrderSchema';
import type redeemOrderSchema from '../OrionAggregator/schemas/redeemOrderSchema';
import { sourceAtomicHistorySchema, targetAtomicHistorySchema } from './schemas/atomicHistorySchema';
import { makePartial } from '../../utils';
import { networkCodes } from '../../constants';
import { type networkCodes } from '../../constants';
interface IAdminAuthHeaders {
auth: string;
type IAdminAuthHeaders = {
auth: string
[key: string]: string
}
export interface IEditPool {
tokenAIcon?: string;
tokenBIcon?: string;
symbol?: string;
status: PairStatusEnum;
minQty?: number;
tokenASymbol?: string;
tokenBSymbol?: string;
tokensReversed?: boolean;
export type IEditPool = {
tokenAIcon?: string
tokenBIcon?: string
symbol?: string
status: PairStatusEnum
minQty?: number
tokenASymbol?: string
tokenBSymbol?: string
tokensReversed?: boolean
}
type AtomicSwapHistoryBaseQuery = {
limit?: number
sender?: string,
receiver?: string,
used?: 0 | 1,
page?: number,
sourceNetworkCode?: typeof networkCodes[number],
}
sender?: string
receiver?: string
used?: 0 | 1
page?: number
sourceNetworkCode?: typeof networkCodes[number]
} & Partial<Record<string, string | number>>
type AtomicSwapHistorySourceQuery = AtomicSwapHistoryBaseQuery & {
type?: 'source',
expiredLock?: 0 | 1,
state?: 'LOCKED' | 'CLAIMED' |'REFUNDED',
type?: 'source'
expiredLock?: 0 | 1
state?: 'LOCKED' | 'CLAIMED' | 'REFUNDED'
}
type AtomicSwapHistoryTargetQuery = AtomicSwapHistoryBaseQuery & {
type?: 'target',
expiredRedeem?: 0 | 1,
state?: 'REDEEMED' | 'BEFORE-REDEEM',
type?: 'target'
expiredRedeem?: 0 | 1
state?: 'REDEEMED' | 'BEFORE-REDEEM'
}
type CfdHistoryQuery = {
instrument?: string,
page?: number,
limit?: number,
}
instrument?: string
page?: number
limit?: number
} & Partial<Record<string, string | number>>
class OrionBlockchain {
private readonly apiUrl: string;
@@ -110,12 +110,12 @@ class OrionBlockchain {
return `${this.apiUrl}/`;
}
private getSummaryRedeem = (brokerAddress: string, unshifted?: 1 | 0, sourceNetworkCode?: typeof networkCodes[number]) => {
private readonly getSummaryRedeem = (brokerAddress: string, unshifted?: 1 | 0, sourceNetworkCode?: typeof networkCodes[number]) => {
const url = new URL(`${this.apiUrl}/api/atomic/summary-redeem/${brokerAddress}`);
if (unshifted) {
if (unshifted !== undefined && unshifted === 1) {
url.searchParams.append('unshifted', unshifted.toString());
}
if (sourceNetworkCode) {
if (sourceNetworkCode !== undefined) {
url.searchParams.append('sourceNetworkCode', sourceNetworkCode);
}
return fetchWithValidation(
@@ -124,12 +124,12 @@ class OrionBlockchain {
);
};
private getSummaryClaim = (brokerAddress: string) => fetchWithValidation(
private readonly getSummaryClaim = (brokerAddress: string) => fetchWithValidation(
`${this.apiUrl}/api/atomic/summary-claim/${brokerAddress}`,
atomicSummarySchema,
);
private getQueueLength = () => fetchWithValidation(
private readonly getQueueLength = () => fetchWithValidation(
`${this.apiUrl}/api/queueLength`,
z.number().int(),
);
@@ -357,7 +357,10 @@ class OrionBlockchain {
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
Object.entries(query)
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
.forEach(([key, value]) => {
if (value === undefined) throw new Error('Value must be defined');
url.searchParams.append(key, value.toString());
});
return fetchWithValidation(url.toString(), atomicHistorySchema);
};
@@ -366,9 +369,12 @@ class OrionBlockchain {
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
Object.entries(query)
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
.forEach(([key, value]) => {
if (value === undefined) throw new Error('Value must be defined');
url.searchParams.append(key, value.toString());
});
if (!query.type) url.searchParams.append('type', 'source');
if (query.type !== undefined) url.searchParams.append('type', 'source');
return fetchWithValidation(url.toString(), sourceAtomicHistorySchema);
};
@@ -377,9 +383,12 @@ class OrionBlockchain {
const url = new URL(`${this.apiUrl}/api/atomic/history/`);
Object.entries(query)
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
.forEach(([key, value]) => {
if (value === undefined) throw new Error('Value must be defined');
url.searchParams.append(key, value.toString());
});
if (!query.type) url.searchParams.append('type', 'target');
if (query.type !== undefined) url.searchParams.append('type', 'target');
return fetchWithValidation(url.toString(), targetAtomicHistorySchema);
};
@@ -406,7 +415,10 @@ class OrionBlockchain {
const url = new URL(`${this.apiUrl}/api/cfd/deposit-withdraw/${address}`);
Object.entries(query)
.forEach(([key, value]) => url.searchParams.append(key, value.toString()));
.forEach(([key, value]) => {
if (value === undefined) throw new Error('Value must be defined');
url.searchParams.append(key, value.toString());
});
return fetchWithValidation(url.toString(), cfdHistorySchema);
};

View File

@@ -1,11 +1,11 @@
import fetchWithValidation from '../../fetchWithValidation';
import { Exchange } from '../../types';
import { type Exchange } from '../../types';
import { statisticsOverviewSchema, topPairsStatisticsSchema } from './schemas';
import candlesSchema from './schemas/candlesSchema';
import { PriceFeedWS } from './ws';
class PriceFeed {
private apiUrl: string;
private readonly apiUrl: string;
readonly ws: PriceFeedWS;

View File

@@ -6,12 +6,12 @@ import { tickerInfoSchema, candleSchema } from './schemas';
import priceSchema from './schemas/priceSchema';
type TickerInfo = {
pairName: string;
lastPrice: string;
openPrice: string;
highPrice: string;
lowPrice: string;
volume24h: string;
pairName: string
lastPrice: string
openPrice: string
highPrice: string
lowPrice: string
volume24h: string
}
const allTickersSchema = z.unknown().array()
@@ -57,11 +57,11 @@ export type Subscription<
Schema = z.infer<typeof subscriptions[T]['schema']>
> = typeof subscriptions[T] extends { payload: true }
? {
callback: (data: Schema) => void,
payload: string,
} : {
callback: (data: Schema) => void,
}
callback: (data: Schema) => void
payload: string
} : {
callback: (data: Schema) => void
}
export default class PriceFeedSubscription<T extends SubscriptionType = SubscriptionType> {
public readonly id: string;
@@ -104,16 +104,23 @@ export default class PriceFeedSubscription<T extends SubscriptionType = Subscrip
this.isClosedIntentionally = false;
const { payload, url, type } = this;
this.ws = new WebSocket(`${url}/${type}${payload ? `/${payload.toString()}` : ''}`);
this.ws = new WebSocket(`${url}/${type}${payload !== undefined ? `/${payload.toString()}` : ''}`);
this.ws.onmessage = (e) => {
if (e.data === 'pong') return;
const json: unknown = JSON.parse(e.data.toString());
const { data } = e;
// const isBufferArray = Array.isArray(data);
// const isArrayBuffer = data instanceof ArrayBuffer;
const isBuffer = Buffer.isBuffer(data);
if (!isBuffer) throw new Error('Not a buffer');
const dataString = data.toString();
if (dataString === 'pong') return;
const json: unknown = JSON.parse(dataString);
const subscription = subscriptions[type];
const parseResult = subscription.schema.safeParse(json);
if (parseResult.success === false) {
if (!parseResult.success) {
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}`);
throw new Error(`Can't recognize PriceFeed "${type}" subscription message "${dataString}": ${errorsMessage}`);
}
this.callback(parseResult.data);
};

View File

@@ -1,4 +1,4 @@
import PriceFeedSubscription, { SubscriptionType, Subscription } from './PriceFeedSubscription';
import PriceFeedSubscription, { type SubscriptionType, type Subscription } from './PriceFeedSubscription';
export * as schemas from './schemas';
export class PriceFeedWS {
@@ -11,7 +11,7 @@ export class PriceFeedWS {
>;
}> = {};
private url: string;
private readonly url: string;
constructor(url: string) {
this.url = url;
@@ -36,7 +36,7 @@ export class PriceFeedWS {
return {
type: sub.type,
id: sub.id,
unsubscribe: () => this.unsubscribe(sub.type, sub.id),
unsubscribe: () => { this.unsubscribe(sub.type, sub.id); },
};
}

View File

@@ -6,21 +6,21 @@ import globalAnalyticsSchema from './schemas/globalAnalyticsSchema';
import linkSchema from './schemas/linkSchema';
type CreateLinkPayloadType = {
referer: string;
link_option: number;
};
referer: string
link_option: number
}
type SubscribePayloadType = {
ref_target: string;
referral: string;
ref_target: string
referral: string
}
type SignatureType = {
signature: string;
};
signature: string
}
class ReferralSystem {
private apiUrl: string;
private readonly apiUrl: string;
get api() {
return this.apiUrl;