Spooky Doge Logo

dApp Integration Guide

Integrate your dApp with Spooky Doge wallet for Dogecoin payments and Doginal transfers


Platform Support

Spooky Doge wallet is available on:

Both platforms inject the same window.dogecoin provider, so you can support all users with a single codebase.

Quick Start

1. Detect the Wallet

// Check if Spooky Doge wallet is available
function isSpookyWalletAvailable() {
  return typeof window.dogecoin !== 'undefined' && window.dogecoin.isSpookyWallet;
}

// Wait for wallet to be ready (it injects after page load)
window.addEventListener('dogecoin#initialized', () => {
  console.log('Spooky Doge wallet detected!');
});

2. Connect to the Wallet

async function connectWallet() {
  if (!isSpookyWalletAvailable()) {
    alert('Please install Spooky Doge wallet or open in the Spooky Doge app browser');
    return null;
  }

  try {
    // Opens approval popup for user
    const result = await window.dogecoin.connect();
    console.log('Connected! Address:', result.address);
    return result.address;
  } catch (error) {
    console.error('Connection rejected:', error.message);
    return null;
  }
}

3. Get Account Information

// Get connected address
const address = await window.dogecoin.getAddress();

// Get wallet balance in koinu (1 DOGE = 100,000,000 koinu)
const balance = await window.dogecoin.getBalance();
const dogeBalance = balance / 100000000;

// Check if currently connected
const connected = window.dogecoin.isConnected();

// Get all connected accounts
const accounts = await window.dogecoin.getAccounts();

4. Send DOGE

// Simple single-output transaction
async function sendPayment(recipientAddress, amountInDoge) {
  try {
    // Opens transaction approval popup
    const result = await window.dogecoin.sendTransaction({
      to: recipientAddress,
      amount: amountInDoge  // Amount in DOGE (not koinu)
    });

    console.log('Transaction sent! TXID:', result.txid);
    return result.txid;
  } catch (error) {
    console.error('Transaction failed:', error.message);
    throw error;
  }
}

// Advanced: Multi-output transaction (e.g., with marketplace fee)
async function sendPaymentWithFee(recipientAddress, amount, marketplaceFeeAddress, feeAmount) {
  try {
    const result = await window.dogecoin.sendTransaction({
      outputs: [
        { address: recipientAddress, amount: amount },
        { address: marketplaceFeeAddress, amount: feeAmount }
      ]
    });

    console.log('Transaction sent! TXID:', result.txid);
    return result.txid;
  } catch (error) {
    console.error('Transaction failed:', error.message);
    throw error;
  }
}

// Example: Send 100 DOGE to seller + 5 DOGE marketplace fee
await sendPaymentWithFee('DSellerAddress...', 100, 'DMarketplaceFeeAddress...', 5);

5. Work with Doginals (Inscriptions)

// Get all doginals in the wallet
const doginals = await window.dogecoin.getDoginals();
doginals.forEach(d => {
  console.log('Inscription:', d.inscriptionId);
  console.log('Image URL:', d.imageUrl);
  console.log('Content Type:', d.contentType);
});

// Transfer a single doginal
async function transferDoginal(inscriptionId, recipientAddress) {
  try {
    const result = await window.dogecoin.sendDoginal({
      inscriptionId: inscriptionId,  // Single inscription ID
      to: recipientAddress
    });
    console.log('Doginal transferred! TXID:', result.txid);
    return result.txid;
  } catch (error) {
    console.error('Transfer failed:', error.message);
    throw error;
  }
}

// Transfer MULTIPLE doginals in one transaction
async function transferMultipleDoginals(inscriptionIds, recipientAddress) {
  try {
    const result = await window.dogecoin.sendDoginal({
      inscriptionId: inscriptionIds,  // Array of inscription IDs
      to: recipientAddress
    });
    console.log('Doginals transferred! TXID:', result.txid);
    return result.txid;
  } catch (error) {
    console.error('Transfer failed:', error.message);
    throw error;
  }
}

