Merge pull request #146 from orionprotocol/remove-cfd

Removed cfd
This commit is contained in:
Dmitry
2023-07-11 12:32:12 +03:00
committed by GitHub
23 changed files with 16 additions and 585 deletions

View File

@@ -134,7 +134,7 @@ const assets = await orion.getAssets(); // Optional: tradableOnly: boolean (defa
### Get pairs
```ts
const pairs = await orion.getPairs("spot"); // 'spot' | 'futures'
const pairs = await orion.getPairs("spot"); // 'spot'
// Response example:
// {

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "@orionprotocol/sdk",
"version": "0.19.25-rc1",
"version": "0.19.33-rc2",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@orionprotocol/sdk",
"version": "0.19.25-rc1",
"version": "0.19.33-rc2",
"license": "ISC",
"dependencies": {
"@babel/runtime": "^7.21.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@orionprotocol/sdk",
"version": "0.19.32",
"version": "0.19.33-rc3",
"description": "Orion Protocol SDK",
"main": "./lib/index.cjs",
"module": "./lib/index.js",

View File

@@ -1,15 +0,0 @@
const CFD_ORDER_TYPES = {
CFDOrder: [
{ name: 'senderAddress', type: 'address' },
{ name: 'matcherAddress', type: 'address' },
{ name: 'instrumentAddress', type: 'address' },
{ name: 'amount', type: 'uint64' },
{ name: 'price', type: 'uint64' },
{ name: 'matcherFee', type: 'uint64' },
{ name: 'nonce', type: 'uint64' },
{ name: 'expiration', type: 'uint64' },
{ name: 'buySide', type: 'uint8' },
],
};
export default CFD_ORDER_TYPES;

View File

@@ -1,31 +0,0 @@
import { ethers } from 'ethers';
import type { CFDOrder } from '../types.js';
const hashCFDOrder = (order: CFDOrder) => ethers.utils.solidityKeccak256(
[
'uint8',
'address',
'address',
'address',
'uint64',
'uint64',
'uint64',
'uint64',
'uint64',
'uint8',
],
[
'0x03',
order.senderAddress,
order.matcherAddress,
order.instrumentAddress,
order.amount,
order.price,
order.matcherFee,
order.nonce,
order.expiration,
order.buySide === 1 ? '0x01' : '0x00',
],
);
export default hashCFDOrder;

View File

@@ -1,5 +1,4 @@
export { default as signCancelOrder } from './signCancelOrder.js';
export { default as signCancelOrderPersonal } from './signCancelOrderPersonal.js';
export { default as signOrder } from './signOrder.js';
export { default as signCFDOrder } from './signCFDOrder.js';
export { default as signOrderPersonal } from './signOrderPersonal.js';

View File

@@ -1,88 +0,0 @@
import type { TypedDataSigner } from '@ethersproject/abstract-signer';
import { BigNumber } from 'bignumber.js';
import type { ethers } from 'ethers';
import { joinSignature, splitSignature } from 'ethers/lib/utils.js';
import { INTERNAL_PROTOCOL_PRECISION } from '../constants/index.js';
import type { CFDOrder, SignedCFDOrder, SupportedChainId } from '../types.js';
import normalizeNumber from '../utils/normalizeNumber.js';
import getDomainData from './getDomainData.js';
import signCFDOrderPersonal from './signCFDOrderPersonal.js';
import hashCFDOrder from './hashCFDOrder.js';
import CFD_ORDER_TYPES from '../constants/cfdOrderTypes.js';
const DEFAULT_EXPIRATION = 29 * 24 * 60 * 60 * 1000; // 29 days
type SignerWithTypedDataSign = ethers.Signer & TypedDataSigner;
export const signCFDOrder = async (
instrumentAddress: string,
side: 'BUY' | 'SELL',
price: BigNumber.Value,
amount: BigNumber.Value,
matcherFee: BigNumber.Value,
senderAddress: string,
matcherAddress: string,
usePersonalSign: boolean,
signer: ethers.Signer,
chainId: SupportedChainId,
stopPrice: BigNumber.Value | undefined,
isFromDelegate?: boolean,
) => {
const nonce = Date.now();
const expiration = nonce + DEFAULT_EXPIRATION;
const order: CFDOrder = {
senderAddress,
matcherAddress,
instrumentAddress,
amount: normalizeNumber(
amount,
INTERNAL_PROTOCOL_PRECISION,
BigNumber.ROUND_FLOOR,
).toNumber(),
price: normalizeNumber(
price,
INTERNAL_PROTOCOL_PRECISION,
BigNumber.ROUND_FLOOR,
).toNumber(),
matcherFee: normalizeNumber(
matcherFee,
INTERNAL_PROTOCOL_PRECISION,
BigNumber.ROUND_CEIL, // ROUND_CEIL because we don't want get "not enough fee" error
).toNumber(),
nonce,
expiration,
buySide: side === 'BUY' ? 1 : 0,
stopPrice: stopPrice !== undefined
? new BigNumber(stopPrice).toNumber()
: undefined,
isPersonalSign: usePersonalSign,
isFromDelegate,
};
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const typedDataSigner = signer as SignerWithTypedDataSign;
const signature = usePersonalSign
? await signCFDOrderPersonal(order, signer)
: await typedDataSigner._signTypedData(
getDomainData(chainId),
CFD_ORDER_TYPES,
order,
);
// https://github.com/poap-xyz/poap-fun/pull/62#issue-928290265
// "Signature's v was always send as 27 or 28, but from Ledger was 0 or 1"
const fixedSignature = joinSignature(splitSignature(signature));
// if (!fixedSignature) throw new Error("Can't sign order");
const signedOrder: SignedCFDOrder = {
...order,
id: hashCFDOrder(order),
signature: fixedSignature,
};
return signedOrder;
};
export default signCFDOrder;

View File

@@ -1,30 +0,0 @@
import { ethers } from 'ethers';
import type { CFDOrder } from '../types.js';
const { arrayify, joinSignature, splitSignature } = ethers.utils;
const signCFDOrderPersonal = async (order: CFDOrder, signer: ethers.Signer) => {
const message = ethers.utils.solidityKeccak256(
[
'string', 'address', 'address', 'address', 'uint64', 'uint64', 'uint64', 'uint64', 'uint64', 'uint8',
],
[
'order',
order.senderAddress,
order.matcherAddress,
order.instrumentAddress,
order.amount,
order.price,
order.matcherFee,
order.nonce,
order.expiration,
order.buySide,
],
);
const signature = await signer.signMessage(arrayify(message));
// NOTE: metamask broke sig.v value and we fix it in next line
return joinSignature(splitSignature(signature));
};
export default signCFDOrderPersonal;

View File

@@ -8,11 +8,11 @@ import errorSchema from './schemas/errorSchema.js';
import placeAtomicSwapSchema from './schemas/placeAtomicSwapSchema.js';
import { AggregatorWS } from './ws/index.js';
import { atomicSwapHistorySchema } from './schemas/atomicSwapHistorySchema.js';
import type { BasicAuthCredentials, Exchange, SignedCancelOrderRequest, SignedCFDOrder, SignedOrder } from '../../types.js';
import { pairConfigSchema } from './schemas/index.js';
import type { BasicAuthCredentials, Exchange, SignedCancelOrderRequest, SignedOrder } from '../../types.js';
import {
aggregatedOrderbookSchema, exchangeOrderbookSchema, poolReservesSchema,
} from './schemas/aggregatedOrderbookSchema.js';
pairConfigSchema, aggregatedOrderbookSchema,
exchangeOrderbookSchema, poolReservesSchema,
} from './schemas/index.js';
import type networkCodes from '../../constants/networkCodes.js';
import toUpperCase from '../../utils/toUpperCase.js';
import httpToWS from '../../utils/httpToWS.js';
@@ -55,7 +55,6 @@ class Aggregator {
this.getTradeProfits = this.getTradeProfits.bind(this);
this.placeAtomicSwap = this.placeAtomicSwap.bind(this);
this.placeOrder = this.placeOrder.bind(this);
this.placeCFDOrder = this.placeCFDOrder.bind(this);
this.cancelOrder = this.cancelOrder.bind(this);
this.checkWhitelisted = this.checkWhitelisted.bind(this);
this.getLockedBalance = this.getLockedBalance.bind(this);
@@ -94,7 +93,7 @@ class Aggregator {
);
}
getPairsList = (market: 'spot' | 'futures') => {
getPairsList = (market: 'spot') => {
const url = new URL(`${this.apiUrl}/api/v1/pairs/list`);
url.searchParams.append('market', toUpperCase(market));
@@ -142,7 +141,7 @@ class Aggregator {
);
};
getPairConfigs = (market: 'spot' | 'futures') => {
getPairConfigs = (market: 'spot') => {
const url = new URL(`${this.apiUrl}/api/v1/pairs/exchangeInfo`);
url.searchParams.append('market', toUpperCase(market));
@@ -249,40 +248,6 @@ class Aggregator {
errorSchema,
);
placeCFDOrder = (
signedOrder: SignedCFDOrder,
isReversedOrder?: boolean,
) => {
const headers = {
'Content-Type': 'application/json',
Accept: 'application/json',
...(isReversedOrder !== undefined) && {
'X-Reverse-Order': isReversedOrder ? 'true' : 'false',
},
...this.basicAuthHeaders,
};
return fetchWithValidation(
`${this.apiUrl}/api/v1/order/futures`,
z.object({
orderId: z.string(),
placementRequests: z.array(
z.object({
amount: z.number(),
brokerAddress: z.string(),
exchange: z.string(),
}),
).optional(),
}),
{
headers,
method: 'POST',
body: JSON.stringify(signedOrder),
},
errorSchema,
);
};
getSwapInfo = (
type: 'exactSpend' | 'exactReceive',
assetIn: string,

View File

@@ -7,8 +7,6 @@ const MessageType = {
ASSET_PAIRS_CONFIG_UPDATE: 'apcu',
ASSET_PAIR_CONFIG_UPDATE: 'apiu',
ADDRESS_UPDATE: 'au',
CFD_ADDRESS_UPDATE: 'auf',
FUTURES_TRADE_INFO_UPDATE: 'fti',
BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATE: 'btasabu',
UNSUBSCRIPTION_DONE: 'ud',
} as const;

View File

@@ -3,10 +3,8 @@ const SubscriptionType = {
ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE: 'apius',
AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE: 'aobus',
ADDRESS_UPDATES_SUBSCRIBE: 'aus',
CFD_ADDRESS_UPDATES_SUBSCRIBE: 'ausf',
BROKER_TRADABLE_ATOMIC_SWAP_ASSETS_BALANCE_UPDATES_SUBSCRIBE: 'btasabus',
SWAP_SUBSCRIBE: 'ss',
FUTURES_TRADE_INFO_SUBSCRIBE: 'fts',
} as const;
export default SubscriptionType;

View File

@@ -11,13 +11,11 @@ import {
import UnsubscriptionType from './UnsubscriptionType.js';
import type {
SwapInfoBase, AssetPairUpdate, OrderbookItem,
Balance, Exchange, CFDBalance, FuturesTradeInfo, SwapInfo, Json, BasicAuthCredentials,
Balance, Exchange, SwapInfo, Json, BasicAuthCredentials,
} from '../../../types.js';
import unsubscriptionDoneSchema from './schemas/unsubscriptionDoneSchema.js';
import assetPairConfigSchema from './schemas/assetPairConfigSchema.js';
import type { fullOrderSchema, orderUpdateSchema } from './schemas/addressUpdateSchema.js';
import cfdAddressUpdateSchema from './schemas/cfdAddressUpdateSchema.js';
import futuresTradeInfoSchema from './schemas/futuresTradeInfoSchema.js';
import { objectKeys } from '../../../utils/objectKeys.js';
// import assertError from '../../../utils/assertError.js';
// import errorSchema from './schemas/errorSchema';
@@ -30,13 +28,11 @@ const messageSchema = z.union([
initMessageSchema,
pingPongMessageSchema,
addressUpdateSchema,
cfdAddressUpdateSchema,
assetPairsConfigSchema,
assetPairConfigSchema,
brokerMessageSchema,
orderBookSchema,
swapInfoSchema,
futuresTradeInfoSchema,
errorSchema,
unsubscriptionDoneSchema,
]);
@@ -51,13 +47,6 @@ type SwapInfoSubscriptionPayload = {
is?: boolean // instant settlement
}
type FuturesTradeInfoPayload = {
s: string // wallet address
i: string // pair
a: number // amount
p?: number // price
}
type BrokerTradableAtomicSwapBalanceSubscription = {
callback: (balances: Partial<Record<string, number>>) => void
}
@@ -92,12 +81,6 @@ type SwapInfoSubscription = {
callback: (swapInfo: SwapInfo) => void
}
type FuturesTradeInfoSubscription = {
payload: FuturesTradeInfoPayload
callback: (futuresTradeInfo: FuturesTradeInfo) => void
errorCb?: (message: string) => void
}
type AddressUpdateUpdate = {
kind: 'update'
balances: Partial<
@@ -120,38 +103,19 @@ type AddressUpdateInitial = {
orders?: Array<z.infer<typeof fullOrderSchema>> | undefined // The field is not defined if the user has no orders
}
type CfdAddressUpdateUpdate = {
kind: 'update'
balances?: CFDBalance[] | undefined
order?: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema> | undefined
}
type CfdAddressUpdateInitial = {
kind: 'initial'
balances: CFDBalance[]
orders?: Array<z.infer<typeof fullOrderSchema>> | undefined // The field is not defined if the user has no orders
}
type AddressUpdateSubscription = {
payload: string
callback: (data: AddressUpdateUpdate | AddressUpdateInitial) => void
errorCb?: (message: string) => void
}
type CfdAddressUpdateSubscription = {
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.SWAP_SUBSCRIBE]: SwapInfoSubscription
[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]: FuturesTradeInfoSubscription
}
const exclusiveSubscriptions = [
@@ -191,8 +155,6 @@ type Subscriptions = Partial<{
[K in keyof Subscription]: Partial<Record<string, Subscription[K]>>
}>;
const FUTURES_SUFFIX = 'USDF';
class AggregatorWS {
private ws?: WebSocket | undefined;
@@ -388,8 +350,7 @@ class AggregatorWS {
const isOrderBooksSubscription = (subId: string) => {
const isSpotPairName = subId.includes('-') && subId.split('-').length === 2;
const isFuturesPairName = subId.endsWith(FUTURES_SUFFIX);
return isSpotPairName || isFuturesPairName;
return isSpotPairName;
}
if (newestSubId.includes('0x')) { // is wallet address (ADDRESS_UPDATE)
@@ -401,20 +362,10 @@ class AggregatorWS {
delete this.subscriptions[SubscriptionType.ADDRESS_UPDATES_SUBSCRIBE]?.[key];
}
}
const aufSubscriptions = this.subscriptions[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE];
if (aufSubscriptions) {
const targetAufSub = Object.entries(aufSubscriptions).find(([, value]) => value?.payload === newestSubId);
if (targetAufSub) {
const [key] = targetAufSub;
delete this.subscriptions[SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE]?.[key];
}
}
} else if (uuidValidate(newestSubId)) {
// is swap info subscription (contains hyphen)
delete this.subscriptions[SubscriptionType.SWAP_SUBSCRIBE]?.[newestSubId];
delete this.subscriptions[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_SUBSCRIBE]?.[newestSubId];
delete this.subscriptions[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]?.[newestSubId];
// !!! swap info subscription is uuid that contains hyphen
} else if (isOrderBooksSubscription(newestSubId)) { // is pair name(AGGREGATED_ORDER_BOOK_UPDATE)
const aobSubscriptions = this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE];
@@ -593,18 +544,6 @@ class AggregatorWS {
}
}
break;
case MessageType.FUTURES_TRADE_INFO_UPDATE:
this.subscriptions[SubscriptionType.FUTURES_TRADE_INFO_SUBSCRIBE]?.[json.id]?.callback({
futuresTradeRequestId: json.id,
sender: json.S,
instrument: json.i,
buyPrice: json.bp,
sellPrice: json.sp,
buyPower: json.bpw,
sellPower: json.spw,
minAmount: json.ma,
});
break;
case MessageType.INITIALIZATION:
this.onInit?.();
break;
@@ -674,46 +613,6 @@ class AggregatorWS {
});
}
break;
case MessageType.CFD_ADDRESS_UPDATE:
switch (json.k) { // message kind
case 'i': { // initial
const fullOrders = (json.o)
? json.o.reduce<Array<z.infer<typeof fullOrderSchema>>>((prev, o) => {
prev.push(o);
return prev;
}, [])
: undefined;
this.subscriptions[
SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE
]?.[json.id]?.callback({
kind: 'initial',
orders: fullOrders,
balances: json.b,
});
}
break;
case 'u': { // update
let orderUpdate: z.infer<typeof orderUpdateSchema> | z.infer<typeof fullOrderSchema> | undefined;
if (json.o) {
const firstOrder = json.o[0];
orderUpdate = firstOrder;
}
this.subscriptions[
SubscriptionType.CFD_ADDRESS_UPDATES_SUBSCRIBE
]?.[json.id]?.callback({
kind: 'update',
order: orderUpdate,
balances: json.b,
});
}
break;
default:
break;
}
break;
case MessageType.ADDRESS_UPDATE: {
const balances = (json.b)
? Object.entries(json.b)

View File

@@ -1,11 +1,11 @@
import { z } from 'zod';
import { exchanges } from '../../../../constants/index.js';
import orderStatuses from '../../../../constants/orderStatuses.js';
import executionTypes from '../../../../constants/executionTypes.js';
import subOrderStatuses from '../../../../constants/subOrderStatuses.js';
import MessageType from '../MessageType.js';
import balancesSchema from './balancesSchema.js';
import baseMessageSchema from './baseMessageSchema.js';
import executionTypes from '../../../../constants/cfdExecutionTypes.js';
const baseAddressUpdate = baseMessageSchema.extend({
id: z.string(),
@@ -35,8 +35,8 @@ export const orderUpdateSchema = z.object({
S: z.enum(orderStatuses), // status
l: z.boolean().optional(), // is liquidation order
t: z.number(), // update time
E: z.enum(executionTypes).optional(), // execution type
C: z.string().optional(), // trigger condition
E: z.enum(executionTypes).optional(),
c: subOrderSchema.array(),
})
.transform((val) => ({
@@ -80,7 +80,7 @@ export const fullOrderSchema = z.object({
T: z.number(), // creation time / unix timestamp
t: z.number(), // update time
c: subOrderSchema.array(),
E: z.enum(executionTypes).optional(), // execution type
E: z.enum(executionTypes).optional(),
C: z.string().optional(), // trigger condition
ro: z.boolean().optional(), // is reversed order
}).transform((val) => ({

View File

@@ -1,33 +0,0 @@
import { z } from 'zod';
import { fullOrderSchema, orderUpdateSchema } from './addressUpdateSchema.js';
import baseMessageSchema from './baseMessageSchema.js';
import MessageType from '../MessageType.js';
import cfdBalancesSchema from './cfdBalancesSchema.js';
const baseCfdAddressUpdate = baseMessageSchema.extend({
id: z.string(),
T: z.literal(MessageType.CFD_ADDRESS_UPDATE),
S: z.string(), // subscription
uc: z.array(z.enum(['b', 'o'])), // update content
});
const updateMessageSchema = baseCfdAddressUpdate.extend({
k: z.literal('u'), // kind of message: "u" - updates
uc: z.array(z.enum(['b', 'o'])), // update content: "o" - orders updates, "b" - balance updates
b: cfdBalancesSchema.optional(),
o: z.tuple([fullOrderSchema.or(orderUpdateSchema)]).optional(),
});
const initialMessageSchema = baseCfdAddressUpdate.extend({
k: z.literal('i'), // kind of message: "i" - initial
b: cfdBalancesSchema,
o: z.array(fullOrderSchema)
.optional(), // When no orders — no field
});
const cfdAddressUpdateSchema = z.union([
initialMessageSchema,
updateMessageSchema,
]);
export default cfdAddressUpdateSchema

View File

@@ -1,52 +0,0 @@
import { z } from 'zod';
import positionStatuses from '../../../../constants/positionStatuses.js';
const cfdBalanceSchema = z
.object({
i: z.string(),
b: z.string(),
pnl: z.string(),
fr: z.string(),
e: z.string(),
p: z.string(),
cp: z.string(),
pp: z.string(),
r: z.string(),
m: z.string(),
mu: z.string(),
fmu: z.string(),
awb: z.string(),
l: z.string(),
s: z.enum(positionStatuses),
lfrs: z.string(),
lfrd: z.string(),
sfrs: z.string(),
sfrd: z.string(),
sop: z.string().optional(),
})
.transform((obj) => ({
instrument: obj.i,
balance: obj.b,
profitLoss: obj.pnl,
fundingRate: obj.fr,
equity: obj.e,
position: obj.p,
currentPrice: obj.cp,
positionPrice: obj.pp,
reserves: obj.r,
margin: obj.m,
marginUSD: obj.mu,
freeMarginUSD: obj.fmu,
availableWithdrawBalance: obj.awb,
leverage: obj.l,
status: obj.s,
longFundingRatePerSecond: obj.lfrs,
longFundingRatePerDay: obj.lfrd,
shortFundingRatePerSecond: obj.sfrs,
shortFundingRatePerDay: obj.sfrd,
stopOutPrice: obj.sop,
}));
const cfdBalancesSchema = z.array(cfdBalanceSchema);
export default cfdBalancesSchema;

View File

@@ -1,16 +0,0 @@
import { z } from 'zod';
import MessageType from '../MessageType.js';
const futuresTradeInfoSchema = z.object({
T: z.literal(MessageType.FUTURES_TRADE_INFO_UPDATE),
id: z.string(), // trade info request UUID, set by client side
S: z.string(), // sender
i: z.string(), // instrument
bp: z.number().optional(), // buy price
sp: z.number().optional(), // sell price
bpw: z.number(), // buy power
spw: z.number(), // sell power
ma: z.number(), // min amount
});
export default futuresTradeInfoSchema;

View File

@@ -7,6 +7,5 @@ export { default as initMessageSchema } from './initMessageSchema.js';
export { default as pingPongMessageSchema } from './pingPongMessageSchema.js';
export { default as swapInfoSchema } from './swapInfoSchema.js';
export { default as balancesSchema } from './balancesSchema.js';
export { default as cfdBalancesSchema } from './cfdBalancesSchema.js';
export * from './orderBookSchema.js';

View File

@@ -9,8 +9,6 @@ import {
userEarnedSchema,
type PairStatusEnum,
pairStatusSchema,
cfdContractsSchema,
cfdHistorySchema,
governanceContractsSchema,
governancePoolsSchema,
governancePoolSchema,
@@ -59,12 +57,6 @@ type AtomicSwapHistoryTargetQuery = AtomicSwapHistoryBaseQuery & {
expiredRedeem?: 0 | 1
state?: 'REDEEMED' | 'BEFORE-REDEEM'
}
type CfdHistoryQuery = {
instrument?: string
page?: number
limit?: number
} & Partial<Record<string, string | number>>
class BlockchainService {
private readonly apiUrl: string;
@@ -110,8 +102,6 @@ class BlockchainService {
this.getBlockNumber = this.getBlockNumber.bind(this);
this.getRedeemOrderBySecretHash = this.getRedeemOrderBySecretHash.bind(this);
this.claimOrder = this.claimOrder.bind(this);
this.getCFDContracts = this.getCFDContracts.bind(this);
this.getCFDHistory = this.getCFDHistory.bind(this);
this.getGovernanceContracts = this.getGovernanceContracts.bind(this);
this.getGovernancePools = this.getGovernancePools.bind(this);
this.getGovernancePool = this.getGovernancePool.bind(this);
@@ -222,12 +212,6 @@ class BlockchainService {
{ headers: this.basicAuthHeaders }
);
getCFDPrices = () => fetchWithValidation(
`${this.apiUrl}/api/cfd/prices`,
z.record(z.string()).transform(makePartial),
{ headers: this.basicAuthHeaders }
);
getTokensFee = () => fetchWithValidation(
`${this.apiUrl}/api/tokensFee`,
z.record(z.string()).transform(makePartial),
@@ -454,24 +438,6 @@ class BlockchainService {
},
);
getCFDContracts = () => fetchWithValidation(
`${this.apiUrl}/api/cfd/contracts`,
cfdContractsSchema,
{ headers: this.basicAuthHeaders },
);
getCFDHistory = (address: string, query: CfdHistoryQuery = {}) => {
const url = new URL(`${this.apiUrl}/api/cfd/deposit-withdraw/${address}`);
Object.entries(query)
.forEach(([key, value]) => {
if (value === undefined) throw new Error('Value must be defined');
url.searchParams.append(key, value.toString());
});
return fetchWithValidation(url.toString(), cfdHistorySchema, { headers: this.basicAuthHeaders });
};
getGovernanceContracts = () => fetchWithValidation(
`${this.apiUrl}/api/governance/info`,
governanceContractsSchema,

View File

@@ -1,20 +0,0 @@
import { z } from 'zod';
const cfdContractsSchema = z.array(z.object({
name: z.string(),
alias: z.string(),
address: z.string(),
leverage: z.number(),
soLevel: z.number(),
shortFR: z.number(),
longFR: z.number(),
shortFRStored: z.number(),
longFRStored: z.number(),
lastFRPriceUpdateTime: z.number(),
priceIndex: z.number(),
feePercent: z.number(),
withdrawMarginLevel: z.number(),
delegateContractAddress: z.string(),
}));
export default cfdContractsSchema;

View File

@@ -1,52 +0,0 @@
import { z } from 'zod';
import { HistoryTransactionStatus } from '../../../types.js';
export enum historyTransactionType {
WITHDRAW = 'withdrawal',
DEPOSIT = 'deposit',
}
const cfdHistoryItem = z.object({
_id: z.string(),
__v: z.number(),
address: z.string(),
instrument: z.string(),
instrumentAddress: z.string(),
balance: z.string(),
amount: z.string(),
amountNumber: z.string(),
position: z.string(),
reason: z.enum(['WITHDRAW', 'DEPOSIT']),
positionPrice: z.string(),
fundingRate: z.string(),
transactionHash: z.string(),
blockNumber: z.number(),
createdAt: z.number(),
});
const cfdHistorySchema = z.object({
success: z.boolean(),
count: z.number(),
total: z.number(),
pagination: z.object({}),
data: z.array(cfdHistoryItem),
}).transform((response) => {
return response.data.map((item) => {
const {
createdAt, reason, transactionHash, amountNumber,
} = item;
const type = historyTransactionType[reason];
return {
type,
date: createdAt,
token: 'USDT',
amount: amountNumber,
status: HistoryTransactionStatus.DONE,
transactionHash,
user: item.address,
};
});
});
export default cfdHistorySchema;

View File

@@ -12,8 +12,6 @@ export { default as atomicSummarySchema } from './atomicSummarySchema.js';
export { default as poolsLpAndStakedSchema } from './poolsLpAndStakedSchema.js';
export { default as userVotesSchema } from './userVotesSchema.js';
export { default as userEarnedSchema } from './userEarnedSchema.js';
export { default as cfdContractsSchema } from './cfdContractsSchema.js';
export { default as cfdHistorySchema } from './cfdHistorySchema.js';
export { default as governanceContractsSchema } from './governanceContractsSchema.js';
export { default as governancePoolsSchema } from './governancePoolsSchema.js';
export { default as governancePoolSchema } from './governancePoolSchema.js';

View File

@@ -35,29 +35,6 @@ export type Balance = {
export type PositionStatus = typeof positionStatuses[number];
export type CFDBalance = {
instrument: string
balance: string
profitLoss: string
fundingRate: string
equity: string
position: string
currentPrice: string
positionPrice: string
reserves: string
margin: string
marginUSD: string
freeMarginUSD: string
availableWithdrawBalance: string
leverage: string
status: PositionStatus
longFundingRatePerSecond: string
longFundingRatePerDay: string
shortFundingRatePerSecond: string
shortFundingRatePerDay: string
stopOutPrice: string | undefined
}
export type Order = {
senderAddress: string // address
matcherAddress: string // address
@@ -73,26 +50,6 @@ export type Order = {
isPersonalSign: boolean // bool
}
export type CFDOrder = {
senderAddress: string // address
matcherAddress: string // address
instrumentAddress: string // address
amount: number // uint64
price: number // uint64
matcherFee: number // uint64
nonce: number // uint64
expiration: number // uint64
buySide: 0 | 1 // uint8, 1=buy, 0=sell
stopPrice?: number | undefined // uint64
isPersonalSign: boolean // bool
isFromDelegate?: boolean | undefined // bool
}
export type SignedCFDOrder = {
id: string // hash of Order (it's not part of order structure in smart-contract)
signature: string // bytes
} & CFDOrder
export type SignedOrder = {
id: string // hash of Order (it's not part of order structure in smart-contract)
signature: string // bytes
@@ -246,17 +203,6 @@ export type SwapInfoByAmountOut = SwapInfoBase & {
export type SwapInfo = SwapInfoByAmountIn | SwapInfoByAmountOut;
export type FuturesTradeInfo = {
futuresTradeRequestId: string
sender: string
instrument: string
buyPrice: number | undefined
sellPrice: number | undefined
buyPower: number
sellPower: number
minAmount: number
}
export enum HistoryTransactionStatus {
PENDING = 'Pending',
DONE = 'Done',
@@ -298,7 +244,7 @@ export type VerboseUnitConfig = {
// https://price-feed:3003/
}
}
basicAuth?: BasicAuthCredentials,
basicAuth?: BasicAuthCredentials
}
export type KnownEnv = typeof knownEnvs[number];