@nexex/cli
Version:
162 lines • 6.84 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const api_1 = require("@nexex/api");
const command_1 = require("@oclif/command");
const chalk_1 = __importDefault(require("chalk"));
const ethers_1 = require("ethers");
const utils_1 = require("ethers/utils");
const prompts_1 = __importDefault(require("prompts"));
const constants_1 = require("../../constants");
const MarketBase_1 = __importDefault(require("../../MarketBase"));
const Token_1 = require("../../model/Token");
class MarketBuy extends MarketBase_1.default {
async run() {
const { flags } = this.parse(MarketBuy);
const { showAddr } = flags;
this.initObClient(flags);
const market = await this.getMarket(flags);
const [base, quote] = market.split('-');
const init = this.initApi();
const walletAddr = await this.readWalletAddr();
await init;
const [makerToken, takerToken] = await Promise.all([
Token_1.Token.create(quote, this.dex),
Token_1.Token.create(base, this.dex)
]);
console.log(`${chalk_1.default.bold('Buy')} ${chalk_1.default.green(takerToken.toString(showAddr))}, pay ${chalk_1.default.red(makerToken.toString(showAddr))}, with account ${walletAddr}`);
const amount = await this.getAmount(flags, base);
console.log(`${chalk_1.default.bold(`Amount of ${takerToken.toString(showAddr)} to buy`)}: ${chalk_1.default.yellow(amount)}`);
const price = await this.getPrice(flags);
console.log(`${chalk_1.default.bold('Price')}: ${chalk_1.default.yellow(price)}`);
const buyAmount = await this.dex.token.parseAmount(takerToken.addr, amount);
const payAmount = await this.dex.token.formatAmount(makerToken.addr, buyAmount.mul(utils_1.parseUnits(price, 8)).div(utils_1.parseUnits('1', 8)));
console.log(`${chalk_1.default.bold(`Amount of ${quote} to pay`)}: ${chalk_1.default.yellow(payAmount.toDisplay())}`);
const expire = await this.getExpire(flags);
const expireDate = new Date(expire * 1000);
console.log(`${chalk_1.default.bold(`Available before:`)}: ${chalk_1.default.yellow(expireDate.toLocaleString())}`);
const makerTokenBalance = await this.dex.token.balanceOf(makerToken.addr, walletAddr);
const exchangeContractAddress = this.dex.exchange.getContractAddress();
const order = {
maker: walletAddr,
taker: api_1.constants.NULL_ADDRESS,
makerFeeRecipient: constants_1.FEE_RECIPIENT,
makerTokenAddress: makerToken.addr,
takerTokenAddress: takerToken.addr,
exchangeContractAddress,
salt: api_1.Dex.generatePseudoRandomSalt(),
makerFeeRate: api_1.FeeRate.from('0.001').toString(),
takerFeeRate: api_1.FeeRate.from('0.001').toString(),
makerTokenAmount: payAmount.toString(),
takerTokenAmount: buyAmount.toString(),
expirationUnixTimestampSec: expire
};
if (makerTokenBalance.lte(payAmount)) {
console.log(chalk_1.default.red(`no enough balance, require ${quote} ${payAmount.toDisplay()}, own ${makerTokenBalance.toDisplay()}`));
this.exit(1);
}
const wallet = await this.readWallet();
const signed = await this.dex.signOrder(wallet, order);
const orderHash = api_1.orderUtil.getOrderHashHex(signed);
await this.obClient.placeOrder(signed);
console.log(`publish ${orderHash} success`);
this.exit(0);
}
async getTokenAddress(nameOrAddress) {
if (ethers_1.ethers.utils.isHexString(nameOrAddress)) {
return utils_1.getAddress(nameOrAddress);
}
return this.dex.tokenRegistry.getTokenAddressBySymbol(nameOrAddress);
}
async getAmount(flags, token) {
const { amount } = flags;
if (amount) {
return amount;
}
const response = await prompts_1.default({
type: 'text',
name: 'amount',
message: `Enter the amount of ${token} to buy? (unit: ether)`,
validate: input => {
try {
utils_1.parseEther(input);
return true;
}
catch (e) {
return 'not a valid number';
}
}
}, { onCancel: () => this.exit(1) });
return response.amount;
}
async getPrice(flags) {
const { price } = flags;
if (price) {
return price;
}
const response = await prompts_1.default({
type: 'text',
name: 'price',
message: `Enter the price (8 decimals at most):`,
validate: input => {
try {
utils_1.parseUnits(input, 8);
return true;
}
catch (e) {
return 'not a valid price';
}
}
}, { onCancel: () => this.exit(1) });
return response.price;
}
async getExpire(flags) {
let { expire } = flags;
const reg = /^(\d+)\s*(d|h|m|s)$/;
if (!expire || !reg.exec(expire)) {
const response = await prompts_1.default({
type: 'text',
name: 'expire',
message: `Enter the expire: ? [d/h/s]`,
initial: '1d',
validate: input => {
if (!reg.exec(input)) {
return 'not a valid input';
}
return true;
}
}, { onCancel: () => this.exit(1) });
expire = response.expire;
}
const [_, number, unit] = reg.exec(expire);
const now = Math.round(new Date().getTime() / 1000) + 1;
if (unit === 's') {
return now + Number(number);
}
else if (unit === 'm') {
return now + Number(number) * 60;
}
else if (unit === 'h') {
return now + Number(number) * 60 * 60;
}
else if (unit === 'd') {
return now + Number(number) * 60 * 60 * 24;
}
}
}
MarketBuy.description = 'place a buy order to a orderbook relayer';
MarketBuy.examples = [
`$ nexex-cli market:buy --amount 0.3 --price 0.11 --expire 1d
Enter the passphrase to use the wallet and sign the order.
`
];
MarketBuy.flags = {
...MarketBase_1.default.flags,
amount: command_1.flags.string(),
price: command_1.flags.string(),
expire: command_1.flags.string()
};
exports.default = MarketBuy;
//# sourceMappingURL=buy.js.map