mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-25 15:17:40 +03:00
feat!: added Integrator service
This commit is contained in:
@@ -58,6 +58,9 @@ export default class Orion {
|
||||
priceFeed: {
|
||||
api: networkConfig.api + networkConfig.services.priceFeed.all,
|
||||
},
|
||||
integrator: {
|
||||
api: networkConfig.api + networkConfig.services.integrator.http,
|
||||
}
|
||||
},
|
||||
};
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ import Exchange from './Exchange/index.js';
|
||||
import FarmingManager from './FarmingManager/index.js';
|
||||
import { chains, envs } from '../config/index.js';
|
||||
import type { networkCodes } from '../constants/index.js';
|
||||
import { IntegratorService } from '../services/Integrator/index.js';
|
||||
|
||||
type KnownConfig = {
|
||||
env: KnownEnv
|
||||
@@ -22,6 +23,8 @@ export default class Unit {
|
||||
|
||||
public readonly blockchainService: BlockchainService;
|
||||
|
||||
public readonly integrator: IntegratorService;
|
||||
|
||||
public readonly aggregator: Aggregator;
|
||||
|
||||
public readonly priceFeed: PriceFeed;
|
||||
@@ -58,6 +61,9 @@ export default class Unit {
|
||||
priceFeed: {
|
||||
api: networkConfig.api + networkConfig.services.priceFeed.all,
|
||||
},
|
||||
integrator: {
|
||||
api: networkConfig.api + networkConfig.services.integrator.http,
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
@@ -65,7 +71,7 @@ export default class Unit {
|
||||
}
|
||||
const chainInfo = chains[config.chainId];
|
||||
if (!chainInfo) throw new Error('Chain info is required');
|
||||
|
||||
|
||||
this.chainId = config.chainId;
|
||||
this.networkCode = chainInfo.code;
|
||||
this.contracts = chainInfo.contracts
|
||||
@@ -75,6 +81,7 @@ export default class Unit {
|
||||
this.provider.pollingInterval = 1000;
|
||||
|
||||
this.blockchainService = new BlockchainService(this.config.services.blockchainService.http, this.config.basicAuth);
|
||||
this.integrator = new IntegratorService(this.config.services.integrator.api, intNetwork);
|
||||
this.aggregator = new Aggregator(
|
||||
this.config.services.aggregator.http,
|
||||
this.config.services.aggregator.ws,
|
||||
|
||||
@@ -177,6 +177,9 @@ describe('Orion', () => {
|
||||
priceFeed: {
|
||||
api: orionPriceFeedAPI + '/price-feed',
|
||||
},
|
||||
integrator: {
|
||||
api: '',
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,9 @@ export const pureEnvNetworksSchema = z.object({
|
||||
priceFeed: z.object({
|
||||
all: z.string(),
|
||||
}),
|
||||
integrator: z.object({
|
||||
http: z.string(),
|
||||
}),
|
||||
}),
|
||||
rpc: z.string().optional(),
|
||||
liquidityMigratorAddress: z.string().optional(),
|
||||
|
||||
1
src/services/Integrator/constants.ts
Normal file
1
src/services/Integrator/constants.ts
Normal file
@@ -0,0 +1 @@
|
||||
export const AVAILABLE_POOL_FEE = ['0.01', '0.05', '0.3', '1'] as const;
|
||||
121
src/services/Integrator/index.ts
Normal file
121
src/services/Integrator/index.ts
Normal file
@@ -0,0 +1,121 @@
|
||||
import {
|
||||
environmentResponseSchema,
|
||||
getPoolResponseSchema,
|
||||
listNFTOrderResponseSchema,
|
||||
listPoolResponseSchema,
|
||||
} from './schemas/index.js';
|
||||
import { fetchWithValidation } from 'simple-typed-fetch';
|
||||
|
||||
type BasePayload = {
|
||||
chainId: number
|
||||
jsonrpc: '1.0'
|
||||
};
|
||||
|
||||
type GetEnvironmentPayload = BasePayload & {
|
||||
model: 'Environment'
|
||||
method: 'getEnvironment'
|
||||
params: []
|
||||
};
|
||||
|
||||
type ListNFTOrderPayload = BasePayload & {
|
||||
model: 'OrionV3NFTManager'
|
||||
method: 'listNFTOrder'
|
||||
params: [string]
|
||||
};
|
||||
|
||||
type GetPoolInfoPayload = BasePayload & {
|
||||
model: 'OrionV3Factory'
|
||||
method: 'getPoolInfo'
|
||||
params: [string, string, string]
|
||||
};
|
||||
|
||||
type ListPoolPayload = BasePayload & {
|
||||
model: 'OrionFarmV3'
|
||||
method: 'listPool'
|
||||
params: [string]
|
||||
};
|
||||
|
||||
type Payload =
|
||||
| GetEnvironmentPayload
|
||||
| ListNFTOrderPayload
|
||||
| GetPoolInfoPayload
|
||||
| ListPoolPayload;
|
||||
|
||||
class IntegratorService {
|
||||
private readonly apiUrl: string;
|
||||
|
||||
private readonly chainId: number;
|
||||
|
||||
get api() {
|
||||
return this.apiUrl;
|
||||
}
|
||||
|
||||
constructor(apiUrl: string, chainId: number) {
|
||||
this.apiUrl = apiUrl;
|
||||
this.chainId = chainId;
|
||||
|
||||
this.getEnvironment = this.getEnvironment.bind(this);
|
||||
this.listNFTOrder = this.listNFTOrder.bind(this);
|
||||
this.getPoolInfo = this.getPoolInfo.bind(this);
|
||||
this.listPool = this.listPool.bind(this);
|
||||
}
|
||||
|
||||
makeRPCPayload = (payload: Omit<Payload, 'chainId' | 'jsonrpc'>) => {
|
||||
return JSON.stringify({
|
||||
...payload,
|
||||
chainId: this.chainId,
|
||||
jsonrpc: '1.0',
|
||||
});
|
||||
};
|
||||
|
||||
private readonly getEnvironment = () => {
|
||||
return fetchWithValidation(this.apiUrl, environmentResponseSchema, {
|
||||
method: 'POST',
|
||||
body: this.makeRPCPayload({
|
||||
model: 'Environment',
|
||||
method: 'getEnvironment',
|
||||
params: [],
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
private readonly listNFTOrder = (address: string) => {
|
||||
return fetchWithValidation(this.apiUrl, listNFTOrderResponseSchema, {
|
||||
method: 'POST',
|
||||
body: this.makeRPCPayload({
|
||||
model: 'OrionV3NFTManager',
|
||||
method: 'listNFTOrder',
|
||||
params: [address],
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
private readonly getPoolInfo = (
|
||||
token0: string,
|
||||
token1: string,
|
||||
poolAddress: string
|
||||
) => {
|
||||
return fetchWithValidation(this.apiUrl, getPoolResponseSchema, {
|
||||
method: 'POST',
|
||||
body: this.makeRPCPayload({
|
||||
model: 'OrionV3Factory',
|
||||
method: 'getPoolInfo',
|
||||
params: [token0, token1, poolAddress],
|
||||
}),
|
||||
});
|
||||
}
|
||||
|
||||
private readonly listPool = (address: string) => {
|
||||
return fetchWithValidation(this.apiUrl, listPoolResponseSchema, {
|
||||
method: 'POST',
|
||||
body: this.makeRPCPayload({
|
||||
model: 'OrionFarmV3',
|
||||
method: 'listPool',
|
||||
params: [address],
|
||||
}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export * as schemas from './schemas/index.js';
|
||||
export { IntegratorService };
|
||||
26
src/services/Integrator/schemas/basic-pool-info-schema.ts
Normal file
26
src/services/Integrator/schemas/basic-pool-info-schema.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { z } from 'zod';
|
||||
import { evmAddressSchema } from './util-schemas.js';
|
||||
|
||||
const basicPoolInfo = z.object({
|
||||
poolAddress: evmAddressSchema,
|
||||
isInitialized: z.boolean(),
|
||||
liquidity: z.number().nonnegative(),
|
||||
liquidityInUsd: z.number().nonnegative(),
|
||||
liquidityShare: z.number().nonnegative(),
|
||||
isFarming: z.boolean(),
|
||||
rewardsTotal: z.number().nonnegative(),
|
||||
rewardsPerPeriod: z.number().nonnegative(),
|
||||
rewardsShare: z.number().nonnegative(),
|
||||
feePerPeriod: z.number().nonnegative(),
|
||||
feeTotal: z.number().nonnegative(),
|
||||
feeShare: z.number().nonnegative(),
|
||||
tickMultiplier: z.number().nonnegative(),
|
||||
MAX_TICK: z.number().nonnegative().int(),
|
||||
minAPR: z.number().nonnegative(),
|
||||
maxAPR: z.number().nonnegative(),
|
||||
avgAPR: z.number().nonnegative(),
|
||||
maxBoost: z.number().nonnegative().int(),
|
||||
feeRate: z.array(z.number().nonnegative()),
|
||||
});
|
||||
|
||||
export default basicPoolInfo;
|
||||
@@ -0,0 +1,19 @@
|
||||
import { z } from 'zod';
|
||||
import { evmAddressSchema } from './util-schemas.js';
|
||||
import infoSchema from './info-schema.js';
|
||||
|
||||
const environmentResponseSchema = z.object({
|
||||
result: z.object({
|
||||
chainId: z.number().int().nonnegative(),
|
||||
nativeToken: z.string(),
|
||||
OrionV3Factory: evmAddressSchema,
|
||||
OrionV3NFTManager: evmAddressSchema,
|
||||
SwapRouter: evmAddressSchema,
|
||||
OrionFarmV3: evmAddressSchema,
|
||||
OrionVoting: evmAddressSchema,
|
||||
veORN: evmAddressSchema,
|
||||
}),
|
||||
info: infoSchema,
|
||||
});
|
||||
|
||||
export default environmentResponseSchema;
|
||||
21
src/services/Integrator/schemas/get-pool-response-schema.ts
Normal file
21
src/services/Integrator/schemas/get-pool-response-schema.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { z } from 'zod';
|
||||
import { evmAddressSchema } from './util-schemas.js';
|
||||
import { AVAILABLE_POOL_FEE } from '../constants.js';
|
||||
import basicPoolInfo from './basic-pool-info-schema.js';
|
||||
import infoSchema from './info-schema.js';
|
||||
|
||||
const getPoolResponseSchema = z.object({
|
||||
result: z.object({
|
||||
token0: z.string().nonempty(),
|
||||
token1: z.string().nonempty(),
|
||||
token0Address: evmAddressSchema,
|
||||
token1Address: evmAddressSchema,
|
||||
|
||||
totalLiquidity: z.number().nonnegative(),
|
||||
WETH9: evmAddressSchema,
|
||||
pools: z.record(z.enum(AVAILABLE_POOL_FEE), basicPoolInfo.nullable()),
|
||||
}),
|
||||
info: infoSchema,
|
||||
});
|
||||
|
||||
export default getPoolResponseSchema;
|
||||
4
src/services/Integrator/schemas/index.ts
Normal file
4
src/services/Integrator/schemas/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export { default as environmentResponseSchema } from './environment-response-schema.js';
|
||||
export { default as listNFTOrderResponseSchema } from './list-nft-order-response-schema.js';
|
||||
export { default as getPoolResponseSchema } from './get-pool-response-schema.js';
|
||||
export { default as listPoolResponseSchema } from './list-pool-response-schema.js';
|
||||
12
src/services/Integrator/schemas/info-schema.ts
Normal file
12
src/services/Integrator/schemas/info-schema.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import { z } from 'zod';
|
||||
import { hexStringSchema } from './util-schemas.js';
|
||||
|
||||
const infoSchema = z.object({
|
||||
blockNumber: z.number().int().nonnegative(),
|
||||
blockHash: hexStringSchema,
|
||||
timeRequest: z.number().int().nonnegative(),
|
||||
timeAnswer: z.number().int().nonnegative(),
|
||||
changes: z.number().int().nonnegative(),
|
||||
});
|
||||
|
||||
export default infoSchema;
|
||||
@@ -0,0 +1,10 @@
|
||||
import { z } from 'zod';
|
||||
import poolSchema from './pool-schema.js';
|
||||
import infoSchema from './info-schema.js';
|
||||
|
||||
const listNFTOrderResponseSchema = z.object({
|
||||
result: z.array(poolSchema),
|
||||
info: infoSchema,
|
||||
});
|
||||
|
||||
export default listNFTOrderResponseSchema;
|
||||
26
src/services/Integrator/schemas/list-pool-response-schema.ts
Normal file
26
src/services/Integrator/schemas/list-pool-response-schema.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
import { z } from 'zod';
|
||||
import { evmAddressSchema } from './util-schemas.js';
|
||||
import basicPoolInfo from './basic-pool-info-schema.js';
|
||||
import infoSchema from './info-schema.js';
|
||||
|
||||
const poolOfListPoolSchema = z.object({
|
||||
token0: z.string().nonempty(),
|
||||
token1: z.string().nonempty(),
|
||||
token0Address: evmAddressSchema,
|
||||
token1Address: evmAddressSchema,
|
||||
|
||||
token0Decimals: z.number().int().nonnegative().max(18),
|
||||
token1Decimals: z.number().int().nonnegative().max(18),
|
||||
WETH9: evmAddressSchema,
|
||||
|
||||
...basicPoolInfo.shape,
|
||||
|
||||
type: z.string().nonempty(),
|
||||
});
|
||||
|
||||
const listPoolResponseSchema = z.object({
|
||||
result: z.array(poolOfListPoolSchema),
|
||||
info: infoSchema,
|
||||
});
|
||||
|
||||
export default listPoolResponseSchema;
|
||||
33
src/services/Integrator/schemas/pool-schema.ts
Normal file
33
src/services/Integrator/schemas/pool-schema.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { z } from 'zod';
|
||||
import { evmAddressSchema } from './util-schemas.js';
|
||||
|
||||
const poolSchema = z.object({
|
||||
tokenId: evmAddressSchema,
|
||||
|
||||
token0: z.string().nonempty(),
|
||||
token1: z.string().nonempty(),
|
||||
token0Address: evmAddressSchema,
|
||||
token1Address: evmAddressSchema,
|
||||
token0Decimals: z.number().int().nonnegative().max(18),
|
||||
token1Decimals: z.number().int().nonnegative().max(18),
|
||||
|
||||
amount: z.number().nonnegative(),
|
||||
amount0: z.number().nonnegative(),
|
||||
amount1: z.number().nonnegative(),
|
||||
from: z.number().nonnegative(),
|
||||
to: z.number().nonnegative(),
|
||||
fee: z.number().nonnegative(),
|
||||
collectFee: z.number().nonnegative(),
|
||||
reward: z.number().nonnegative(),
|
||||
apr: z.number().nonnegative(),
|
||||
boost: z.number().int().nonnegative(),
|
||||
isStaked: z.boolean(),
|
||||
poolFee: z.number().nonnegative(),
|
||||
poolAddress: evmAddressSchema,
|
||||
veOrnForMaxBoost: z.number().nonnegative(),
|
||||
veOrnMaxBoost: z.number().nonnegative(),
|
||||
veORNCurrent: z.number().nonnegative(),
|
||||
time: z.number().int().nonnegative(), // tim
|
||||
});
|
||||
|
||||
export default poolSchema;
|
||||
14
src/services/Integrator/schemas/util-schemas.ts
Normal file
14
src/services/Integrator/schemas/util-schemas.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ethers } from 'ethers';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const evmAddressSchema = z
|
||||
.string()
|
||||
.refine(ethers.utils.isAddress, (v) => ({
|
||||
message: `${v} is not a valid address`,
|
||||
}));
|
||||
|
||||
export const hexStringSchema = z
|
||||
.string()
|
||||
.refine(ethers.utils.isAddress, (v) => ({
|
||||
message: `${v} is not a valid hex string`,
|
||||
}));
|
||||
@@ -252,6 +252,12 @@ export type VerboseUnitConfig = {
|
||||
// http://10.23.5.11:3003/,
|
||||
// https://price-feed:3003/
|
||||
}
|
||||
integrator: {
|
||||
api: string
|
||||
// For example:
|
||||
// http://localhost:3004/,
|
||||
// http://
|
||||
}
|
||||
}
|
||||
basicAuth?: BasicAuthCredentials
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user