mirror of
https://github.com/orionprotocol/sdk.git
synced 2026-03-14 06:02:36 +03:00
removed crypto-js dependency
This commit is contained in:
@@ -26,7 +26,7 @@ const orion = new Orion({
|
||||
|
||||
// Also you can set some config as default and override it for some params
|
||||
const orion = new Orion("testing", {
|
||||
analyticsAPI: "https://asdasd.orionprotocol.io",
|
||||
analyticsAPI: "https://analytics-api.orionprotocol.io",
|
||||
networks: {
|
||||
[SupportedChainId.BSC_TESTNET]: {
|
||||
nodeJsonRpc: "https://data-seed-prebsc-1-s1.binance.org:8545/",
|
||||
|
||||
76
README.md
76
README.md
@@ -1,12 +1,8 @@
|
||||
<!-- Insert logo -->
|
||||
[//]: # ( <img src="./logo.svg" width="300" alt="Orion Protocol SDK logo"/>)
|
||||
|
||||
<div align="center">
|
||||
<img
|
||||
src="./logo.svg"
|
||||
width="300"
|
||||
alt="Orion Protocol SDK logo"
|
||||
/>
|
||||
<h1>Orion Protocol SDK</h1>
|
||||
<h1>Lumia Stream SDK</h1>
|
||||
<p>Use CEX and DEX liquidity without KYC.</p>
|
||||
</div>
|
||||
|
||||
@@ -14,16 +10,15 @@
|
||||

|
||||
[](https://www.npmjs.com/package/@orionprotocol/sdk)
|
||||
|
||||
Do you want to integrate the Orion protocol into your application? See [integration guide](./docs/INTEGRATION.md)
|
||||
Do you want to integrate the Lumia Stream protocol into your application? See [integration guide](./docs/INTEGRATION.md)
|
||||
|
||||
## Overview
|
||||
|
||||
Orion Software Developer Kit is a set of functions and methods that allow dApp developers connect to the superior aggregated liquidity of Orion Protocol which combines orderbooks of centralized exchanges as well decentralized automatic market makers such as Uniswap or Spookyswap across several supported blockchains.
|
||||
Through this connection, developers using the SDK can perform a wide range of actions, including swapping selected tokens using Orion’s aggregated liquidity, obtaining relevant market information through subscriptions, add and remove liquidity to Orion’s pools.
|
||||
Lumia Stream Developer Kit, natively built into Lumia, is a set of functions and methods that allow dApp developers to connect to the superior aggregated liquidity of Lumia Stream which combines orderbooks of centralized exchanges as well as decentralized Automatic Market Makers (AMMs) such as Uniswap, PancakeSwap, and Curve, across several supported blockchains. Through this connection, developers using the SDK can perform a wide range of actions, including swapping selected tokens, obtaining relevant market information through subscriptions, and more.
|
||||
|
||||
## API Key
|
||||
|
||||
Orion’s SDK is free to use and does not require an API key or registration. Refer to integration examples for more detailed information.
|
||||
Lumia Stream’s SDK is free to use and does not require an API key or registration. Refer to integration examples for more detailed information.
|
||||
|
||||
- [Overview](#overview)
|
||||
- [API Key](#api-key)
|
||||
@@ -33,7 +28,7 @@ Orion’s SDK is free to use and does not require an API key or registration. Re
|
||||
- [High level methods](#high-level-methods)
|
||||
- [Get assets](#get-assets)
|
||||
- [Get pairs](#get-pairs)
|
||||
- [Get Orion Bridge history](#get-orion-bridge-history)
|
||||
- [Get Lumia Stream Bridge history](#get-lumia-stream-bridge-history)
|
||||
- [Bridge swap](#bridge-swap)
|
||||
- [Withdraw](#withdraw)
|
||||
- [Deposit](#deposit)
|
||||
@@ -145,7 +140,7 @@ const pairs = await orion.getPairs("spot"); // 'spot'
|
||||
// }
|
||||
```
|
||||
|
||||
### Get Orion Bridge history
|
||||
### Get Lumia Stream Bridge history
|
||||
|
||||
```ts
|
||||
const bridgeHistory = await orion.bridge.getHistory(
|
||||
@@ -722,7 +717,7 @@ switch (data.type) {
|
||||
```
|
||||
## PMM
|
||||
|
||||
PMM allows institutional traders to request RFQ orders from Orion and then fill them.
|
||||
PMM allows institutional traders to request RFQ orders from Lumia Stream and then fill them.
|
||||
|
||||
RFQ order allows trader to fix the price for a certain time interval (up to 90 seconds, including the order settlement time interval on blockchain).
|
||||
|
||||
@@ -735,56 +730,63 @@ Please take look at code example below.
|
||||
Simple example:
|
||||
|
||||
```ts
|
||||
import Orion from '../Orion';
|
||||
// Node.js
|
||||
|
||||
import { Orion } from '@orionprotocol/sdk'
|
||||
import {Wallet} from "ethers";
|
||||
import {simpleFetch} from "simple-typed-fetch";
|
||||
|
||||
(async() => {
|
||||
const apiKey = '958153f1-b8b9-3ec4-84eb-2147429105d9';
|
||||
const secretKey = 'secretKey';
|
||||
const yourWalletPrivateKey = '0x...';
|
||||
|
||||
|
||||
const orion = new Orion('testing'); // Leave empty for PROD environment
|
||||
const bsc = orion.getUnit('bsc');
|
||||
const wallet = new Wallet(yourWalletPrivateKey, bsc.provider);
|
||||
|
||||
|
||||
// This can be done only once, no need to repeat this every time
|
||||
// assetToDecimals can also be useful for calculations
|
||||
const {assetToAddress, assetToDecimals} = await simpleFetch(bsc.blockchainService.getInfo)();
|
||||
|
||||
// assetToDecimals can also be useful for calculations
|
||||
// const {assetToAddress, assetToDecimals} = await bsc.blockchainService.getInfo();
|
||||
const info = await bsc.blockchainService.getInfo();
|
||||
|
||||
if(!info.isOk())
|
||||
return;
|
||||
|
||||
const {assetToAddress, assetToDecimals} = info.value.data;
|
||||
|
||||
// Also you need to allow FRQ contract to spend tokens from your address.
|
||||
// This also can be done only once.
|
||||
await bsc.pmm.setAllowance(assetToAddress.ORN, '1000000000000000000', wallet);
|
||||
|
||||
|
||||
// Just output the PMM router contract address
|
||||
console.log('Router contract address: ', await bsc.pmm.getContractAddress());
|
||||
|
||||
const rfqOrder = await bsc.aggregator.RFQOrder(
|
||||
assetToAddress.ORN, // Spending asset
|
||||
assetToAddress.USDT, // Receiving asset
|
||||
'10000000000', // Amount in "satoshi" of spending asset
|
||||
apiKey,
|
||||
secretKey,
|
||||
'0x61Eed69c0d112C690fD6f44bB621357B89fBE67F' // Can be any address, ignored for now
|
||||
assetToAddress.ORN, // Spending asset
|
||||
assetToAddress.USDT, // Receiving asset
|
||||
'1000000000', // Amount in "satoshi" of spending asset
|
||||
apiKey,
|
||||
secretKey,
|
||||
'0x61Eed69c0d112C690fD6f44bB621357B89fBE67F' // Can be any address, ignored for now
|
||||
);
|
||||
|
||||
|
||||
if(!rfqOrder.success) {
|
||||
console.log(rfqOrder.error);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// ... here you can check order prices, etc.
|
||||
|
||||
|
||||
// Send order to blockchain
|
||||
try {
|
||||
const tx = await bsc.pmm.fillRFQOrder(rfqOrder, wallet);
|
||||
|
||||
// If tx.hash is not empty - then transaction was sent to blockchain
|
||||
console.log(tx.hash);
|
||||
const tx = await bsc.pmm.fillRFQOrder(rfqOrder, wallet);
|
||||
|
||||
// If tx.hash is not empty - then transaction was sent to blockchain
|
||||
console.log(tx.hash);
|
||||
}
|
||||
catch(err) {
|
||||
console.log(err);
|
||||
}
|
||||
console.log(err);
|
||||
}
|
||||
})();
|
||||
```
|
||||
|
||||
@@ -814,4 +816,4 @@ RFQ order response example description (`rfqOrder` from example above):
|
||||
* maker - can be ignored for now;
|
||||
* allowedSender - can be ignored for now;
|
||||
* makingAmount - how much you will RECEIVE (in receiving asset's precision)
|
||||
* takingAmount - how much you should SPEND (in spending asset's precision)
|
||||
* takingAmount - how much you should SPEND (in spending asset's precision)
|
||||
|
||||
18
package-lock.json
generated
18
package-lock.json
generated
@@ -1,19 +1,19 @@
|
||||
{
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.20.66-rc2",
|
||||
"version": "0.20.79",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@orionprotocol/sdk",
|
||||
"version": "0.20.66-rc2",
|
||||
"version": "0.20.79",
|
||||
"hasInstallScript": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@orionprotocol/contracts": "1.22.10",
|
||||
"@orionprotocol/contracts": "1.23.3",
|
||||
"@types/lodash.clonedeep": "^4.5.9",
|
||||
"bignumber.js": "^9.1.1",
|
||||
"bson-objectid": "^2.0.4",
|
||||
@@ -2423,9 +2423,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@orionprotocol/contracts": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.10.tgz",
|
||||
"integrity": "sha512-c9cUkXs1Nv8p+EVTybwJqeXhecwm7xeycAVauhl6jYAqvKOx7PDCUjzE3Nh0tpi4xP3CLeABgNy8JAFYyvN1VA=="
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.23.3.tgz",
|
||||
"integrity": "sha512-3PBnuiUe//v7COArcm/dzFx71vxW+a9emU4PHi1zBdow+OUAa4WNb+NmNZ3AOjnx2AZKK+gWJY+zKo1zSfAOHQ=="
|
||||
},
|
||||
"node_modules/@sinclair/typebox": {
|
||||
"version": "0.27.8",
|
||||
@@ -13493,9 +13493,9 @@
|
||||
}
|
||||
},
|
||||
"@orionprotocol/contracts": {
|
||||
"version": "1.22.10",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.22.10.tgz",
|
||||
"integrity": "sha512-c9cUkXs1Nv8p+EVTybwJqeXhecwm7xeycAVauhl6jYAqvKOx7PDCUjzE3Nh0tpi4xP3CLeABgNy8JAFYyvN1VA=="
|
||||
"version": "1.23.3",
|
||||
"resolved": "https://registry.npmjs.org/@orionprotocol/contracts/-/contracts-1.23.3.tgz",
|
||||
"integrity": "sha512-3PBnuiUe//v7COArcm/dzFx71vxW+a9emU4PHi1zBdow+OUAa4WNb+NmNZ3AOjnx2AZKK+gWJY+zKo1zSfAOHQ=="
|
||||
},
|
||||
"@sinclair/typebox": {
|
||||
"version": "0.27.8",
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
"@babel/plugin-syntax-import-assertions": "^7.20.0",
|
||||
"@tsconfig/esm": "^1.0.4",
|
||||
"@tsconfig/strictest": "^2.0.1",
|
||||
"@types/crypto-js": "^4.2.2",
|
||||
"@types/express": "^4.17.17",
|
||||
"@types/jest": "^29.5.1",
|
||||
"@types/node": "^20.5.1",
|
||||
@@ -89,7 +88,7 @@
|
||||
"@babel/runtime": "^7.21.0",
|
||||
"@ethersproject/abstract-signer": "^5.7.0",
|
||||
"@ethersproject/providers": "^5.7.2",
|
||||
"@orionprotocol/contracts": "1.22.10",
|
||||
"@orionprotocol/contracts": "1.23.3",
|
||||
"@types/lodash.clonedeep": "^4.5.9",
|
||||
"bignumber.js": "^9.1.1",
|
||||
"bson-objectid": "^2.0.4",
|
||||
|
||||
@@ -21,10 +21,15 @@ export default class Orion {
|
||||
|
||||
// TODO: get tradable pairs (aggregated)
|
||||
|
||||
public logger: ((message: string) => void) | undefined;
|
||||
|
||||
constructor(
|
||||
envOrConfig: KnownEnv | EnvConfig = 'production',
|
||||
overrides?: DeepPartial<EnvConfig>
|
||||
overrides?: DeepPartial<EnvConfig>,
|
||||
logger?: ((message: string) => void) | undefined
|
||||
) {
|
||||
this.logger = logger;
|
||||
|
||||
let config: EnvConfig;
|
||||
if (typeof envOrConfig === 'string') {
|
||||
const envConfig = envs[envOrConfig];
|
||||
@@ -33,7 +38,7 @@ export default class Orion {
|
||||
}
|
||||
this.env = envOrConfig;
|
||||
config = {
|
||||
analyticsAPI: envConfig.analyticsAPI,
|
||||
analyticsAPI: envConfig?.analyticsAPI,
|
||||
referralAPI: envConfig.referralAPI,
|
||||
networks: Object.entries(envConfig.networks).map(([chainId, networkConfig]) => {
|
||||
if (!isValidChainId(chainId)) throw new Error(`Invalid chainId: ${chainId}`);
|
||||
@@ -92,7 +97,7 @@ export default class Orion {
|
||||
// api: networkConfig.api,
|
||||
nodeJsonRpc: networkConfig.nodeJsonRpc,
|
||||
services: networkConfig.services,
|
||||
});
|
||||
}, logger);
|
||||
return {
|
||||
...acc,
|
||||
[chainId]: unit,
|
||||
|
||||
@@ -397,7 +397,7 @@ async function shouldUseExchangeBalance(
|
||||
let useExchangeBalance = true;
|
||||
let additionalTransferAmount = 0n;
|
||||
|
||||
if (exchangeBalance == 0n) {
|
||||
if (walletBalance >= amount || exchangeBalance == 0n) {
|
||||
useExchangeBalance = false;
|
||||
additionalTransferAmount = amount;
|
||||
} else {
|
||||
|
||||
@@ -41,7 +41,10 @@ export default class Unit {
|
||||
|
||||
public readonly contracts: Record<string, string>;
|
||||
|
||||
constructor(config: KnownConfig | VerboseUnitConfig) {
|
||||
public logger: ((message: string) => void) | undefined;
|
||||
|
||||
constructor(config: KnownConfig | VerboseUnitConfig, logger?: ((message: string) => void) | undefined) {
|
||||
this.logger = logger;
|
||||
if ('env' in config) {
|
||||
const staticConfig = envs[config.env];
|
||||
if (!staticConfig) {
|
||||
@@ -118,7 +121,8 @@ export default class Unit {
|
||||
this.aggregator = new Aggregator(
|
||||
this.config.services.aggregator.http,
|
||||
this.config.services.aggregator.ws,
|
||||
this.config.basicAuth
|
||||
this.config.basicAuth,
|
||||
logger,
|
||||
);
|
||||
this.priceFeed = new PriceFeed(
|
||||
this.config.services.priceFeed.api,
|
||||
|
||||
@@ -219,5 +219,18 @@
|
||||
"WETH": "0xe5d7c2a44ffddf6b295a15c148167daaaf5cf34f",
|
||||
"curveRegistry": ""
|
||||
}
|
||||
},
|
||||
"43114": {
|
||||
"chainId": "43114",
|
||||
"label": "Avalanche Network",
|
||||
"shortName": "Avax",
|
||||
"code": "avax",
|
||||
"baseCurrencyName": "AVAX",
|
||||
"rpc": "https://api.avax.network/ext/bc/C/rpc/",
|
||||
"explorer": "https://snowtrace.io/",
|
||||
"contracts": {
|
||||
"WETH": "0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",
|
||||
"curveRegistry": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"production": {
|
||||
"analyticsAPI": "https://trade.orion.xyz/api/stats",
|
||||
"referralAPI": "https://trade.orion.xyz/referral-api",
|
||||
"networks": {
|
||||
"1": {
|
||||
@@ -165,11 +164,28 @@
|
||||
"http": "/orion-indexer/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"43114": {
|
||||
"api": "https://trade.orion.xyz/avalanche-c-chain",
|
||||
"services": {
|
||||
"aggregator": {
|
||||
"http": "/backend",
|
||||
"ws": "/v1"
|
||||
},
|
||||
"blockchain": {
|
||||
"http": ""
|
||||
},
|
||||
"priceFeed": {
|
||||
"all": "/price-feed"
|
||||
},
|
||||
"indexer": {
|
||||
"http": "/orion-indexer/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"testing": {
|
||||
"analyticsAPI": "https://trade.orion.xyz/api/stats",
|
||||
"referralAPI": "https://testing.orion.xyz/referral-api",
|
||||
"networks": {
|
||||
"97": {
|
||||
@@ -284,7 +300,6 @@
|
||||
}
|
||||
},
|
||||
"staging": {
|
||||
"analyticsAPI": "https://trade.orion.xyz/api/stats",
|
||||
"referralAPI": "https://staging.orion.xyz/referral-api",
|
||||
"networks": {
|
||||
"1": {
|
||||
@@ -448,11 +463,28 @@
|
||||
"http": "/orion-indexer/"
|
||||
}
|
||||
}
|
||||
},
|
||||
"43114": {
|
||||
"api": "https://trade.orion.xyz/avalanche-c-chain",
|
||||
"services": {
|
||||
"aggregator": {
|
||||
"http": "/backend",
|
||||
"ws": "/v1"
|
||||
},
|
||||
"blockchain": {
|
||||
"http": ""
|
||||
},
|
||||
"priceFeed": {
|
||||
"all": "/price-feed"
|
||||
},
|
||||
"indexer": {
|
||||
"http": "/orion-indexer/"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"experimental": {
|
||||
"analyticsAPI": "https://trade.orion.xyz/api/stats",
|
||||
"referralAPI": "https://testing.orion.xyz/referral-api",
|
||||
"networks": {
|
||||
"97": {
|
||||
@@ -494,7 +526,6 @@
|
||||
}
|
||||
},
|
||||
"kucoin-production": {
|
||||
"analyticsAPI": "https://trade.orion.xyz/api/stats",
|
||||
"referralAPI": "https://trade.orion.xyz/referral-api",
|
||||
"networks": {
|
||||
"1": {
|
||||
|
||||
@@ -23,7 +23,7 @@ export const pureEnvNetworksSchema = z.object({
|
||||
});
|
||||
|
||||
export const pureEnvPayloadSchema = z.object({
|
||||
analyticsAPI: z.string().url(),
|
||||
analyticsAPI: z.string().url().optional(),
|
||||
referralAPI: z.string().url(),
|
||||
networks: z.record(
|
||||
z.nativeEnum(SupportedChainId),
|
||||
|
||||
@@ -19,4 +19,5 @@ export const productionChains = [
|
||||
SupportedChainId.OPBNB,
|
||||
SupportedChainId.INEVM,
|
||||
SupportedChainId.LINEA,
|
||||
SupportedChainId.AVAX,
|
||||
];
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default ['ftm', 'bsc', 'eth', 'polygon', 'okc', 'arb', 'drip', 'opbnb', 'inevm', 'linea'] as const;
|
||||
export default ['ftm', 'bsc', 'eth', 'polygon', 'okc', 'arb', 'drip', 'opbnb', 'inevm', 'linea', 'avax'] as const;
|
||||
|
||||
@@ -1 +1 @@
|
||||
export default ['FTM', 'BSC', 'ETH', 'POLYGON', 'OKC', 'ARB', 'OPBNB', 'INEVM', 'LINEA'] as const;
|
||||
export default ['FTM', 'BSC', 'ETH', 'POLYGON', 'OKC', 'ARB', 'OPBNB', 'INEVM', 'LINEA', 'AVAX'] as const;
|
||||
|
||||
@@ -35,11 +35,16 @@ class Aggregator {
|
||||
return this.apiUrl;
|
||||
}
|
||||
|
||||
public logger: ((message: string) => void) | undefined;
|
||||
|
||||
constructor(
|
||||
httpAPIUrl: string,
|
||||
wsAPIUrl: string,
|
||||
basicAuth?: BasicAuthCredentials
|
||||
basicAuth?: BasicAuthCredentials,
|
||||
logger?: ((message: string) => void) | undefined
|
||||
) {
|
||||
this.logger = logger;
|
||||
|
||||
// const oaUrl = new URL(apiUrl);
|
||||
// const oaWsProtocol = oaUrl.protocol === 'https:' ? 'wss' : 'ws';
|
||||
// const aggregatorWsUrl = `${oaWsProtocol}://${oaUrl.host + (oaUrl.pathname === '/'
|
||||
@@ -47,7 +52,7 @@ class Aggregator {
|
||||
// : oaUrl.pathname)}/v1`;
|
||||
|
||||
this.apiUrl = httpAPIUrl;
|
||||
this.ws = new AggregatorWS(httpToWS(wsAPIUrl));
|
||||
this.ws = new AggregatorWS(httpToWS(wsAPIUrl), undefined, logger);
|
||||
this.basicAuth = basicAuth;
|
||||
|
||||
this.getHistoryAtomicSwaps = this.getHistoryAtomicSwaps.bind(this);
|
||||
@@ -374,8 +379,7 @@ class Aggregator {
|
||||
return fetchWithValidation(url.toString(), atomicSwapHistorySchema, { headers: this.basicAuthHeaders });
|
||||
};
|
||||
|
||||
|
||||
private encode_utf8(s : string) {
|
||||
private encode_utf8(s: string) {
|
||||
return unescape(encodeURIComponent(s));
|
||||
}
|
||||
|
||||
@@ -385,12 +389,12 @@ class Aggregator {
|
||||
.digest('hex');
|
||||
}
|
||||
|
||||
private generateHeaders(body : any, method : string, path : string, timestamp : number, apiKey : string, secretKey : string) {
|
||||
private generateHeaders(body: any, method: string, path: string, timestamp: number, apiKey: string, secretKey: string) {
|
||||
const sortedBody = Object.keys(body)
|
||||
.sort()
|
||||
.map((key) => (
|
||||
`${key}=${body[key]}`
|
||||
)).join('&');
|
||||
.sort()
|
||||
.map((key) => (
|
||||
`${key}=${body[key]}`
|
||||
)).join('&');
|
||||
|
||||
const payload = timestamp + method.toUpperCase() + path + sortedBody;
|
||||
|
||||
@@ -407,40 +411,38 @@ class Aggregator {
|
||||
}
|
||||
|
||||
public async RFQOrder(
|
||||
tokenFrom: string,
|
||||
tokenTo: string,
|
||||
fromTokenAmount: string,
|
||||
apiKey: string, //
|
||||
secretKey: string,
|
||||
wallet: string
|
||||
) : Promise<z.infer<typeof pmmOrderSchema>> {
|
||||
|
||||
tokenFrom: string,
|
||||
tokenTo: string,
|
||||
fromTokenAmount: string,
|
||||
apiKey: string, //
|
||||
secretKey: string,
|
||||
wallet: string
|
||||
): Promise<z.infer<typeof pmmOrderSchema>> {
|
||||
// Making the order structure
|
||||
const
|
||||
path = '/rfq'
|
||||
, url = `${this.apiUrl}/api/v1/integration/pmm`+path
|
||||
, headers = {
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
, data = {
|
||||
"baseToken":tokenFrom, // USDT
|
||||
"quoteToken":tokenTo, // ORN
|
||||
"amount": fromTokenAmount, // 100
|
||||
"taker": wallet,
|
||||
"feeBps": 0
|
||||
}
|
||||
, method = 'POST'
|
||||
, timestamp = Date.now()
|
||||
, signatureHeaders = this.generateHeaders(data, method, path, timestamp, apiKey, secretKey)
|
||||
, compiledHeaders = {...headers, ...signatureHeaders.headers, }
|
||||
, body = JSON.stringify(data)
|
||||
path = '/rfq';
|
||||
const url = `${this.apiUrl}/api/v1/integration/pmm` + path;
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
const data = {
|
||||
baseToken: tokenFrom, // USDT
|
||||
quoteToken: tokenTo, // ORN
|
||||
amount: fromTokenAmount, // 100
|
||||
taker: wallet,
|
||||
feeBps: 0
|
||||
};
|
||||
const method = 'POST';
|
||||
const timestamp = Date.now();
|
||||
const signatureHeaders = this.generateHeaders(data, method, path, timestamp, apiKey, secretKey);
|
||||
const compiledHeaders = { ...headers, ...signatureHeaders.headers, };
|
||||
const body = JSON.stringify(data)
|
||||
;
|
||||
|
||||
|
||||
let res = pmmOrderSchema.parse({});
|
||||
const res = pmmOrderSchema.parse({});
|
||||
|
||||
try {
|
||||
const result = await fetch(url,{
|
||||
const result = await fetch(url, {
|
||||
headers: compiledHeaders,
|
||||
method,
|
||||
body
|
||||
@@ -449,14 +451,13 @@ class Aggregator {
|
||||
const json = await result.json();
|
||||
const parseResult = pmmOrderSchema.safeParse(json);
|
||||
|
||||
if(!parseResult.success) {
|
||||
if (!parseResult.success) {
|
||||
// Try to parse error answer
|
||||
const errorSchema = z.object({error: z.object({code: z.number(), reason: z.string()})});
|
||||
const errorSchema = z.object({ error: z.object({ code: z.number(), reason: z.string() }) });
|
||||
|
||||
const errorParseResult = errorSchema.safeParse(json);
|
||||
|
||||
if(!errorParseResult.success)
|
||||
throw Error(`Unrecognized answer from aggregator: ${json}`);
|
||||
if (!errorParseResult.success) { throw Error(`Unrecognized answer from aggregator: ${json}`); }
|
||||
|
||||
throw Error(errorParseResult.data.error.reason);
|
||||
}
|
||||
@@ -465,8 +466,8 @@ class Aggregator {
|
||||
res.signature = parseResult.data.signature;
|
||||
res.error = '';
|
||||
res.success = true;
|
||||
}
|
||||
catch(err) {
|
||||
// return result;
|
||||
} catch (err) {
|
||||
res.error = `${err}`;
|
||||
}
|
||||
return res;
|
||||
|
||||
@@ -66,10 +66,11 @@ type PairConfigSubscription = {
|
||||
|
||||
type AggregatedOrderbookSubscription = {
|
||||
payload: string
|
||||
dc?: number
|
||||
callback: (
|
||||
asks: OrderbookItem[],
|
||||
bids: OrderbookItem[],
|
||||
pair: string
|
||||
pair: string,
|
||||
) => void
|
||||
errorCb?: (message: string) => void
|
||||
}
|
||||
@@ -195,9 +196,10 @@ class AggregatorWS {
|
||||
|
||||
readonly basicAuth?: BasicAuthCredentials | undefined;
|
||||
|
||||
constructor(wsUrl: string, basicAuth?: BasicAuthCredentials) {
|
||||
constructor(wsUrl: string, basicAuth?: BasicAuthCredentials, logger?: ((message: string) => void) | undefined) {
|
||||
this.wsUrl = wsUrl;
|
||||
this.basicAuth = basicAuth;
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
private messageQueue: BufferLike[] = [];
|
||||
@@ -252,7 +254,7 @@ class AggregatorWS {
|
||||
subscription: Subscription[T],
|
||||
prevSubscriptionId?: string
|
||||
) {
|
||||
const id = type === 'aobus'
|
||||
const id = type === SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE
|
||||
? ((subscription as any).payload as string) // TODO: Refactor!!!
|
||||
: uuidv4();
|
||||
|
||||
@@ -262,6 +264,12 @@ class AggregatorWS {
|
||||
subRequest['T'] = type;
|
||||
subRequest['id'] = id;
|
||||
|
||||
if ('dc' in subscription) {
|
||||
if (typeof subscription.dc === 'number') {
|
||||
subRequest['dc'] = subscription.dc;
|
||||
}
|
||||
}
|
||||
|
||||
if ('payload' in subscription) {
|
||||
if (typeof subscription.payload === 'string') {
|
||||
subRequest['S'] = subscription.payload;
|
||||
@@ -369,11 +377,11 @@ class AggregatorWS {
|
||||
delete this.subscriptions[SubscriptionType.ASSET_PAIR_CONFIG_UPDATES_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];
|
||||
if (aobSubscriptions) {
|
||||
const targetAobSub = Object.entries(aobSubscriptions).find(([, value]) => value?.payload === newestSubId);
|
||||
if (targetAobSub) {
|
||||
const [key] = targetAobSub;
|
||||
const aobusSubscriptions = this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE];
|
||||
if (aobusSubscriptions) {
|
||||
const targetAobusSub = Object.entries(aobusSubscriptions).find(([, value]) => value?.payload === newestSubId);
|
||||
if (targetAobusSub) {
|
||||
const [key] = targetAobusSub;
|
||||
delete this.subscriptions[SubscriptionType.AGGREGATED_ORDER_BOOK_UPDATES_SUBSCRIBE]?.[key];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ class BlockchainService {
|
||||
this.getRedeemOrderBySecretHash = this.getRedeemOrderBySecretHash.bind(this);
|
||||
this.claimOrder = this.claimOrder.bind(this);
|
||||
this.getGasLimits = this.getGasLimits.bind(this);
|
||||
this.getExchangeContractWalletBalance = this.getExchangeContractWalletBalance.bind(this);
|
||||
}
|
||||
|
||||
get basicAuthHeaders() {
|
||||
@@ -495,6 +496,12 @@ class BlockchainService {
|
||||
z.record(z.number()),
|
||||
{ headers: this.basicAuthHeaders }
|
||||
);
|
||||
|
||||
getExchangeContractWalletBalance = (exchangeContractAddress: string) => fetchWithValidation(
|
||||
`${this.apiUrl}/api/broker/getWalletBalance/${exchangeContractAddress}`,
|
||||
z.record(z.string()),
|
||||
{ headers: this.basicAuthHeaders }
|
||||
);
|
||||
}
|
||||
|
||||
export * as schemas from './schemas/index.js';
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
PoolV2InfoResponseSchema,
|
||||
testIncrementorSchema,
|
||||
veORNInfoResponseSchema,
|
||||
votingInfoResponseSchema
|
||||
votingInfoResponseSchema,
|
||||
} from './schemas';
|
||||
import { fetchWithValidation } from 'simple-typed-fetch';
|
||||
import { BigNumber } from 'bignumber.js';
|
||||
@@ -94,6 +94,7 @@ class IndexerService {
|
||||
this.veORNInfo = this.veORNInfo.bind(this);
|
||||
this.listAmount = this.listAmount.bind(this);
|
||||
this.getAmountByORN = this.getAmountByORN.bind(this);
|
||||
this.getAmountAt = this.getAmountAt.bind(this);
|
||||
this.getAmountAtCurrent = this.getAmountAtCurrent.bind(this);
|
||||
this.getVotingInfo = this.getVotingInfo.bind(this);
|
||||
}
|
||||
@@ -117,6 +118,23 @@ class IndexerService {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} amount - amount
|
||||
* @param {number} [timestamp = Date.now()] - timestamp, defaults to current time
|
||||
*/
|
||||
readonly getAmountAt = (
|
||||
amount: number,
|
||||
timestamp = Date.now()
|
||||
): BigNumber => {
|
||||
const finalTimestamp = timestamp / 1000;
|
||||
|
||||
// sqrt
|
||||
return BigNumber(amount).dividedBy(this.getK(finalTimestamp));
|
||||
};
|
||||
|
||||
/**
|
||||
* @deprecated since version 69 in favor of getAmountAt
|
||||
*/
|
||||
readonly getAmountAtCurrent = (amount: number): BigNumber => {
|
||||
const timestamp = Date.now() / 1000;
|
||||
|
||||
@@ -134,8 +152,7 @@ class IndexerService {
|
||||
const multSQRT = deltaDaysBN.dividedBy(WEEK_DAYS).sqrt();
|
||||
const multCUBE = deltaDaysBN.dividedBy(alpha).pow(3);
|
||||
|
||||
return BigNumber(amountToken)
|
||||
.multipliedBy(multSQRT.plus(multCUBE));
|
||||
return BigNumber(amountToken).multipliedBy(multSQRT.plus(multCUBE));
|
||||
};
|
||||
|
||||
readonly getVotingInfo = (userAddress?: string) => {
|
||||
@@ -208,7 +225,11 @@ class IndexerService {
|
||||
});
|
||||
};
|
||||
|
||||
readonly poolV2Info = (token0: string, token1: string, address: string | undefined) => {
|
||||
readonly poolV2Info = (
|
||||
token0: string,
|
||||
token1: string,
|
||||
address: string | undefined
|
||||
) => {
|
||||
return fetchWithValidation(this.apiUrl, PoolV2InfoResponseSchema, {
|
||||
method: 'POST',
|
||||
body: this.makeRPCPayload({
|
||||
|
||||
@@ -90,6 +90,7 @@ export enum SupportedChainId {
|
||||
OPBNB = '204',
|
||||
INEVM = '2525',
|
||||
LINEA = '59144',
|
||||
AVAX = '43114',
|
||||
|
||||
POLYGON_TESTNET = '80001',
|
||||
FANTOM_TESTNET = '4002',
|
||||
@@ -279,7 +280,7 @@ export type KnownEnv = typeof knownEnvs[number];
|
||||
export type Json = string | number | boolean | null | Json[] | { [key: string]: Json };
|
||||
|
||||
export type EnvConfig = {
|
||||
analyticsAPI: string
|
||||
analyticsAPI: string | undefined
|
||||
referralAPI: string
|
||||
networks: Partial<
|
||||
Record<
|
||||
|
||||
Reference in New Issue
Block a user