diff --git a/package-lock.json b/package-lock.json index 2428d553..f7772ccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@orionprotocol/sdk", - "version": "0.22.15", + "version": "0.22.15-rc1002", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@orionprotocol/sdk", - "version": "0.22.15", + "version": "0.22.15-rc1002", "hasInstallScript": true, "license": "ISC", "dependencies": { @@ -27,7 +27,7 @@ "merge-anything": "^5.1.7", "neverthrow": "^6.0.0", "patch-package": "^8.0.0", - "simple-typed-fetch": "0.2.3", + "simple-typed-fetch": "0.2.5", "stream-browserify": "^3.0.0", "tiny-invariant": "^1.3.1", "ts-is-present": "^1.2.2", @@ -10399,9 +10399,9 @@ "dev": true }, "node_modules/simple-typed-fetch": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.3.tgz", - "integrity": "sha512-EXP2mVVsVf4A3+5QGevs8789ztnT6FozsYyMrIrUYhfqtX2V+X9xETHeGXffmgv7YQ0p+GrW7N+5x+b+pBW59Q==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.5.tgz", + "integrity": "sha512-T/KKUHKOZgaYVp3dbjE1wEK5cAGmG5N7FNAzP6ZGqLDhzBsRm3Gpt8bO/kowV6bt8duXDWiapYFQibW/8iHp6Q==", "dependencies": { "isomorphic-unfetch": "^4.0.2", "neverthrow": "^6.0.0", @@ -19336,9 +19336,9 @@ "dev": true }, "simple-typed-fetch": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.3.tgz", - "integrity": "sha512-EXP2mVVsVf4A3+5QGevs8789ztnT6FozsYyMrIrUYhfqtX2V+X9xETHeGXffmgv7YQ0p+GrW7N+5x+b+pBW59Q==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/simple-typed-fetch/-/simple-typed-fetch-0.2.5.tgz", + "integrity": "sha512-T/KKUHKOZgaYVp3dbjE1wEK5cAGmG5N7FNAzP6ZGqLDhzBsRm3Gpt8bO/kowV6bt8duXDWiapYFQibW/8iHp6Q==", "requires": { "isomorphic-unfetch": "^4.0.2", "neverthrow": "^6.0.0", diff --git a/package.json b/package.json index a640a6c7..855ecac2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@orionprotocol/sdk", - "version": "0.22.15", + "version": "0.22.15-rc1002", "description": "Orion Protocol SDK", "main": "./lib/index.cjs", "module": "./lib/index.js", @@ -102,7 +102,7 @@ "merge-anything": "^5.1.7", "neverthrow": "^6.0.0", "patch-package": "^8.0.0", - "simple-typed-fetch": "0.2.3", + "simple-typed-fetch": "0.2.5", "stream-browserify": "^3.0.0", "tiny-invariant": "^1.3.1", "ts-is-present": "^1.2.2", diff --git a/src/Orion/index.ts b/src/Orion/index.ts index 6230d227..2da4b9e3 100644 --- a/src/Orion/index.ts +++ b/src/Orion/index.ts @@ -3,11 +3,18 @@ import { chains, envs } from '../config'; import type { networkCodes } from '../constants/index.js'; import Unit from '../Unit/index.js'; import { ReferralSystem } from '../services/ReferralSystem'; -import type { SupportedChainId, DeepPartial, VerboseUnitConfig, KnownEnv, EnvConfig, AggregatedAssets } from '../types.js'; +import type { + SupportedChainId, + DeepPartial, + VerboseUnitConfig, + KnownEnv, + EnvConfig, + AggregatedAssets +} from '../types.js'; import { isValidChainId } from '../utils/index.js'; import { simpleFetch } from 'simple-typed-fetch'; import Bridge from './bridge/index.js'; -import { Frontage } from '../services/Frontage'; +import { FrontageService } from '../services/Frontage'; export default class Orion { public readonly env?: string; @@ -16,9 +23,9 @@ export default class Orion { public readonly referralSystem: ReferralSystem; - public readonly bridge: Bridge; + public readonly frontage: FrontageService; - public readonly frontage: Frontage; + public readonly bridge: Bridge; // TODO: get tradable assets (aggregated) @@ -88,6 +95,7 @@ export default class Orion { } this.referralSystem = new ReferralSystem(config.referralAPI); + this.frontage = new FrontageService(config.frontageAPI); this.units = Object.entries(config.networks) .reduce>>((acc, [chainId, networkConfig]) => { @@ -111,8 +119,6 @@ export default class Orion { this.bridge = new Bridge( this.unitsArray, ); - - this.frontage = new Frontage(config.frontageAPI); } get unitsArray() { @@ -129,7 +135,7 @@ export default class Orion { if (!unit) { throw new Error( `Invalid network code: ${networkCodeOrChainId}. ` + - `Available network codes: ${this.unitsArray.map((u) => u.networkCode).join(', ')}`); + `Available network codes: ${this.unitsArray.map((u) => u.networkCode).join(', ')}`); } return unit; } @@ -167,7 +173,7 @@ export default class Orion { const networks = chainIds.map((chainId) => chains[chainId]?.label).join(', '); console.error( `Asset found in Aggregator, but not in BlockchainService (base): ${baseAsset} (${pair}).` + - ` Networks: ${networks}` + ` Networks: ${networks}` ); } else { tradableAggregatedAssets[baseAsset] = aggregatedBaseAsset; @@ -177,7 +183,7 @@ export default class Orion { const networks = chainIds.map((chainId) => chains[chainId]?.label).join(', '); console.error( `Asset found in Aggregator, but not in BlockchainService (quote): ${quoteAsset} (${pair}).` + - ` Networks: ${networks}` + ` Networks: ${networks}` ); } else { tradableAggregatedAssets[quoteAsset] = aggregatedQuoteAsset; @@ -189,11 +195,11 @@ export default class Orion { async getPairs(...params: Parameters) { const result: Partial< - Record< - string, - SupportedChainId[] - > - > = {}; + Record< + string, + SupportedChainId[] + > + > = {}; await Promise.all(this.unitsArray.map(async (unit) => { const pairs = await simpleFetch(unit.aggregator.getPairsList)(...params); diff --git a/src/Unit/index.ts b/src/Unit/index.ts index 7bf23745..7d837839 100644 --- a/src/Unit/index.ts +++ b/src/Unit/index.ts @@ -2,6 +2,7 @@ import { JsonRpcProvider } from 'ethers'; import { Aggregator } from '../services/Aggregator'; import { BlockchainService } from '../services/BlockchainService'; import { PriceFeed } from '../services/PriceFeed'; +import { IndexerService } from '../services/Indexer'; import type { KnownEnv, SupportedChainId, @@ -10,7 +11,6 @@ import type { import Exchange from './Exchange/index.js'; import { chains, envs } from '../config'; import type { networkCodes } from '../constants/index.js'; -import { IndexerService } from '../services/Indexer'; import Pmm from './Pmm'; type KnownConfig = { diff --git a/src/config/chains.json b/src/config/chains.json index 3b673eda..45f70282 100644 --- a/src/config/chains.json +++ b/src/config/chains.json @@ -193,5 +193,18 @@ "WETH": "0x4200000000000000000000000000000000000006", "curveRegistry": "" } + }, + "994873017": { + "chainId": "994873017", + "label": "Lumia", + "shortName": "Lumia", + "code": "lumia", + "baseCurrencyName": "LUMIA", + "rpc": "https://mainnet-rpc.lumia.org/", + "explorer": "https://explorer.lumia.org", + "contracts": { + "WETH": "", + "curveRegistry": "" + } } } diff --git a/src/config/envs.json b/src/config/envs.json index 789cb5cf..88f03621 100644 --- a/src/config/envs.json +++ b/src/config/envs.json @@ -201,6 +201,24 @@ "http": "/orion-indexer/" } } + }, + "994873017": { + "api": "https://trade.orion.xyz/lumia-mainnet", + "services": { + "aggregator": { + "http": "/backend", + "ws": "/v1" + }, + "blockchain": { + "http": "" + }, + "priceFeed": { + "all": "/price-feed" + }, + "indexer": { + "http": "/orion-indexer/" + } + } } } }, diff --git a/src/config/index.ts b/src/config/index.ts index aab5746e..d97b3667 100644 --- a/src/config/index.ts +++ b/src/config/index.ts @@ -1,6 +1,6 @@ import jsonChains from './chains.json' assert { type: 'json' }; import jsonEnvs from './envs.json' assert { type: 'json' }; -import { pureEnvSchema, pureChainInfoSchema } from './schemas/index.js'; +import { pureEnvSchema, pureChainInfoSchema } from './schemas'; const chains = pureChainInfoSchema.parse(jsonChains); const envs = pureEnvSchema.parse(jsonEnvs); diff --git a/src/constants/chains.ts b/src/constants/chains.ts index 02190479..3b03a722 100644 --- a/src/constants/chains.ts +++ b/src/constants/chains.ts @@ -18,4 +18,5 @@ export const productionChains = [ SupportedChainId.LINEA, SupportedChainId.AVAX, SupportedChainId.BASE, + SupportedChainId.LUMIA, ]; diff --git a/src/services/BlockchainService/schemas/infoSchema.ts b/src/services/BlockchainService/schemas/infoSchema.ts index 0294e8a2..fada7995 100644 --- a/src/services/BlockchainService/schemas/infoSchema.ts +++ b/src/services/BlockchainService/schemas/infoSchema.ts @@ -13,7 +13,7 @@ const infoSchema = z.object({ swapExecutorContractAddress: z.string(), libValidatorContractAddress: z.string().optional(), exchangeContractAddress: z.string(), - spvContractAddress: z.string(), + spvContractAddress: z.string().optional(), oracleContractAddress: z.string(), matcherAddress: z.string(), orderFeePercent: z.number(), diff --git a/src/services/Frontage/index.ts b/src/services/Frontage/index.ts index 1d597c83..c721a550 100644 --- a/src/services/Frontage/index.ts +++ b/src/services/Frontage/index.ts @@ -1,76 +1,20 @@ import { fetchWithValidation } from 'simple-typed-fetch'; -import { tickersSchema } from './schemas'; -import type { TickersBaseSearchParams, TickersCategories } from '../../types'; +import { aggregatedMetricsSchema } from './schemas'; -export class Frontage { +export class FrontageService { private readonly apiUrl: string; constructor(apiUrl: string) { this.apiUrl = apiUrl; - } - - searchTickers = ({ - searchValue, - currentNetwork, - targetNetwork, - sortBy, - sortType, - offset, - limit, - }: { searchValue: string } & TickersBaseSearchParams) => { - const url = new URL(this.apiUrl); - const params = new URLSearchParams(); - - params.set('searchValue', encodeURIComponent(searchValue)); - if (currentNetwork !== undefined) params.set('currentNetwork', encodeURIComponent(currentNetwork).toUpperCase()); - if (targetNetwork !== undefined) params.set('targetNetwork', encodeURIComponent(targetNetwork).toUpperCase()); - if (sortBy !== undefined) params.set('sortBy', encodeURIComponent(sortBy)); - if (sortType !== undefined) params.set('sortType', encodeURIComponent(sortType)); - if (offset !== undefined) params.set('offset', offset.toString()); - if (limit !== undefined) params.set('limit', limit.toString()); - - url.pathname += '/api/v1/tickers/search'; - url.search = params.toString(); - return fetchWithValidation( - url.toString(), - tickersSchema - ); - }; - - getTickers = ({ - category, - currentNetwork, - targetNetwork, - sortBy, - sortType, - offset, - limit, - tickers, - }: { category: TickersCategories, tickers?: string } & TickersBaseSearchParams) => { - const url = new URL(this.apiUrl); - const params = new URLSearchParams(); - - if (category === 'FAVORITES' && tickers !== undefined) params.set('tickers', tickers); - if (category !== 'FAVORITES') params.set('category', category); - if (currentNetwork !== undefined) params.set('currentNetwork', encodeURIComponent(currentNetwork).toUpperCase()); - if (targetNetwork !== undefined) params.set('targetNetwork', encodeURIComponent(targetNetwork).toUpperCase()); - if (sortBy !== undefined) params.set('sortBy', encodeURIComponent(sortBy)); - if (sortType !== undefined) params.set('sortType', encodeURIComponent(sortType)); - if (offset !== undefined) params.set('offset', offset.toString()); - if (limit !== undefined) params.set('limit', limit.toString()); - - if (category === 'FAVORITES' && tickers !== undefined) { - url.pathname += '/api/v1/tickers/get/favourites'; - } else { - url.pathname += '/api/v1/tickers/get/category'; - } - - url.search = params.toString(); + this.getAggregatedMetrics = this.getAggregatedMetrics.bind(this); + } + readonly getAggregatedMetrics = () => { + const url = new URL(`${this.apiUrl}/api/v1/metrics/aggregated`); return fetchWithValidation( url.toString(), - tickersSchema + aggregatedMetricsSchema, ); }; } diff --git a/src/services/Frontage/schemas/aggregated-metrics-schema.ts b/src/services/Frontage/schemas/aggregated-metrics-schema.ts new file mode 100644 index 00000000..e94c8eda --- /dev/null +++ b/src/services/Frontage/schemas/aggregated-metrics-schema.ts @@ -0,0 +1,29 @@ +import { z } from 'zod'; +import uppercasedNetworkCodes from '../../../constants/uppercasedNetworkCodes'; + +const volumeInfoSchema = z.object({ + volume24: z.number(), + volume7d: z.number(), + volumeAllTime: z.number(), + networks: z.array(z.enum(uppercasedNetworkCodes)), +}) + +const supplyMetricsSchema = z.object({ + circulatingSupply: z.number(), + totalSupply: z.number(), + maxSupply: z.number(), +}) + +const governanceMetricsSchema = z.object({ + totalLumiaLocked: z.number(), + totalVeLumia: z.number(), + totalVeLumiaInVoting: z.number(), + weeklyLumiaReward: z.number(), + networks: z.array(z.enum(uppercasedNetworkCodes)), +}) + +export const aggregatedMetricsSchema = z.object({ + volumeInfo: volumeInfoSchema, + supplyMetrics: supplyMetricsSchema, + governanceMetrics: governanceMetricsSchema +}); diff --git a/src/services/Frontage/schemas/error-schema.ts b/src/services/Frontage/schemas/error-schema.ts new file mode 100644 index 00000000..1163d5f3 --- /dev/null +++ b/src/services/Frontage/schemas/error-schema.ts @@ -0,0 +1,9 @@ +import { z } from 'zod'; + +export const errorSchema = z.object({ + error: z.object({ + code: z.number(), + reason: z.string(), + }), + timestamp: z.string(), +}); diff --git a/src/services/Frontage/schemas/index.ts b/src/services/Frontage/schemas/index.ts index 4611949c..e97697e9 100644 --- a/src/services/Frontage/schemas/index.ts +++ b/src/services/Frontage/schemas/index.ts @@ -1 +1 @@ -export * from './tickers-schema'; +export * from './aggregated-metrics-schema'; diff --git a/src/types.ts b/src/types.ts index 602f5932..0267700f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -92,6 +92,7 @@ export enum SupportedChainId { ARBITRUM = '42161', AVAX = '43114', LINEA = '59144', + LUMIA = '994873017', BSC_TESTNET = '97', SEPOLIA = '11155111',