Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.magic.link/llms.txt

Use this file to discover all available pages before exploring further.

When signing messages or transactions on Solana, you need to properly encode your data. Unlike EVM chains, Solana uses a unified signing approach where all data is base64-encoded before signing.

Message Signing

For signing raw messages or strings, encode your data as base64:
TypeScript
const personalSign = async (data: string | Uint8Array) => {
  // Convert string to Uint8Array if needed
  const messageUint8 = typeof data === 'string' ? new TextEncoder().encode(data) : data;
  
  // Encode as base64
  const message = Buffer.from(messageUint8).toString('base64');
  
  const body = { message_base64: message };
  return await fetch('/v1/wallet/sign/message', { 
    method: 'POST', 
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
      'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
      'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
      'X-Magic-Chain': 'SOL'
    },
    body: JSON.stringify(body) 
  });
};

Transaction Signing

Solana transaction signing involves serializing the transaction message and encoding it as base64. The process differs based on transaction type:
import { Transaction, PublicKey } from '@solana/web3.js';

const signLegacyTransaction = async (tx: Transaction) => {
  // Serialize the transaction message
  const messageBytes = tx.serializeMessage();
  const rawDataBase64 = Buffer.from(messageBytes).toString('base64');
  
  const body = { message_base64: rawDataBase64 };
  const res = await fetch('/v1/wallet/sign/message', { 
    method: 'POST', 
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${YOUR_JWT_TOKEN}`,
      'X-Magic-API-Key': 'YOUR_MAGIC_API_KEY',
      'X-OIDC-Provider-ID': 'YOUR_OIDC_PROVIDER_ID',
      'X-Magic-Chain': 'SOL'
    },
    body: JSON.stringify(body) 
  });
  
  const { signature } = await res.json();
  
  // Convert signature back to bytes and attach to transaction
  // Handle both hex (0x prefixed) and base64 signatures
  const sigBytes = signature.startsWith('0x') 
    ? Buffer.from(signature.slice(2), 'hex')
    : Buffer.from(signature, 'base64');
  const signerPk = new PublicKey('YOUR_WALLET_PUBLIC_KEY');
  tx.addSignature(signerPk, sigBytes);
  
  return tx.serialize();
};