Skip to main content

Withdraw ERC20 (Myria) Tokens

  • Learn how to withdraw ERC20 tokens from Myria L2 network to Ethereum L1 network.
  • To inspect the function in the SDK with details payload and response format you can reference at SDK Docs.

Prerequisites

  • Make sure that you have ERC-20 tokens (such as Myria tokens) in the L2 wallet
  • You can deposit ERC20 (ex: MYR tokens) from L1 to L2 wallet, can reference at depositERC20 step.
  • Or if your L2 wallet received the ERC-20 tokens from Airdrop / Campaign events.

Withdrawal process

  1. Available balance of ERC-20 tokens in the L2 wallet
  2. Initiate the withdrawal
  3. Get withdraw balance
  4. Complete withdraw

Implementation

info

You can find the full React implementation for ERC20 withdrawals in the Myria React Samples repository.

1. Set up a React project

Withdrawing ERC20 tokens requires client-side interaction with the MetaMask wallet. It's recommended to use React to implement such behavior.

You can create a React app via Create React App. Note, the below project relies on the Web3.js library and needs custom configuration.

2. Create a myria-client.ts helper

It's recommended to have a separate .ts file for quick access to the MyriaClient.

For more details, use the Myria Core SDK overview.

3. Withdraw ERC20 tokens

The withdrawErc20() function has the following parameters:

  1. params object:
  • tokenType - TokenType.ERC20 as an enum TokenType
  • amount - the Wei amount that you'd to withdraw
  • tokenAddress - The smart contract address of your ERC-20 token
  • senderPublicKey - The Stark Key that you registered in Myria L2
  • senderEthAddress - Your wallet address in L1
  • receiverPublicKey - Your wallet address in L1
  • quantum - Default constants 10^10 as pre-defined value in Myria
  1. sendOptions object:
  • from - public key of your wallet
  • confirmationType - Recommendation type is Confirmed as the request is awaiting until transaction is confirmed at on-chain and received transaction receipts
import { ConfirmationType, TokenType, WithdrawOffchainParamsV2, WithdrawalModule, MyriaClient, SendOptions } from "myria-core-sdk";
import Web3 from 'web3';

const QUANTUM = 10000000000; // 10^10 as pre-defined rules in Myria

function convertEthToWei(amount: string): string {
if (!amount || Number(amount) === 0) return '0';
return Web3.utils.toWei(amount.toString()).toString();
}

export async function withdrawERC20(client: MyriaClient, starkKey: string, account: string, contractAddress: string, amount: string) {
const withdrawalModule: WithdrawalModule = new WithdrawalModule(client);

const withdrawErc20Params : WithdrawOffchainParamsV2 = {
tokenType: TokenType.ERC20,
amount: String(convertEthToWei(amount.toString())),
tokenAddress: contractAddress, // Your ERC-20 smart contract of tokens
senderPublicKey: `0x${pKey}`,
senderEthAddress: account,
receiverPublicKey: account,
quantum: QUANTUM.toString(),
};

const sendOptions: SendOptions = {
from: account,
confirmationType: ConfirmationType.Confirmed,
}

const responseWithdraw: TransactionData = await withdrawModule.withdrawalOffchainV2(withdrawErc20Params, sendOptions);
console.log(JSON.stringify(responseWithdraw, null, 2));
}

4. Get available withdraw balance

  • At this stage, the system have tracked your off-chain withdraw transactions and depend on the batch job that Myria processing internally with Starkware so your withdraw balance would be available along at that time
  • The maximum estimated time would be 35-48 hous for batch job timing to be processing.
info

Important note: You're only able to Complete The Withdraw as next step (Withdraw On-chain) if the withdraw balance is available and greater > 0 in L1.

The getWithdrawBalance() function has the following parameters:

  1. params object:
  • tokenType - TokenType.ERC20 as an enum TokenType
  • assetId - The computed hex string with Starkware's algorithm by combination of ERC-20 tokens smart contract and token type + quantum
  • tokenAddress - The smart contract address of your ERC-20 token
  • quantum - Default constants 10^10 as pre-defined value in Myria
import { ConfirmationType, TokenType, WithdrawalModule, MyriaClient } from "myria-core-sdk";
import Web3 from 'web3';

// Reference at this link: https://github.com/starkware-libs/starkware-crypto-utils
const StarkwareLib = require('@starkware-industries/starkware-crypto-utils');
const { asset } = StarkwareLib;

const QUANTUM = 10000000000; // 10^10 as pre-defined rules in Myria

export async function getWithdrawBalance(client: MyriaClient, account: string, contractAddress: string) {
const withdrawalModule: WithdrawalModule = new WithdrawalModule(client);

// Computed asset type by combination of Smart contract address and tokens type, Quantum
const assetType = asset.getAssetType({
type: 'ERC20',
data: {
quantum: QUANTUM.toString(),
tokenAddress: contractAddress
}
});

const availableWithdrawBalance = await withdrawModule.getWithdrawalBalance(account, assetId);
console.log(JSON.stringify(availableWithdrawBalance, null, 2));
}

4. Complete Withdraw - Withdraw fund to your L1 wallet

  • This step is final step of withdraw as it would move your fund from Myria L1 to your wallet (ex: Metamask) in L1
  • The process of withdraw on-chain would required the gas fee in your L1 wallet (Metamask).
info

Important note: Your withdrawal transaction would cost gas fee based on ethereum networks gas and it could be fluctuated in time.

The withdrawOnchainErc20() function has the following parameters:

  1. params object:
  • tokenType - TokenType.ERC20 as an enum TokenType
  • assetId - The computed hex string with Starkware's algorithm by combination of ERC-20 tokens smart contract and token type + quantum
  • tokenAddress - The smart contract address of your ERC-20 token
  • quantum - Default constants 10^10 as pre-defined value in Myria
import { ConfirmationType, TokenType, WithdrawalModule, MyriaClient, WithdrawOnchainParams } from "myria-core-sdk";
import Web3 from 'web3';

// Reference at this link: https://github.com/starkware-libs/starkware-crypto-utils
const StarkwareLib = require('@starkware-industries/starkware-crypto-utils');
const { asset } = StarkwareLib;

const QUANTUM = 10000000000; // 10^10 as pre-defined rules in Myria

export async function withdrawOnchainErc20(client: MyriaClient, account: string, contractAddress: string) {
const withdrawalModule: WithdrawalModule = new WithdrawalModule(client);

// Computed asset type by combination of Smart contract address and tokens type, Quantum
const assetType: string = asset.getAssetType({
type: TokenType.ERC20,
data: {
quantum: QUANTUM,
tokenAddress: contractAddress
}
});

const withdrawOnchainErc20Payload: WithdrawOnchainParams = {
starkKey: walletAddress,
assetType
};

const sendOptions = {
from: account,
nonce: new Date().getTime(), // It's optional but it's recommend to pass the unique nonce by get timestamp
confirmationType: ConfirmationType.Confirmed
};


const result = await withdrawModule.withdrawalOnchain(withdrawOnchainErc20Payload, sendOptions);

const withdrawOnchainResult = await withdrawModule.getWithdrawalBalance(account, assetId);
console.log(JSON.stringify(withdrawOnchainResult, null, 2));
}