Validator Client
Getting Started
Installation
pnpm install @dydxprotocol/v4-client-js
Initializing the Client
import { ValidatorClient, Network } from "@dydxprotocol/v4-client-js";
const client = await ValidatorClient.connect(Network.testnet().validatorConfig);
Configuring a Network
import {
Network,
ValidatorClient,
IndexerConfig,
ValidatorConfig
} from '@dydxprotocol/v4-client-js';
const indexerConfig = new IndexerConfig(
{INDEXER_REST_URL},
{INDEXER_WEBSOCKET_URL}
);
const denomConfig = {
USDC_DENOM: 'ibc/8E27BA2D5493AF5636760E354E46004562C46AB7EC0CC4C1CA14E9E20E2545B5',
USDC_DECIMALS: 6,
USDC_GAS_DENOM: 'uusdc',
CHAINTOKEN_DENOM: {CHAIN_TOKEN_DENOM} //string
CHAINTOKEN_DECIMALS: {CHAIN_TOKEN_DECIMALS} //integer
};
const validatorConfig = new ValidatorConfig(
{VALIDATOR_REST_URL},
{CHAIN_ID},
denomConfig
);
const custom_network = new Network(
'custom-network-name',
indexerConfig,
validatorConfig
);
const client = await ValidatorClient.connect(
custom_network.validatorConfig
);
Creating a LocalWallet
import {
BECH32_PREFIX,
LocalWallet,
} from '@dydxprotocol/v4-client-js';
const mnemonic = 'YOUR MNEMONIC HERE';
const wallet = await LocalWallet.fromMnemonic(mnemonic, BECH32_PREFIX);
Simulate, Sign and Send Transactions
Simulate a Transaction
const messages = () => Promise.resolve([ /* ... your transaction messages here */ ]);
const fee = await client.simulate(wallet, messages);
Sign a Transaction
const messages = () => Promise.resolve([ /* ... your transaction messages here */ ]);
const zeroFee = true;
const signedTransaction = await client.sign(wallet, messages, zeroFee);
Send a Transaction
const messages = () => Promise.resolve([ /* ... your transaction messages here */ ]);
const zeroFee = true;
const signedTransaction = await client.send(wallet, messages, zeroFee);
Get Account Balances
// Get all balances for an account.
const balances = await client.get.getAccountBalances(DYDX_ADDRESS)
// Get balance of one denom for an account.
const balance = await client.get.getAccountBalance(DYDX_ADDRESS, TOKEN_DENOM)
Transfers, Deposits, and Withdraws
Transfering an Asset
import { SubaccountClient } from '@dydxprotocol/v4-client-js';
const subaccount = new SubaccountClient(wallet, 0);
const recipientAddress = 'dydx...' // address of the recipient
const recipientSubaccountNumber = 0 // subaccount number of the recipient
const assetId = 0 // asset id of the token you want to transfer
const amount = Long.fromNumber(/* amount of the token you want to transfer */);
const tx = await client.post.transfer(
subaccount,
recipientAddress,
recipientSubaccountNumber,
assetId,
amount
);
Depositing from wallet to Subaccount
import { SubaccountClient } from '@dydxprotocol/v4-client-js';
const subaccount = new SubaccountClient(wallet, 0);
const assetId = 0 // asset id of the token you want to deposit
const amount = Long.fromNumber(/* amount of the token you want to deposit */);
const tx = await client.post.deposit(
subaccount,
assetId,
amount
);
Withdrawing from Subaccount to wallet
import { SubaccountClient } from '@dydxprotocol/v4-client-js';
const subaccount = new SubaccountClient(wallet, 0);
const assetId = 0 // asset id of the token you want to withdraw
const amount = Long.fromNumber(/* amount of the token you want to withdraw */);
const tx = await client.post.withdraw(
subaccount,
assetId,
amount
);
Placing and Cancelling Orders
Placing an Order
import { OrderFlags, Order_Side, Order_TimeInForce, SubaccountClient } from '@dydxprotocol/v4-client-js';
const subaccount = new SubaccountClient(wallet, 0);
const clientId = 123 // set to a number, can be used by the client to identify the order
const clobPairId = 0 // perpertual market id
const side = Order_Side.SIDE_BUY // side of the order
const quantums = Long.fromNumber(1_000_000_000); // quantums are calculated by the size if the order
const subticks = Long.fromNumber(1_000_000_000); // subticks are calculated by the price of the order
const timeInForce = Order_TimeInForce.TIME_IN_FORCE_UNSPECIFIED; // TimeInForce indicates how long an order will remain active before it is executed or expires
const orderFlags = OrderFlags.SHORT_TERM; // either SHORT_TERM, LONG_TERM or CONDITIONAL
const reduceOnly = false; // if true, the order will only reduce the position size
const tx = await client.post.placeOrder(
subaccount,
clientId,
clobPairId,
side,
quantums,
subticks,
timeInForce,
orderFlags,
reduceOnly
);
Cancelling an Order
All paramsters are from Order object from indexer goodTilBlockTime is the UTC epoch second of the order's goodTilBlockTime One and only one of goodTilBlock and goodTilBlockTime should be passed in as a parameter
/*
order is an Order object from the Indexer
*/
const goodTilBlock = order.goodTilBlock
let goodTilBlockTime: number | undefined;
if (order.goodTilBlockTime) {
const datetime = new Date(order.goodTilBlockTime);
const utcMilllisecondsSinceEpoch = datetime.getTime()
goodTilBlockTime = Math.round(utcMilllisecondsSinceEpoch / 1000);
}
const tx = await client.post.cancelOrder(
subaccount,
order.clientId,
order.orderFlags,
order.clobPairId,
goodTilBlock,
goodTilBlockTime
);