Spark BTKN Airdrops

Spark now supports airdrops directly to users’ Xverse wallets — using their Taproot identity as a bridge between the Ordinals world and the Spark ecosystem.

With this setup, projects can reward active Bitcoin users (based on their bc1p… Taproot addresses) while ensuring their tokens automatically appear inside Xverse.


🎯 Overview

Each Xverse wallet has two Spark addresses under the hood:

Address Type
Purpose
Visibility

Primary Spark Address

Used for main balance, trading, and DeFi interactions

Visible & shareable

Taproot-Derived Spark Address

Used only for receiving airdrops based on the user’s Taproot identity

Hidden, not shareable

When a project airdrops tokens to a user’s Taproot-derived Spark address, Xverse automatically:

  • Detects the balance;

  • Displays it as part of the total token balance on the dashboard;

  • Adds a ✳️ “Claim” label next to the token.

When the user clicks Claim, the wallet simply moves the tokens from the Taproot-derived address to their main Spark address — consolidating balances without any manual setup.


🧠 Why Use Taproot-Derived Addresses?

Taproot addresses (the ones starting with bc1p…) are widely used by Ordinals, Runes, and BRC-20 communities. By deriving a Spark address from a user’s Taproot public key, projects can target on-chain Bitcoin identities directly — no sign-up or wallet linking required.

It’s a seamless bridge between Bitcoin culture and Spark-native tokens.


🧰 Deriving a User’s Spark Airdrop Address

To airdrop Spark tokens to a user based on their Taproot address, you can derive the corresponding Spark airdrop address using the snippet below.

This ensures compatibility with Xverse’s “Claim” flow and balance aggregation.

import { Address } from '@scure/btc-signer';
import { hex } from '@scure/base';
import { encodeSparkAddress } from '@buildonspark/spark-sdk';

const getSparkAirdropAddress = async (taprootAddress: string): Promise<string> => {
  const address = Address().decode(taprootAddress);

  if (address.type !== 'tr') {
    throw new Error('Invalid taproot address provided');
  }

  const identityPublicKey = hex.encode(address.pubkey);
  const sparkAirdropAddress = encodeSparkAddress({
    identityPublicKey: `02${identityPublicKey}`,
    network: 'MAINNET',
  });

  return sparkAirdropAddress;
};

Notes:

  • The derivation follows Spark PR #37.

  • Only tr (Taproot) addresses are supported.

  • The resulting address is a valid Spark address on mainnet, ready to receive Spark BTKN airdrops.


💸 How It Looks for Users in Xverse

  1. The project airdrops tokens (e.g. $DRAGON) to the user’s Taproot-derived Spark address.

  2. Xverse detects the balance and displays it in the dashboard total.

  3. A ✳️ “Claim” tag appears next to $DRAGON.

  4. The user opens the token dashboard and clicks Claim your 50 $DRAGON airdrop.

  5. Xverse shows a transaction review screen, confirming:

    • From: Taproot-derived Spark address

    • To: Primary Spark address

    • Amount: Full token balance

  6. After confirming, the tokens move to the main Spark wallet — clean, unified, and ready to use in DeFi or swaps.


🪄 Developer Benefits

  • No need for users to link wallets or sign messages.

  • Works with any existing Taproot user base.

  • Instantly compatible with Xverse — airdrops appear automatically.

  • Smooth, one-click claiming UX built directly into the wallet.


Last updated