// Example: Send 3 doginals at once
const myDoginals = ['abc123i0', 'def456i0', 'ghi789i0'];
await transferMultipleDoginals(myDoginals, 'DRecipientAddress...');

6. Sign Messages

// Request a message signature (no cost, requires user approval)
async function signMessage(message) {
  try {
    const result = await window.dogecoin.signMessage(message);
    console.log('Signature:', result.signature);
    console.log('Signed by:', result.address);
    return result;
  } catch (error) {
    console.error('Signing failed:', error.message);
    throw error;
  }
}

7. Work with DRC-20 Tokens

// Get DRC-20 token balances
async function getDrc20Balances() {
  const balances = await window.dogecoin.request({
    method: 'doge_getDrc20Balances'
  });
  // Returns: [{ tick: 'DOGI', available: '1000', transferable: '500', total: '1500' }, ...]
  return balances;
}

// Send DRC-20 tokens
async function sendDrc20(tick, amount, recipient) {
  const result = await window.dogecoin.request({
    method: 'doge_sendDrc20',
    params: {
      tick: tick,           // Token ticker (e.g., 'DOGI')
      amount: amount,       // Amount as string
      to: recipient         // Recipient address
    }
  });
  return result.txid;
}

Fee: 0.03 DOGE per transfer (0.02 network + 0.01 wallet)

8. Work with Dunes Tokens

// Get Dunes token balances
async function getDunesBalances() {
  const balances = await window.dogecoin.request({
    method: 'doge_getDunesBalances'
  });
  // Returns: [{ name: 'COOL•DUNE', symbol: 'COOLDUNE', balance: '5000', divisibility: 0 }, ...]
  return balances;
}

// Send Dunes tokens
async function sendDune(duneName, amount, recipient) {
  const result = await window.dogecoin.request({
    method: 'doge_sendDune',
    params: {
      duneName: duneName,   // Dune name (e.g., 'COOL•DUNE')
      amount: amount,       // Amount as string
      to: recipient         // Recipient address
    }
  });
  return result.txid;
}

Fee: Variable (0.02 DOGE for single-dune UTXO, 0.20 DOGE for multi-dune auto-split)

8b. Send Dunes to Multiple Recipients

// Send Dunes to MULTIPLE recipients in one transaction (up to 50)
async function sendDuneToMany(duneName, recipients) {
  try {
    const result = await window.dogecoin.sendDuneMulti({
      duneName: duneName,
      outputs: recipients  // [{ address: 'D...', amount: '100' }, ...]
    });
    console.log('Multi-dune transfer sent! TXID:', result.txid);
    return result.txid;
  } catch (error) {
    console.error('Multi-dune transfer failed:', error.message);
    throw error;
  }
}

// Example: Distribute dune rewards to 3 stakers
await sendDuneToMany('SPOOKY.DOGE', [
  { address: 'DStaker1Address...', amount: '500' },
  { address: 'DStaker2Address...', amount: '250' },
  { address: 'DStaker3Address...', amount: '1000' },
]);

Fee: Base 0.20 DOGE + scaling per input/output + 0.01 DOGE wallet fee. Max 50 recipients per transaction.

9. Batch DRC-20 Airdrop (Up to 500 Recipients)

Send a DRC-20 token to up to 500 recipients in one operation. Designed for airdrop tools and staking reward distribution. Each recipient can receive a different amount.

// Batch send DRC-20 tokens to many recipients
async function batchSendDrc20(tick, recipients) {
  try {
    const result = await window.dogecoin.request({
      method: 'doge_batchSendDrc20',
      params: {
        tick: tick,            // DRC-20 token ticker (e.g., 'SLIME')
        recipients: recipients // [{ address: 'D...', amount: '1000' }, ...]
      }
    });

    console.log('Batch complete!');
    console.log('Distribution TXIDs:', result.distributionTxids);
    console.log('Completed:', result.completedRecipients, '/', result.totalRecipients);
    return result;
  } catch (error) {
    if (error.message === 'User rejected') {
      console.log('User declined the batch send');
    } else {
      console.error('Batch failed:', error.message);
    }
    throw error;
  }
}

