Initialize Token Account

Creating a token account from Solana Proxy Account for each x-chain users.

For any tokens to migrate from evm chain to solana chain a user must have an existing token account in solana chain. This is becuase, every token has separate associated token account and a user may own many token account. An associated token account address is derived from the token mint address, user wallet address and token program id.

You can create a token account in following way.

const owner = "0x91845D534744Ef350695CF98393d23acC9639024";
const tokenAddress = "<evm token address>"
const sourceChain = CHAIN_ID_BSC;
const targetChain = CHAIN_ID_SOLANA;

const tokenAddrInSolana = await getTargetAsset(
   signer, 
   tokenAddress, 
   sourceChain, 
   targetChain
)	
const proxyAccount = ZebecSolBridgeClient.getProxyUserKey(
   tryNativeToUint8Array(owner, sourceChain), 
   sourceChain, 
   SOL_ZEBEC_BRIDGE_ADDRESS
);

const ethClient = new ZebecEthBridgeClient(BSC_ZEBEC_BRIDGE_ADDRESS, signer, sourceChain);

const receipt = await ethClient.createTokenAccount(owner, tokenAddrInSolana);

Now you can find signed Vaa bytes of your payload sent to wormhole.

const sequence = parseSequenceFromLogEth(receipt, getBridgeAddressForChain(sourceChain));
const zebecEmitterAddress = getEmitterAddressEth(BSC_ZEBEC_BRIDGE_ADDRESS);
const { vaaBytes } = await getSignedVAAWithRetry(WORMHOLE_RPC_HOSTS, sourceChain, zebecEmitterAddress, sequence);

Rest of work is performed by the relayer. If you want to manually relay the payloads to solana, you can accomplish it in following way.

const payerAddress = wallet.publicKey.toString();
const bridgeAddress = getBridgeAddressForChain(targetChain);

const vaaBuf = Buffer.from(vaaBytes);

setDefaultWasm("node"); // use bundler for browser

// posting vaa in solana
await postVaaSolanaWithRetry(
   connection,
   wallet.signTransaction,
   bridgeAddress,
   payerAddress,
   vaaBuf,
   MAX_VAA_UPLOAD_RETRIES_SOLANA,
);

Then you parse payload information from vaa and call method in Zebec Solana bridge program to initialize token account in solana.

const { parse_vaa } = await importCoreWasm();
const parsedVaa = parse_vaa(vaaBytes);
const parsedPayload = parseZebecPayload(Buffer.from(parsedVaa.payload));

const result = await solanaClient.initiallizePdaTokenAccount(
   vaaBytes,
   <InitializeTokenAccountPayload>parsedPayload,
);

Last updated