Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat/ Oraichain mainnet and OraiDEX CLOB Spot #324

Open
wants to merge 24 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c27ff21
chore: add wbnb is middleware in route trade
trung2891 Jan 23, 2024
de05e44
chore: add orai token on bsc
trung2891 Jan 23, 2024
4730a8c
chore: add oraichain config
trung2891 Jan 23, 2024
34c4fed
feat: add oraichain to chainlist
trung2891 Jan 24, 2024
a7b5647
feat: impl CLOBish for Oraidex
trung2891 Jan 24, 2024
9c8fd50
chore: add getTokens() & markets() on Oraichain
trung2891 Jan 25, 2024
004485d
feat: impl function of CLOBish
trung2891 Jan 29, 2024
0595db1
feat: add oraichain into wallet router
trung2891 Jan 29, 2024
82d7a3d
feat: create & delete order
trung2891 Jan 30, 2024
c2bfafc
feat: impl controller for oraichain
trung2891 Jan 30, 2024
4024150
fix: get tokens balance on Oraichain
trung2891 Jan 30, 2024
f007c4e
feat: execute batch orders
trung2891 Jan 31, 2024
63c17ca
feat: add trading rule
trung2891 Feb 4, 2024
bb63551
(update) get market info from contracts
vuonghuuhung May 10, 2024
d0a7238
(update) get decimal from token info & get all orders when order id i…
vuonghuuhung May 13, 2024
8ec783c
(add) gas limit and gas price
vuonghuuhung May 13, 2024
cc794ae
(update+add) get all orderbook & add xoch token
vuonghuuhung May 17, 2024
9bc766c
(update) init signing client when start
vuonghuuhung May 17, 2024
47168ff
(fix) check path exist to init signer
vuonghuuhung May 19, 2024
b64b8da
(add) test case for oraichain
vuonghuuhung May 20, 2024
430898d
(add) test case for oraidex
vuonghuuhung May 21, 2024
bed574c
(update) follow cosmos base class
vuonghuuhung May 21, 2024
0513a44
(update) set back node version in dockerfile
vuonghuuhung May 21, 2024
068130c
(update) lint
vuonghuuhung May 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,4 @@ RUN yarn build
EXPOSE 15888