// Example: Airdrop SLIME to 5 holders
await batchSendDrc20('SLIME', [
  { address: 'DHolder1...', amount: '1000' },
  { address: 'DHolder2...', amount: '500' },
  { address: 'DHolder3...', amount: '2500' },
  { address: 'DHolder4...', amount: '750' },
  { address: 'DHolder5...', amount: '1200' },
]);
How it works: The wallet creates one transfer inscription per recipient (each encoding the correct amount), then sends them all to recipients in a distribution transaction. Inscriptions always land at the sender first — they only move to recipients when the distribution tx confirms. If anything fails mid-batch, undelivered inscriptions remain in your wallet as pending transfers for retry.
Performance tip: Wallets with multiple fee UTXOs (0.01+ DOGE each) can run parallel inscription chains for faster processing. With 5 UTXOs, ~50 inscriptions can be created without pausing for block confirmations.

Limits: Maximum 500 recipients per call. Distribution transactions auto-split if they exceed ~95KB.

Fee: 0.02 DOGE per inscription tx (2 per recipient = 0.04/recipient) + distribution fee (0.02 base + 0.01 per recipient dust penalty) + 0.01 DOGE dev fee. Example: 50 recipients ≈ 2.54 DOGE total.

10. Listen for Events

// Account changes (user switches address)
window.dogecoin.on('accountsChanged', (accounts) => {
  if (accounts.length === 0) {
    console.log('Wallet disconnected');
  } else {
    console.log('Active account:', accounts[0]);
  }
});

// Connection events
window.dogecoin.on('connect', ({ address }) => {
  console.log('Connected:', address);
});

window.dogecoin.on('disconnect', () => {
  console.log('Wallet disconnected');
});

API Reference

Provider Object

Available at window.dogecoin or window.spookyWallet

Property Type Description
isSpookyWallet boolean Always true - identifies the wallet
isConnected() function Returns true if site is connected

Methods

connect()

Request wallet connection. Opens approval popup.

Returns: Promise<{ address: string }>

disconnect()

Disconnect the dApp from the wallet.

Returns: Promise<void>

getAddress()

Get the currently connected address.

Returns: Promise<string | null> - Null if not connected

getAccounts()

Get all connected accounts.

Returns: Promise<string[]>

getBalance()

Get wallet balance in koinu.

Returns: Promise<number> - Balance in koinu (divide by 100,000,000 for DOGE)

getDoginals()

Get all doginals (inscriptions) in the wallet.

Returns: Promise<Doginal[]>

interface Doginal {
  inscriptionId: string;  // Unique inscription identifier
  output: string;         // UTXO reference (txid:vout)
  contentType: string;    // MIME type (e.g., 'image/png', 'text/html')
  imageUrl: string;       // CDN URL for the content
  value?: number;        // UTXO value in DOGE (optional)
}

sendTransaction(params)

Request a DOGE transaction. Opens approval popup. Supports both simple single-output and advanced multi-output formats.

Parameters (Simple):

{
  to: string;      // Recipient Dogecoin address
  amount: number;  // Amount in DOGE (not koinu)
}

Parameters (Multi-Output):

{
  outputs: Array<{
    address: string;  // Recipient Dogecoin address
    amount: number;   // Amount in DOGE
  }>;
}
Marketplace Tip: Use multi-output to include your marketplace fee in the same transaction. Each output is shown to the user for approval, ensuring full transparency.
Fee Structure: All transactions include a 0.01 DOGE wallet fee plus network fees (~0.02 DOGE). These are shown separately in the approval dialog so users see exactly where their funds go.

Returns: Promise<{ txid: string }>

