Skip to content

Commit

Permalink
Merge branch 'main' into feat/oraidex-info
Browse files Browse the repository at this point in the history
  • Loading branch information
trungbach committed Aug 3, 2023
2 parents 4cedcef + 300c5fc commit 2f79a14
Show file tree
Hide file tree
Showing 7 changed files with 145 additions and 164 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,9 @@ git diff packages/contracts-sdk > patches/contracts-sdk.patch
# rollback
git checkout packages/contracts-sdk
```

## Run sample with CosmwasmSimulate

```bash
NODE_ENV=test yarn --cwd packages/market-maker start
```
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"build": "tsc -p",
"deploy": "yarn publish --access public --patch",
"start:server": "yarn build packages/oraidex-sync/ && npx ts-node packages/oraidex-server/src/index.ts"

},
"workspaces": [
"packages/*"
Expand All @@ -25,7 +24,7 @@
"@cosmjs/stargate": "^0.31.0"
},
"devDependencies": {
"@terran-one/cw-simulate": "https://github.com/oraichain/cw-simulate.git",
"@oraichain/cw-simulate": "^2.8.35",
"@types/jest": "^29.5.2",
"@types/node": "^18.15.8",
"jest": "^29.5.0",
Expand Down
77 changes: 51 additions & 26 deletions packages/market-maker/src/cli.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,28 @@
import { coin } from '@cosmjs/amino';
import { OraiswapLimitOrderClient, OraiswapTokenClient } from '@oraichain/oraidex-contracts-sdk';
import { SimulateCosmWasmClient } from '@terran-one/cw-simulate';
import 'dotenv/config';
import { MakeOrderConfig, UserWallet, decrypt, deployOrderbook, deployToken, getCoingeckoPrice, makeOrders, setupWallet, toDecimals } from './index';
// @ts-nocheck
import { coin } from "@cosmjs/amino";
import { OraiswapLimitOrderClient, OraiswapTokenClient } from "@oraichain/oraidex-contracts-sdk";
import { SimulateCosmWasmClient } from "@oraichain/cw-simulate";
import "dotenv/config";
import {
MakeOrderConfig,
UserWallet,
decrypt,
deployOrderbook,
deployToken,
getCoingeckoPrice,
makeOrders,
setupWallet,
toDecimals
} from "./index";

const cancelPercentage = Number(process.env.CANCEL_PERCENTAGE || 1); // 100% cancel
const [volumeMin, volumeMax] = process.env.VOLUME_RANGE ? process.env.VOLUME_RANGE.split(',').map(Number) : [100000, 150000];
const [volumeMin, volumeMax] = process.env.VOLUME_RANGE
? process.env.VOLUME_RANGE.split(",").map(Number)
: [100000, 150000];
const buyPercentage = Number(process.env.BUY_PERCENTAGE || 0.55);
const [spreadMin, spreadMax] = process.env.SPREAD_RANGE ? process.env.SPREAD_RANGE.split(',').map(Number) : [0.003, 0.006];
const [spreadMin, spreadMax] = process.env.SPREAD_RANGE
? process.env.SPREAD_RANGE.split(",").map(Number)
: [0.003, 0.006];

const orderConfig: MakeOrderConfig = {
cancelPercentage,
Expand All @@ -17,32 +32,34 @@ const orderConfig: MakeOrderConfig = {
spreadMax,
spreadMin
};
const [orderIntervalMin, orderIntervalMax] = process.env.ORDER_INTERVAL_RANGE ? process.env.ORDER_INTERVAL_RANGE.split(',').map(Number) : [50, 100];
const [orderIntervalMin, orderIntervalMax] = process.env.ORDER_INTERVAL_RANGE
? process.env.ORDER_INTERVAL_RANGE.split(",").map(Number)
: [50, 100];
const maxRepeat = 5;
const totalOrders = 10;

(async () => {
let buyer: UserWallet, seller: UserWallet, usdtToken: OraiswapTokenClient, orderBook: OraiswapLimitOrderClient;
// init data for test
if (process.env.NODE_ENV === 'test') {
if (process.env.NODE_ENV === "test") {
const client = new SimulateCosmWasmClient({
chainId: 'Oraichain',
bech32Prefix: 'orai'
chainId: "Oraichain",
bech32Prefix: "orai"
});
buyer = { client, address: 'orai1hz4kkphvt0smw4wd9uusuxjwkp604u7m4akyzv' };
seller = { client, address: 'orai18cgmaec32hgmd8ls8w44hjn25qzjwhannd9kpj' };
client.app.bank.setBalance(buyer.address, [coin(toDecimals(1000), 'orai')]);
client.app.bank.setBalance(seller.address, [coin(toDecimals(1000), 'orai')]);
buyer = { client, address: "orai1hz4kkphvt0smw4wd9uusuxjwkp604u7m4akyzv" };
seller = { client, address: "orai18cgmaec32hgmd8ls8w44hjn25qzjwhannd9kpj" };
client.app.bank.setBalance(buyer.address, [coin(toDecimals(1000), "orai")]);
client.app.bank.setBalance(seller.address, [coin(toDecimals(1000), "orai")]);
usdtToken = await deployToken(buyer.client, buyer.address, {
symbol: 'USDT',
name: 'USDT token'
symbol: "USDT",
name: "USDT token"
});
orderBook = await deployOrderbook(buyer.client, buyer.address);
await orderBook.createOrderBookPair({
baseCoinInfo: { native_token: { denom: 'orai' } },
baseCoinInfo: { native_token: { denom: "orai" } },
quoteCoinInfo: { token: { contract_addr: usdtToken.contractAddress } },
spread: '0.5',
minQuoteCoinAmount: '10'
spread: "0.5",
minQuoteCoinAmount: "10"
});
} else {
buyer = await setupWallet(decrypt(process.env.BUYER_MNEMONIC_PASS, process.env.BUYER_MNEMONIC_ENCRYPTED));
Expand All @@ -51,19 +68,27 @@ const totalOrders = 10;
orderBook = new OraiswapLimitOrderClient(buyer.client, buyer.address, process.env.ORDERBOOK_CONTRACT);
}

console.log('buyer address: ', buyer.address, 'seller address: ', seller.address);
console.log("buyer address: ", buyer.address, "seller address: ", seller.address);

// get price from coingecko
const oraiPrice = await getCoingeckoPrice('oraichain-token');
const oraiPrice = await getCoingeckoPrice("oraichain-token");

let processInd = 0;
while (processInd < maxRepeat) {
await makeOrders(buyer, seller, usdtToken.contractAddress, orderBook.contractAddress, oraiPrice, totalOrders, orderConfig);
await makeOrders(
buyer,
seller,
usdtToken.contractAddress,
orderBook.contractAddress,
oraiPrice,
totalOrders,
orderConfig
);

console.log('Balance after matching:');
console.log("Balance after matching:");
console.log({
buyer: await buyer.client.getBalance(buyer.address, 'orai').then((b) => b.amount + 'orai'),
seller: await usdtToken.balance({ address: seller.address }).then((b) => b.balance + 'usdt')
buyer: await buyer.client.getBalance(buyer.address, "orai").then((b) => b.amount + "orai"),
seller: await usdtToken.balance({ address: seller.address }).then((b) => b.balance + "usdt")
});

// waiting for interval then re call again
Expand Down
129 changes: 39 additions & 90 deletions packages/market-maker/src/common.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import {
ExecuteInstruction,
SigningCosmWasmClient,
} from "@cosmjs/cosmwasm-stargate";
import { ExecuteInstruction, SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
import { stringToPath } from "@cosmjs/crypto";
import { DirectSecp256k1HdWallet } from "@cosmjs/proto-signing";
import { GasPrice } from "@cosmjs/stargate";
Expand All @@ -12,17 +9,15 @@ import {
Cw20Coin,
OraiswapLimitOrderClient,
OraiswapLimitOrderTypes,
OraiswapTokenClient,
OraiswapTokenClient
} from "@oraichain/oraidex-contracts-sdk";
import crypto from "crypto";

export const encrypt = (password: string, val: string) => {
const hashedPassword = crypto.createHash("sha256").update(password).digest();
const IV = crypto.randomBytes(16);
const cipher = crypto.createCipheriv("aes-256-cbc", hashedPassword, IV);
return Buffer.concat([IV, cipher.update(val), cipher.final()]).toString(
"base64"
);
return Buffer.concat([IV, cipher.update(val), cipher.final()]).toString("base64");
};

export const decrypt = (password: string, val: string) => {
Expand All @@ -31,10 +26,7 @@ export const decrypt = (password: string, val: string) => {
const IV = encryptedText.subarray(0, 16);
const encrypted = encryptedText.subarray(16);
const decipher = crypto.createDecipheriv("aes-256-cbc", hashedPassword, IV);
return Buffer.concat([
decipher.update(encrypted),
decipher.final(),
]).toString();
return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString();
};

export type UserWallet = { address: string; client: SigningCosmWasmClient };
Expand All @@ -46,18 +38,13 @@ export async function setupWallet(mnemonic: string): Promise<UserWallet> {
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, {
hdPaths: [stringToPath(process.env.HD_PATH || "m/44'/118'/0'/0/0")],
prefix,
prefix
});
const [firstAccount] = await wallet.getAccounts();
const address = firstAccount.address;
const client = await SigningCosmWasmClient.connectWithSigner(
process.env.RPC_URL!,
wallet,
{
gasPrice: GasPrice.fromString("0.002orai"),
prefix,
}
);
const client = await SigningCosmWasmClient.connectWithSigner(process.env.RPC_URL!, wallet, {
gasPrice: GasPrice.fromString("0.002orai")
});

return { address, client };
}
Expand All @@ -66,12 +53,10 @@ export const getRandomRange = (min: number, max: number): number => {
return ((Math.random() * (max - min + 1)) << 0) + min;
};

export const getCoingeckoPrice = async (
token: "oraichain-token" | "airight"
): Promise<number> => {
const res = await fetch(
`https://price.market.orai.io/simple/price?ids=${token}&vs_currencies=usd`
).then((res) => res.json());
export const getCoingeckoPrice = async (token: "oraichain-token" | "airight"): Promise<number> => {
const res = await fetch(`https://price.market.orai.io/simple/price?ids=${token}&vs_currencies=usd`).then((res) =>
res.json()
);
return res[token].usd;
};

