We'll use a few of the common functions, assuming that they are in a common.ts file. The withdraw step requires a nonce as the transaction is executed against the off-chain engine.
import { toFixedPoint } from '@vertex-protocol/utils';
// Change the import source as needed
import { getVertexClient, prettyPrintJson } from './common';
Mint a mock ERC20 token for testing
Grab a client object and mint mock tokens for the relevant product. This is only available on testnets for obvious reasons.
Minting is on-chain, so we wait for the transaction confirmation for chain state to propagate.
const vertexClient = await getVertexClient();
const { walletClient, publicClient } = vertexClient.context
// If you have access to `walletClient`, you can call `walletClient.account.address`
// directly instead of reaching into `vertexClient.context`
const address = walletClient!.account.address;
const subaccountName = 'default';
// 10 USDC (6 decimals)
const depositAmount = toFixedPoint(10, 6);
const mintTxHash = await vertexClient.spot._mintMockERC20({
amount: depositAmount,
productId: 0,
});
await publicClient.waitForTransactionReceipt({
hash: mintTxHash,
});
Make a deposit
First, call approveAllowance to approve the deposit amount.
This is also an on-chain transaction with a confirmation hash.
Now we can deposit the tokens. This transaction is on-chain.
const depositTxHash = await vertexClient.spot.deposit({
// Your choice of name for the subaccount, this subaccount will be credited with the deposit balance
subaccountName: 'default',
amount: depositAmount,
productId: 0,
});
await publicClient.waitForTransactionReceipt({
hash: depositTxHash,
});
Subaccounts
A subaccount is an independent trading account within Vertex, allowing traders to manage risk across independent subaccounts
Subaccounts are associated by a string name (max 12 char.) and the owner wallet address
After this, we inject a short delay while the offchain sequencer picks up the transaction and credits the account.
await new Promise((resolve) => setTimeout(resolve, 10000));
Query Subaccount balance
Now, call the getSubaccountEngineSummary function to retrieve an overview of your subaccount, including balances.
const subaccountData =
await vertexClient.subaccount.getEngineSubaccountSummary({
subaccountOwner: address,
subaccountName,
});
prettyPrintJson('Subaccount Data After Deposit', subaccountData);
Engine vs. Contract Queries
You may notice that there is a getSubaccountEngineSummary and getSubaccountSummary
The engine variants retrieve the state from the off-chain engine, while the contract variants retrieve the state from the on-chain contracts.
These should ultimately match up, given that our off-chain engine is fully synced and operational.
You should see that your balance associated with productId of 0 now reflects your deposit amount.
Full example
import { toFixedPoint } from '@vertex-protocol/utils';
import { getVertexClient, prettyPrintJson } from './common';
async function main() {
const vertexClient = getVertexClient();
const { walletClient, publicClient } = vertexClient.context;
// If you have access to `walletClient`, you can call `walletClient.account.address`
// directly instead of reaching into `vertexClient.context`
const address = walletClient!.account.address;
const subaccountName = 'default';
// 10 USDC (6 decimals)
const depositAmount = toFixedPoint(10, 6);
// TESTNET ONLY - Mint yourself some tokens
const mintTxHash = await vertexClient.spot._mintMockERC20({
amount: depositAmount,
productId: 0,
});
// Mint goes on-chain, so wait for confirmation
await publicClient.waitForTransactionReceipt({
hash: mintTxHash,
});
// Deposits require approval on the ERC20 token, this is on-chain as well
const approveTxHash = await vertexClient.spot.approveAllowance({
amount: depositAmount,
productId: 0,
});
await publicClient.waitForTransactionReceipt({
hash: approveTxHash,
});
// Now execute the deposit, which goes on-chain
const depositTxHash = await vertexClient.spot.deposit({
// Your choice of name for the subaccount, this subaccount will be credited with the deposit balance
subaccountName: 'default',
amount: depositAmount,
productId: 0,
});
await publicClient.waitForTransactionReceipt({
hash: depositTxHash,
});
await new Promise((resolve) => setTimeout(resolve, 10000));
// For on-chain state, you can use `getSubaccountSummary` - these should match up
const subaccountData =
await vertexClient.subaccount.getEngineSubaccountSummary({
subaccountOwner: address,
subaccountName,
});
prettyPrintJson('Subaccount Data After Deposit', subaccountData);
}
main();