sendDoginal(params)

Request a doginal transfer. Opens approval popup. Supports both single and multiple inscription transfers.

Parameters:

{
  inscriptionId: string | string[];  // Single ID or array of inscription IDs
  to: string;                        // Recipient Dogecoin address
}
Multi-Send: Pass an array of inscription IDs to transfer multiple doginals in a single transaction. Fees scale per inscription: 0.02 DOGE network fee + 0.01 DOGE wallet fee = 0.03 DOGE per inscription. The approval dialog shows each fee component separately.

Returns: Promise<{ txid: string }>

signMessage(message)

Request a message signature. Opens approval popup. Free - no DOGE cost

Parameters: message (string) - The message to sign

Returns: Promise<{ signature: string, address: string }>

The signature is in Bitcoin/Dogecoin signed message format (base64-encoded, 65 bytes), compatible with verifymessage in Dogecoin Core.

signPsbt(params)

Request signing of a partially signed transaction (PSBT). Opens approval popup. Marketplace Integration

This method enables marketplaces to request partial transaction signing for trading Doginals, DRC-20 tokens, and Dunes. The wallet signs only the specified inputs, returning the signed hex to the marketplace for finalization and broadcast.

Accepted formats: Both BIP174 PSBT format (industry standard, starts with magic bytes 70736274ff) and raw transaction hex are supported. If BIP174 is provided, the wallet returns a signed BIP174 PSBT with partial signatures added. If raw hex is provided, the wallet returns a signed raw transaction hex.

Parameters:

{
  psbtHex: string;        // BIP174 PSBT hex or raw transaction hex
  signInputs?: number[];  // Input indices to sign (default: all)
  sighashTypes?: number[]; // Per-input sighash types (default: [0x01] SIGHASH_ALL)
  message?: string;       // Optional message to display to user (e.g. "Buy Doginal #1234 for 500 DOGE")
  imageUrl?: string;      // Optional image URL to display in approval popup (e.g. doginal thumbnail)
}

Returns: Promise<{ signedPsbtHex: string }>

Supported sighash types:

TypeValueUse Case
SIGHASH_ALL0x01Default — signs all inputs and outputs (buyer purchases)
SIGHASH_NONE0x02Signs inputs but no outputs
SIGHASH_SINGLE0x03Signs only the output at the same index as the input
SIGHASH_ALL|ANYONECANPAY0x81Signs one input and all outputs
SIGHASH_NONE|ANYONECANPAY0x82Signs one input, no outputs
SIGHASH_SINGLE|ANYONECANPAY0x83Marketplace listings — seller signs their input + matching output, buyer can add inputs/outputs later
Marketplace Tip: Sellers should use SIGHASH_SINGLE|ANYONECANPAY (0x83) when listing. This lets the buyer add their payment inputs and change outputs without invalidating the seller's signature. Buyers should use SIGHASH_ALL (0x01) to finalize the transaction.
Message Formatting: The wallet parses the message parameter to enhance the approval popup:
Security Note: Users must review and explicitly approve each PSBT signing request. The approval popup displays the origin, transaction data, and any message from the marketplace.

Example: Marketplace Listing (Seller)

async function listDoginal(psbtHex, inputsToSign, doginalInfo) {
  try {
    const result = await window.dogecoin.signPsbt({
      psbtHex: psbtHex,
      signInputs: inputsToSign,
      message: `List ${doginalInfo.name} for ${doginalInfo.price} DOGE`,
      imageUrl: doginalInfo.thumbnailUrl
    });
    
    // Store the signed PSBT as an active listing on your marketplace
    return result.signedPsbtHex;
  } catch (error) {
    console.error('Listing failed:', error.message);
    throw error;
  }
}

Example: Marketplace Purchase (Buyer)

