Creating a Sub-Account

Creating a Sub-Account for Trading

In order to place trades using a SYMM frontend solution or otherwise, it's necessary to create a sub-account using a MultiAccount contract that is whitelisted to interact with the hedger. All MultiAccount contract addresses are listed in the table below:

Users are required to provide a name an input parameter when they create a sub-account. All positions on a sub-account are in CROSS, but positions between sub-accounts are ISOLATED. If you're creating a bot that hedges against the impermanent loss an LP might incur, it could be useful to create a sub-account for each hedged position.

First, we'll define our environment-dependent variables in a .env file like so:

WALLET_PRIVATE_KEY=
WALLET_ADDRESS=
PROVIDER_URL=
MUON_URL=

The PROVIDER_URL field should contain the Ankr RPC URL and the appropriate MUON_URL can be found here.

First we'll define the contract that we want to interact with using Web3. In this case it's the MultiAccount contract. We create a new web3 Contract with the ABI provided in the /abi directory and the multiAccountAddress. We'll also use our WALLET_PRIVATE_KEY defined in the environment to set up our web3 account.

require('dotenv').config();
const config = require('./symmconfig'); //using a separate config file for contract addresses
const { Web3 } = require('web3');
const { multiAccountABI } = require('./abi/MultiAccount');

const web3 = new Web3(new Web3.providers.HttpProvider(process.env.PROVIDER_URL));

const multiAccountAddress = config.MULTI_ACCOUNT_ADDRESS;
const multiAccount = new web3.eth.Contract(multiAccountABI, multiAccountAddress);

const account = web3.eth.accounts.privateKeyToAccount(process.env.WALLET_PRIVATE_KEY);
web3.eth.accounts.wallet.add(account);

Adding a Sub-Account

The addAccount() function takes one parameter, the accountName, here we are simply calling the function on the MultiAccount contract and logging information related to the transaction.

async function addAccount(accountName) {
  if (!accountName) {
    console.error("Account name is not provided.");
    return;
  }

  try {
  //Gas Estimates
    const currentGasPrice = await web3.eth.getGasPrice();
    const increasedGasPriceBigInt = BigInt(currentGasPrice) * BigInt(120) / BigInt(100);
    const gasEstimate = await multiAccount.methods.addAccount(accountName).estimateGas({ from: account.address });
    const gasEstimateBigInt = BigInt(gasEstimate);
    const gasLimitWithBuffer = gasEstimateBigInt + (gasEstimateBigInt * BigInt(20) / BigInt(100));

    const receipt = await multiAccount.methods.addAccount(accountName).send({
      from: account.address,
      gas: gasLimitWithBuffer.toString(), 
      gasPrice: increasedGasPriceBigInt.toString()
    });

    console.log("Account Creation Successful. Transaction hash: ", receipt.transactionHash);

    if (receipt.events.AddAccount) {
      const event = receipt.events.AddAccount.returnValues;
      console.log("Account Created. Address: ", event.account);
      return event.account;
    } else {
      console.log("No AddAccount event found.");
    }
  } catch (error) {
    console.error("Failed to add account:", error);
  }
}

This function creates a sub-account and returns the address.

Last updated

Logo

All rights to the people (c) 2023 Symmetry Labs A.G.