Skip to main content
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();
};