async function buyDoginal(psbtHex, buyerInputs, doginalInfo) {
  try {
    const result = await window.dogecoin.signPsbt({
      psbtHex: psbtHex,
      signInputs: buyerInputs,
      message: `Buy ${doginalInfo.name} for ${doginalInfo.price} DOGE`,
      imageUrl: doginalInfo.thumbnailUrl
    });
    
    // PSBT is now fully signed (seller + buyer), finalize and broadcast
    return result.signedPsbtHex;
  } catch (error) {
    console.error('Purchase failed:', error.message);
    throw error;
  }
}

signPsbts(params) Batch Marketplace

Request batch signing of multiple PSBTs at once. Opens a single approval popup showing all transactions. Used for batch marketplace operations.

This method enables marketplaces to request signing of multiple transactions in a single user interaction. Ideal for listing multiple Doginals, DRC-20 tokens, or Dunes at once. Each PSBT is signed independently, so buyers can purchase individual listings separately.

Parameters:

{
  psbts: Array<{
    psbtHex: string;        // BIP174 PSBT hex or raw transaction hex
    signInputs?: number[];  // Input indices to sign (default: all)
    sighashTypes?: number[]; // Per-input sighash types (default: [0x01] SIGHASH_ALL)
    message?: string;       // Optional message for this transaction (e.g. "List Doginal #1234 for 500 DOGE")
    imageUrl?: string;      // Optional image URL for this transaction (e.g. doginal thumbnail)
  }>
}

Returns: Promise<{ signedPsbts: Array<{ signedPsbtHex: string }> }>

The returned signedPsbts array matches the order of the input psbts array.

Security Note: Users see a single approval popup with a scrollable list of all transactions. They can review each item before approving or rejecting the entire batch.
Example: Batch Listing Multiple Doginals
async function batchListDoginals(listings) {
  try {
    const result = await window.dogecoin.signPsbts({
      psbts: listings.map(listing => ({
        psbtHex: listing.psbtHex,
        signInputs: listing.inputsToSign,
        message: `List ${listing.name} for ${listing.price} DOGE`,
        imageUrl: listing.thumbnailUrl
      }))
    });
    
    // Each signed PSBT is independent - store each as a separate listing
    result.signedPsbts.forEach((signed, index) => {
      console.log(`Listed ${listings[index].name}:`, signed.signedPsbtHex);
    });
    
    return result.signedPsbts;
  } catch (error) {
    console.error('Batch listing failed:', error.message);
    throw error;
  }
}
Via request() Method
const result = await window.dogecoin.request({
  method: 'doge_signPsbts',
  params: {
    psbts: [
      { psbtHex: '...', message: 'List Doginal #1 for 100 DOGE', imageUrl: 'https://...' },
      { psbtHex: '...', message: 'List Doginal #2 for 200 DOGE', imageUrl: 'https://...' }
    ]
  }
});

batchSendDune(params) Batch / Airdrop

Batch send a Dunes token to up to 1000 recipients in one operation. The wallet automatically splits recipients into batches that fit within Dogecoin's 80-byte OP_RETURN relay limit (~10-12 per transaction depending on amounts). Opens a single approval popup showing all recipients, amounts, batch count, and fee breakdown. Designed for airdrop tools and staking reward distribution.

Parameters:

{
  duneName: string;       // Dune name (e.g., "MY.DUNE")
  duneId: string;         // Dune ID (e.g., "5000000:42")
  divisibility: number;   // Token divisibility (e.g., 8)
  recipients: Array<{
    address: string;      // Recipient Dogecoin address
    amount: string;       // Amount as string (e.g., "100")
  }>;
}

Returns:

Promise<{
  txids: string[];          // Transaction IDs for each batch
  totalRecipients: number;  // Total recipients processed
}>

Limits: Maximum 1000 recipients per call. Each batch contains ~10-12 recipients (calculated dynamically based on OP_RETURN payload size). The wallet chains change UTXOs between batches automatically.