Expand All @@ -91,42 +76,25 @@ export const toDecimals = (num: number, decimals: number = 9): string => {
// decimals always >= 6
export const toAmount = (amount: number, decimals = 6): bigint => {
const validatedAmount = validateNumber(amount);
return (
BigInt(Math.trunc(validatedAmount * atomic)) *
BigInt(10 ** (decimals - truncDecimals))
);
return BigInt(Math.trunc(validatedAmount * atomic)) * BigInt(10 ** (decimals - truncDecimals));
};

export const toDisplay = (
amount: string | bigint,
sourceDecimals = 6,
desDecimals = 6
): number => {
export const toDisplay = (amount: string | bigint, sourceDecimals = 6, desDecimals = 6): number => {
if (!amount) return 0;
if (typeof amount === "string" && amount.indexOf(".") !== -1)
amount = amount.split(".")[0];
if (typeof amount === "string" && amount.indexOf(".") !== -1) amount = amount.split(".")[0];
try {
// guarding conditions to prevent crashing
const validatedAmount =
typeof amount === "string" ? BigInt(amount || "0") : amount;
const validatedAmount = typeof amount === "string" ? BigInt(amount || "0") : amount;
const displayDecimals = Math.min(truncDecimals, desDecimals);
const returnAmount =
validatedAmount / BigInt(10 ** (sourceDecimals - displayDecimals));
const returnAmount = validatedAmount / BigInt(10 ** (sourceDecimals - displayDecimals));
// save calculation by using cached atomic
return (
Number(returnAmount) /
(displayDecimals === truncDecimals ? atomic : 10 ** displayDecimals)
);
return Number(returnAmount) / (displayDecimals === truncDecimals ? atomic : 10 ** displayDecimals);
} catch {
return 0;
}
};

export const getSpreadPrice = (
price: number,
spreadDecimal: number,
desDecimals = 6
) => {
export const getSpreadPrice = (price: number, spreadDecimal: number, desDecimals = 6) => {
return Number((price * (1 + spreadDecimal)).toFixed(desDecimals));
};

Expand All @@ -145,7 +113,7 @@ export const deployToken = async (
symbol,
name,
decimals = 6,
initial_balances = [],
initial_balances = []
}: {
symbol: string;
name: string;
Expand All @@ -157,22 +125,13 @@ export const deployToken = async (
client,
senderAddress,
(
await deployContract(
client,
senderAddress,
{
decimals,
symbol,
name,
mint: { minter: senderAddress },
initial_balances: [
{ address: senderAddress, amount: "1000000000" },
...initial_balances,
],
},
"oraiswap_token",
"oraiswap_token"
)
await deployContract(client, senderAddress, {
decimals,
symbol,
name,
mint: { minter: senderAddress },
initial_balances: [{ address: senderAddress, amount: "1000000000" }, ...initial_balances]
}, "oraiswap_token")
).contractAddress
);
};
Expand All @@ -185,17 +144,11 @@ export const deployOrderbook = async (
client,
senderAddress,
(
await deployContract(
client,
senderAddress,
{
admin: senderAddress,
version: "0.0.1",
name: "Orderbook",
},
"oraiswap_limit_order",
"oraiswap_limit_order"
)
await deployContract(client, senderAddress, {
admin: senderAddress,
version: "0.0.1",
name: "Orderbook"
},"oraiswap_limit_order")
).contractAddress
);
};
Expand All @@ -212,9 +165,9 @@ export const cancelOrder = async (
order_by: 1,
limit,
filter: {
bidder: sender.address,
},
},
bidder: sender.address
}
}
} as OraiswapLimitOrderTypes.QueryMsg);

const multipleCancelMsg: ExecuteInstruction[] = [];
Expand All @@ -224,18 +177,14 @@ export const cancelOrder = async (
msg: {
cancel_order: {
asset_infos: assetInfos,
order_id: order.order_id,
},
},
order_id: order.order_id
}
}
};
multipleCancelMsg.push(cancelMsg);
}
if (multipleCancelMsg.length > 0) {
const cancelResult = await sender.client.executeMultiple(
sender.address,
multipleCancelMsg,
"auto"
);
const cancelResult = await sender.client.executeMultiple(sender.address, multipleCancelMsg, "auto");
console.log("cancel orders - txHash:", cancelResult.transactionHash);
}
};
6 changes: 0 additions & 6 deletions packages/market-maker/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@
"declaration": true,
"rootDir": "src"
},
"ts-node": {
"esm": true,
"ignore": [
"node_modules/(?!@terran-one)"
]
},
"include": [
"src/**/*.ts"
],
Expand Down
1 change: 0 additions & 1 deletion packages/matching-relayer/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const mnemonicMinLength = 12; // 12 words
wallet,
{
gasPrice: GasPrice.fromString("0.002orai"),
prefix,
}
);

Expand Down
Loading

0 comments on commit 2f79a14

Please sign in to comment.