Build
Tutorials
Solana

Building universal applications with ZetaChain and Solana is easy. You can deposit SOL and SPL-20 tokens directly from Solana into accounts or smart contracts on ZetaChain. Universal contracts on ZetaChain can handle these deposits and execute contract calls initiated from the Solana blockchain.

In this tutorial, you'll:

  • Deploy a universal contract on ZetaChain.
  • Deposit tokens (SOL and SPL-20) from Solana to ZetaChain.
  • Execute deposit-and-call transactions, depositing tokens and calling a universal app simultaneously.
  • Withdraw tokens back to Solana, optionally calling Solana programs as part of the withdrawal.

Interactions with universal apps from Solana are handled by the Solana Gateway program, learn more about it in the docs.

Ensure you have installed and configured the following before starting:

Start by creating a project and installing the necessary dependencies:

npx zetachain@latest new --project call
cd call
yarn
GATEWAY_ZETACHAIN=0x6c533f7fe93fae114d0954697069df33c9b74fd7
ZRC20_SOL=0xADF73ebA3Ebaa7254E859549A44c74eF7cff7501
RPC_ZETACHAIN=https://zetachain-athens-evm.blockpi.network/v1/rpc/public

In a new terminal window, compile and deploy the universal contract:

UNIVERSAL=$(forge create Universal \
  --rpc-url $RPC_ZETACHAIN \
  --private-key $PRIVATE_KEY \
  --evm-version paris \
  --broadcast \
  --json \
  --constructor-args $GATEWAY_ZETACHAIN | jq -r .deployedTo) && echo $UNIVERSAL

Deposit SOL tokens from Solana to ZetaChain:

npx zetachain solana deposit \
  --recipient $UNIVERSAL \
  --private-key $PRIVATE_KEY_SOLANA \
  --amount 0.01 \
  --chain-id 902

Call the deployed universal contract:

npx zetachain solana call \
  --recipient $UNIVERSAL \
  --private-key $PRIVATE_KEY_SOLANA \
  --chain-id 901 \
  --types string \
  --values hello

Deposit tokens and simultaneously call the deployed universal contract:

npx zetachain solana deposit-and-call \
  --recipient $UNIVERSAL \
  --private-key $PRIVATE_KEY_SOLANA \
  --amount 0.01 \
  --chain-id 901 \
  --types string \
  --values hello

This command deposits tokens and triggers the universal contract function with the argument "hello".

Withdraw tokens from ZetaChain back to Solana:

npx zetachain z withdraw \
  --receiver DrexsvCMH9WWjgnjVbx1iFf3YZcKadupFmxnZLfSyotd \
  --zrc20 $ZRC20_SOL \
  --amount 0.1 \
  --rpc $RPC_ZETACHAIN \
  --gateway $GATEWAY_ZETACHAIN \
  --private-key $PRIVATE_KEY
  • --gateway-zeta-chain: Address of the ZetaChain gateway.
  • --receiver: A Solana wallet address to receive the withdrawn tokens.
  • --zrc20: The ZetaChain representation of the token you want to withdraw (ZRC-20 address).
  • --amount: The amount to withdraw.

Beyond simply withdrawing tokens from ZetaChain back to Solana, you can also execute a Solana program as part of the withdrawal process. This allows for more complex interactions, such as triggering on-chain logic immediately upon receiving funds. For example, you can withdraw SOL or SPL-20 tokens and call a Solana program in a single transaction, enabling use cases like automatic staking, swaps, or contract executions.

The solana directory contains an example Solana program with an on_call function, which can be invoked by a universal app on ZetaChain during the withdrawal process.

The following steps will guide you through setting up an example Solana program and using the ZetaChain Gateway to perform a "withdraw and call".

Build and Set Up the Example Solana Program

cd solana
anchor build

If the build fails, run:

rustup update
rm Cargo.lock
anchor build

Deploy the program:

PROGRAM_ID=$(solana program deploy target/deploy/connected.so \
  --url devnet \
  --output json| jq -r .programId) && echo $PROGRAM_ID

After running this, you should see output indicating that the program was successfully deployed, such as:

D7FLXZPthgJewjp4jsGBLNSCTdDyhB6GEmWddyqTYLZc

Withdraw SOL and Call the Solana Program

PAYLOAD=$(npx zetachain solana encode \
  --connected $PROGRAM_ID \
  --data hello \
  --gateway ZETAjseVjuFsxdRxo6MmTCvqFwb3ZHUx56Co3vCmGis) && echo $PAYLOAD

Make a call to the ZetaChain Gateway to withdraw SOL and call a program on Solana:

npx zetachain z withdraw-and-call \
  --amount 0.001 \
  --receiver $PROGRAM_ID \
  --data $PAYLOAD \
  --private-key $PRIVATE_KEY \
  --rpc $RPC_ZETACHAIN \
  --zrc20 $ZRC20_SOL \
  --gateway $GATEWAY_ZETACHAIN