Fee Structure
Fee ComponentAmountNotes
Size-based network fee~0.005 DOGEPer batch, scales with actual tx size (0.01 DOGE/KB)
Dust penalty0.01 DOGEPer dust output (recipients + dune change)
Dev fee0.01 DOGEPer batch

Example fee calculations (assuming 10 recipients per batch):

Example
const result = await window.dogecoin.request({
  method: 'doge_batchSendDune',
  params: {
    duneName: 'MY.DUNE',
    duneId: '5000000:42',
    divisibility: 8,
    recipients: [
      { address: 'DAddr1...', amount: '100' },
      { address: 'DAddr2...', amount: '250' },
      { address: 'DAddr3...', amount: '500' },
      // ... up to 1000 recipients
    ]
  }
});
console.log('Batch TXIDs:', result.txids);
console.log('Total recipients:', result.totalRecipients);
How It Works
  1. Approval — User reviews recipient list, amounts, batch count, and fee breakdown
  2. Batch calculation — Wallet dynamically determines max recipients per batch based on OP_RETURN payload size (80-byte Dogecoin relay limit)
  3. Sequential batches — Each batch is a single multi-recipient dune transaction. Dune change (0.001 DOGE dust) from batch N feeds as dune input to batch N+1. DOGE change feeds as fee input.
  4. Mempool safety — Pauses at 20 unconfirmed ancestors (Dogecoin's 25-ancestor limit). Auto-retries on mempool chain errors with 60-second waits.
  5. Dune safety — All dune balances always sit on dedicated 0.001 DOGE dust outputs. Dune change never mixes with DOGE change.
Note on batch size: The number of recipients per batch depends on the duneId and amounts being sent. Larger duneIds and amounts use more bytes in the Runestone encoding, resulting in fewer recipients per batch. Typical values are 10-12 per batch.

batchSendDrc20(params) Batch / Airdrop

Batch send a DRC-20 token to up to 500 recipients in one operation. Opens approval popup showing all recipients with amounts and fee breakdown. Designed for airdrop tools and staking reward distribution.

Parameters:

{
  tick: string;    // DRC-20 token ticker (e.g., "SLIME")
  recipients: Array<{
    address: string;  // Recipient Dogecoin address
    amount: string;   // Amount as string (e.g., "1000")
  }>;
}

Returns:

Promise<{
  distributionTxids: string[];   // Distribution transaction IDs
  inscriptionTxids: string[];    // All commit+reveal transaction IDs
  completedRecipients: number;   // Recipients successfully processed
  totalRecipients: number;       // Total requested
}>

Limits: Maximum 500 recipients per call. Distribution auto-splits at ~95KB.

Fee structure:

Example: 50 recipients ≈ 2.54 DOGE total. 500 recipients ≈ 25.04 DOGE total.

const result = await window.dogecoin.request({
  method: 'doge_batchSendDrc20',
  params: {
    tick: 'SLIME',
    recipients: [
      { address: 'DAddr1...', amount: '1000' },
      { address: 'DAddr2...', amount: '500' },
      { address: 'DAddr3...', amount: '2500' },
    ]
  }
});
console.log('Distribution TXIDs:', result.distributionTxids);

request(args)

EIP-1193 style request method for compatibility.

// Examples
const accounts = await window.dogecoin.request({ method: 'doge_requestAccounts' });
const balance = await window.dogecoin.request({ method: 'doge_getBalance' });
const doginals = await window.dogecoin.request({ method: 'doge_getDoginals' });
const result = await window.dogecoin.request({
  method: 'doge_sendTransaction',
  params: { to: 'DAddress...', amount: 10 }
});

Supported Methods:

Method Description
doge_requestAccountsRequest wallet connection
doge_accountsGet connected accounts
doge_getBalanceGet wallet balance
doge_getDoginalsGet doginals in wallet (supports pagination)
doge_sendTransactionSend DOGE (single or multi-output)
doge_sendDoginalTransfer doginals (single or batch)
doge_getDrc20BalancesGet DRC-20 token balances
doge_sendDrc20Send DRC-20 tokens
doge_getDunesBalancesGet Dunes token balances
doge_sendDuneSend Dunes tokens
doge_sendDuneMultiSend Dunes tokens to multiple recipients in one tx
doge_batchSendDuneBatch send Dunes tokens to up to 1000 recipients (airdrop/rewards)
doge_batchSendDrc20Batch send DRC-20 tokens to up to 500 recipients (airdrop/rewards)
doge_signMessageSign a message (free, no DOGE cost)
doge_signPsbtSign a partially signed transaction (marketplace integration)
doge_signPsbtsBatch sign multiple PSBTs at once (marketplace batch listing)
doge_chainIdGet chain identifier ("dogecoin:mainnet")

on(event, callback)

Subscribe to wallet events.

Events:

removeListener(event, callback)

Unsubscribe from wallet events.


Fee Structure

Transaction Type Network Fee Dev Fee Total
Regular DOGE send Dynamic (based on tx size) 0.01 DOGE Variable
Doginal transfer 0.02 DOGE 0.01 DOGE 0.03 DOGE
Multi-doginal transfer 0.02 DOGE x count 0.01 DOGE Variable
DRC-20 transfer 0.02 DOGE 0.01 DOGE 0.03 DOGE
Dune transfer 0.02 DOGE 0.01 DOGE 0.03 DOGE
Multi-dune transfer 0.20 DOGE 0.01 DOGE 0.21 DOGE
Batch Dune airdrop ~0.005 DOGE/batch + 0.01 DOGE per dust output 0.01 DOGE/batch ~0.125 DOGE (10 recipients), ~12.5 DOGE (1000 recipients)
Batch DRC-20 airdrop 0.02 DOGE x 2 per recipient + distribution fee (0.02 + 0.01/recipient dust penalty) 0.01 DOGE ~2.54 DOGE (50 recipients)

Error Handling

Error Message Cause
"Connection rejected by user"User declined connection request
"Site not connected"dApp not connected to wallet
"Wallet not unlocked"User hasn't unlocked the wallet
"Transaction rejected by user"User declined transaction
"Doginal transfer rejected by user"User declined doginal transfer
"Message signing rejected by user"User declined signature request
"DRC-20 transfer rejected by user"User declined DRC-20 transfer
"Dune transfer rejected by user"User declined Dune transfer
"PSBT signing rejected by user"User declined PSBT signing request
"Batch PSBT signing rejected by user"User declined batch PSBT signing request
"Invalid PSBT params: psbtHex is required"Missing psbtHex parameter
"Invalid batch PSBT params: psbts array is required"Missing or empty psbts array parameter
"Insufficient funds"Not enough DOGE for transaction + fees
"Inscription not found in wallet"Requested inscription not in wallet
"Batch DRC-20 send rejected by user"User declined batch DRC-20 airdrop
"Batch Dune send rejected by user"User declined batch Dune airdrop
"Not enough DOGE for batch fees"Insufficient DOGE to cover inscription + distribution fees

Security Notes

  1. User Approval Required - All transactions require explicit user approval via popup
  2. Per-Site Permissions - Each website must be approved separately; users can manage connections in Settings
  3. Non-Custodial - Private keys never leave the wallet
  4. Inscription Protection - UTXOs under 0.1 DOGE are protected from regular spending
  5. Dev Fee Transparency - 0.01 DOGE dev fee included in all transactions

Platform Notes

Browser Extension

Mobile App

Suggesting Users Open in Spooky Doge

if (!isSpookyWalletAvailable()) {
  // Show a banner or modal
  showModal({
    title: 'Use Spooky Doge Wallet',
    message: 'For the best experience, open this site in the Spooky Doge app browser.',
    buttons: [
      { text: 'Get the App', url: 'https://spooksociety.xyz' },
      { text: 'Continue Anyway', action: 'dismiss' }
    ]
  });
}

Support

For integration support or questions: