@nexex/cli
Version:
160 lines • 6.74 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"));
class MarketSell extends MarketBase_1.default {
async run() {
const { flags } = this.parse(MarketSell);
const { config: { market } } = await this.readConfig();
const [base, quote] = market.split('-');
const obClient = this.initObClient(flags);
const init = this.initApi();
const walletAddr = await this.readWalletAddr();
console.log(`${chalk_1.default.bold('Sell')} ${chalk_1.default.green(base)}, to exchange ${chalk_1.default.red(quote)}, with account ${walletAddr}`);
const amount = await this.getAmount(flags, base);
console.log(`${chalk_1.default.bold(`Amount of ${base} to sell`)}: ${chalk_1.default.yellow(amount)}`);
const price = await this.getPrice(flags);
console.log(`${chalk_1.default.bold('Price')}: ${chalk_1.default.yellow(price)}`);
await init;
const [makerTokenAddress, takerTokenAddress] = await Promise.all([
this.getTokenAddress(base),
this.getTokenAddress(quote)
]);
const sellAmount = await this.dex.token.parseAmount(makerTokenAddress, amount);
const exchangeAmount = await this.dex.token.formatAmount(takerTokenAddress, sellAmount.mul(utils_1.parseUnits(price, 8)).div(utils_1.parseUnits('1', 8)));
console.log(`${chalk_1.default.bold(`Amount of ${quote} to exchange`)}: ${chalk_1.default.yellow(exchangeAmount.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(makerTokenAddress, walletAddr);
const exchangeContractAddress = this.dex.exchange.getContractAddress();
const order = {
maker: walletAddr,
taker: api_1.constants.NULL_ADDRESS,
makerFeeRecipient: constants_1.FEE_RECIPIENT,
makerTokenAddress,
takerTokenAddress,
exchangeContractAddress,
salt: api_1.Dex.generatePseudoRandomSalt(),
makerFeeRate: api_1.FeeRate.from('0.001').toString(),
takerFeeRate: api_1.FeeRate.from('0.001').toString(),
makerTokenAmount: sellAmount.toString(),
takerTokenAmount: exchangeAmount.toString(),
expirationUnixTimestampSec: expire
};
if (makerTokenBalance.lte(sellAmount)) {
console.log(chalk_1.default.red(`no enough balance, require ${base} ${sellAmount.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 obClient.placeOrder(signed);
console.log(`publish ${orderHash} success`);
this.exit(0);
}
async getTokenAddress(nameOrAddress) {
if (ethers_1.ethers.utils.isHexString(nameOrAddress)) {
return nameOrAddress.toLowerCase();
}
return (await this.dex.tokenRegistry.getTokenAddressBySymbol(nameOrAddress)).toLowerCase();
}
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;
}
}
}
MarketSell.description = 'place a sell order to a orderbook relayer';
MarketSell.examples = [
`$ nexex-cli market:sell --amount 0.3 --price 0.11 --expire 1d
Enter the passphrase to use the wallet and sign the order.
`
];
MarketSell.flags = {
...MarketBase_1.default.flags,
amount: command_1.flags.string(),
price: command_1.flags.string(),
expire: command_1.flags.string()
};
exports.default = MarketSell;
//# sourceMappingURL=sell.js.map