# Set the default command to run when starting the container
CMD yarn run start
CMD yarn run start
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@
"@osmonauts/math": "^1.11.3",
"@pancakeswap/sdk": "^4.0.0",
"@pancakeswap/smart-router": "^4.2.1",
"@oraichain/common-contracts-sdk": "^1.0.31",
"@oraichain/oraidex-common": "^1.0.86",
"@oraichain/oraidex-contracts-sdk": "^1.0.31",
"@pancakeswap/swap-sdk-core": "^1.0.0",
"@pancakeswap/tokens": "^0.1.6",
"@pancakeswap/v3-core": "^1.0.2",
Expand Down
9 changes: 4 additions & 5 deletions src/chains/cosmos/cosmos-base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ export class CosmosBase {
if (this.chainName == 'osmosis'){
this._provider = await createRPCQueryClient({rpcEndpoint: this.rpcUrl});
await this.getLatestBasePrice();
}else{
} else {
this._provider = StargateClient.connect(this.rpcUrl);
}
// If we're not ready, this._initialized will be a Promise that resolves after init() completes
this._initialized = (async () => {
try {
await this.loadTokens(this.tokenListSource, this.tokenListType)
await this.loadTokens(this.tokenListSource, this.tokenListType);
return true;
} catch (e) {
logger.error(`Failed to initialize ${this.chainName} chain: ${e}`);
Expand Down Expand Up @@ -421,7 +421,8 @@ export class CosmosBase {
}

getTokenDecimals(token: any): number {
return token ? token.denom_units[token.denom_units.length - 1].exponent : 6; // Last denom unit has the decimal amount we need from our list
return token ? token.decimals : 6;
// return token ? token.denom_units[token.denom_units.length - 1].exponent : 6; // Last denom unit has the decimal amount we need from our list
}

async getBalances(wallet: CosmosWallet): Promise<Record<string, CosmosTokenValue>> {
Expand All @@ -447,10 +448,8 @@ export class CosmosBase {
const { denomTrace } = await setupIbcExtension(
await provider.queryClient
).ibc.transfer.denomTrace(ibcHash);

if (denomTrace) {
const { baseDenom } = denomTrace;

token = this.getTokenByBase(baseDenom);
}
}
Expand Down
53 changes: 53 additions & 0 deletions src/chains/oraichain/oraichain.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { TokenListType } from '../../services/base';
import { ConfigManagerV2 } from '../../services/config-manager-v2';
export interface NetworkConfig {
name: string;
rpcURL: string;
tokenListType: TokenListType;
tokenListSource: string;
marketListType: string;
marketListSource: string;
}

export interface Config {
network: NetworkConfig;
nativeCurrencySymbol: string;
manualGasPrice: number;
gasLimit: number;
}

export namespace OraichainConfig {
export const config: Config = getOraichainConfig('oraichain', 'mainnet');
}

export function getOraichainConfig(
chainName: string,
networkName: string
): Config {
const configManager = ConfigManagerV2.getInstance();
return {
network: {
name: networkName,
rpcURL: configManager.get(
chainName + '.networks.' + networkName + '.nodeURL'
),
tokenListType: configManager.get(
chainName + '.networks.' + networkName + '.tokenListType'
),
tokenListSource: configManager.get(
chainName + '.networks.' + networkName + '.tokenListSource'
),
marketListType: configManager.get(
chainName + '.networks.' + networkName + '.marketListType'
),
marketListSource: configManager.get(
chainName + '.networks.' + networkName + '.marketListSource'
),
},
nativeCurrencySymbol: configManager.get(
chainName + '.nativeCurrencySymbol'
),
manualGasPrice: configManager.get(chainName + '.manualGasPrice'),
gasLimit: configManager.get(chainName + '.gasLimit'),
};
}
172 changes: 172 additions & 0 deletions src/chains/oraichain/oraichain.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
import { TokensRequest } from '../../network/network.requests';
import { TokenInfo, TokenValue, tokenValueToString } from '../../services/base';
import { Oraichain } from './oraichain';
import { validateGetTokensRequest } from './oraichain.validators';
import {
validateCosmosBalanceRequest,
validateCosmosPollRequest,
} from '../cosmos/cosmos.validators';
import {
CosmosBalanceRequest,
CosmosPollRequest,
} from '../cosmos/cosmos.requests';
import {
HttpException,
TOKEN_NOT_SUPPORTED_ERROR_CODE,
TOKEN_NOT_SUPPORTED_ERROR_MESSAGE,
} from '../../services/error-handler';
import { decodeTxRaw } from '@cosmjs/proto-signing';
import { BigNumber } from 'ethers';

export interface Token {
base: string;
address: string;
name: string;
symbol: string;
decimals: number;
}

export const toOraichainBalances = (
balances: Record<string, TokenValue>,
tokenSymbols: Array<string>
): Record<string, string> => {
const walletBalances: Record<string, string> = {};

tokenSymbols.forEach((symbol) => {
let balance = '0.0';
if (balances[symbol]) {
balance = tokenValueToString(balances[symbol]);
}

walletBalances[symbol] = balance;
});

return walletBalances;
};

export class OraichainController {
static async getTokens(
oraichainLish: Oraichain,
req: TokensRequest
): Promise<{ tokens: TokenInfo[] }> {
validateGetTokensRequest(req);

let tokens: Token[] = [];
if (!req.tokenSymbols) {
tokens = oraichainLish.storedTokenList;
} else {
for (const t of req.tokenSymbols as []) {
const token = oraichainLish.getTokenForSymbol(t);
if (token != undefined) {
tokens.push(token);
}
}
}

// convert token into TokenINfo
const tokensInfo: TokenInfo[] = [];
tokens.map((token) => {
const tokenInfo: TokenInfo = {
address: token.base,
chainId: 0,
decimals: token.decimals,
name: token.name,
symbol: token.symbol,
};
tokensInfo.push(tokenInfo);
});

return { tokens: tokensInfo };
}

static async balances(cosmosish: Oraichain, req: CosmosBalanceRequest) {
validateCosmosBalanceRequest(req);

const { tokenSymbols } = req;

let cw20Tokens: Token[] = [];

tokenSymbols.forEach((symbol: string) => {
const token = cosmosish.getTokenForSymbol(symbol);

if (!token) {
throw new HttpException(
500,
TOKEN_NOT_SUPPORTED_ERROR_MESSAGE + symbol,
TOKEN_NOT_SUPPORTED_ERROR_CODE
);
} else {
if (token.base != 'orai' && !token.base.startsWith('ibc/')) {
cw20Tokens.push(token);
}
}
});

const cw20Balances = await this.getTokensBalance(
cosmosish,
req.address,
cw20Tokens
);
const denomBalances = await cosmosish.getBalance(req.address);
const filteredBalances = toOraichainBalances(
{ ...denomBalances, ...cw20Balances },
tokenSymbols
);

return {
balances: filteredBalances,
};
}

static async getTokensBalance(
cosmosish: Oraichain,
address: string,
tokens: Token[]
): Promise<Record<string, TokenValue>> {
const balances: Record<string, TokenValue> = {};

await Promise.all(
tokens.map(async (token: Token) => {
try {
let balance = await cosmosish.queryContractSmart(token.base, {
balance: {
address,
},
});
balances[token.symbol] = {
value: BigNumber.from(parseInt(balance.balance, 10)),
decimals: cosmosish.getTokenDecimals(token),
};
} catch (err) {
balances[token.symbol] = {
value: BigNumber.from(parseInt('0', 10)),
decimals: cosmosish.getTokenDecimals(token),
};
}
})
);

return balances;
}

static async poll(cosmos: Oraichain, req: CosmosPollRequest) {
validateCosmosPollRequest(req);

if (req.txHash == undefined) {
throw new HttpException(500, 'txHash is required');
}

const transaction = await cosmos.getTransaction(req.txHash);
const currentBlock = await cosmos.getCurrentBlockNumber();

return {
txHash: req.txHash,
currentBlock,
txBlock: transaction.height,
gasUsed: transaction.gasUsed,
gasWanted: transaction.gasWanted,
txData: decodeTxRaw(transaction.tx),
events: transaction.events,
};
}
}
Loading