Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/blindpaylabs/blindpay-node/llms.txt

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

Blockchain wallets are destination addresses where stablecoins are deposited after payin conversions or sources for payout conversions. This guide covers creating, verifying, and managing blockchain wallets across different networks.

Overview

BlindPay supports blockchain wallets on multiple networks:
  • EVM chains: Ethereum, Polygon, Base, Arbitrum, Optimism, etc.
  • Stellar: Stellar network
  • Solana: Solana network
Each receiver can have multiple wallets across different networks.

Wallet Types

BlindPay supports two types of wallets:

Account Abstraction Wallets

Modern wallets that provide better UX and security. Simply provide the wallet address.
const { data: wallet, error } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'Main Wallet',
  network: 'polygon',
  address: '0xDD6a3aD0949396e57C7738ba8FC1A46A5a1C372C'
});

Traditional Wallets

Require signature verification to prove ownership. You must sign a message and provide the transaction hash.
// Step 1: Get the message to sign
const { data: messageData, error: msgError } = 
  await blindpay.wallets.blockchain.getWalletMessage('re_000000000000');

// Step 2: Sign the message with your wallet
// const signature = await wallet.signMessage(messageData.message);
// const txHash = '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359';

// Step 3: Create wallet with transaction hash
const { data: wallet, error } = await blindpay.wallets.blockchain.createWithHash({
  receiver_id: 're_000000000000',
  name: 'Main Wallet',
  network: 'polygon',
  signature_tx_hash: txHash
});
Use Account Abstraction wallets (createWithAddress) for simpler integration. Traditional wallets (createWithHash) are for backward compatibility.

Creating Wallets

EVM Wallets (Polygon, Base, Ethereum, etc.)

1

Create EVM wallet

import { BlindPay } from '@blindpay/sdk';

const blindpay = new BlindPay({
  apiKey: process.env.BLINDPAY_API_KEY,
  instanceId: process.env.BLINDPAY_INSTANCE_ID
});

const { data: wallet, error } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'Polygon USDC Wallet',
  network: 'polygon',
  address: '0xYourWalletAddress'
});

if (error) {
  console.error('Error creating wallet:', error.message);
  return;
}

console.log('Wallet created:', {
  id: wallet.id,
  name: wallet.name,
  network: wallet.network,
  address: wallet.address,
  is_account_abstraction: wallet.is_account_abstraction
});

Stellar Wallets

1

Create Stellar wallet

const { data: wallet, error } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'Stellar USDC Wallet',
  network: 'stellar',
  address: 'GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B'
});

console.log('Stellar wallet created:', wallet);
2

Create asset trustline (if needed)

For USDB on Stellar, you need to create a trustline:
const { data: trustline, error } = 
  await blindpay.wallets.blockchain.createAssetTrustline(
    'GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B'
  );

if (error) {
  console.error('Error creating trustline:', error.message);
  return;
}

// Sign and submit the XDR transaction
console.log('Sign this XDR:', trustline.xdr);
// Use Stellar SDK to sign and submit

Solana Wallets

1

Create Solana wallet

const { data: wallet, error } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'Solana USDC Wallet',
  network: 'solana',
  address: '7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5'
});

console.log('Solana wallet created:', wallet);

Network Examples

const { data: wallet } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'Polygon Wallet',
  network: 'polygon',
  address: '0xYourAddress'
});

Managing Wallets

List Wallets

// Get all wallets for a receiver
const { data: wallets, error } = await blindpay.wallets.blockchain.list(
  're_000000000000'
);

if (error) {
  console.error('Error listing wallets:', error.message);
  return;
}

wallets.forEach(wallet => {
  console.log(`${wallet.name} (${wallet.network}):`, {
    id: wallet.id,
    address: wallet.address,
    is_account_abstraction: wallet.is_account_abstraction
  });
});

Get Specific Wallet

const { data: wallet, error } = await blindpay.wallets.blockchain.get({
  receiver_id: 're_000000000000',
  id: 'bw_000000000000'
});

if (error) {
  console.error('Error fetching wallet:', error.message);
  return;
}

console.log('Wallet details:', wallet);

Delete Wallet

const { data, error } = await blindpay.wallets.blockchain.delete({
  receiver_id: 're_000000000000',
  id: 'bw_000000000000'
});

if (error) {
  console.error('Error deleting wallet:', error.message);
  return;
}

console.log('Wallet deleted successfully');
Deleting a wallet that’s linked to a virtual account will cause future deposits to fail. Update the virtual account first.

Advanced: USDB Token Operations

Mint USDB on Stellar

const { data, error } = await blindpay.wallets.blockchain.mintUsdbStellar({
  address: 'GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B',
  amount: '1000000', // Amount in stroops
  signedXdr: 'AAAAAgAAAABqVFqpZzXx...' // Signed XDR transaction
});

if (error) {
  console.error('Error minting USDB:', error.message);
  return;
}

console.log('USDB minted successfully');

Mint USDB on Solana

const { data, error } = await blindpay.wallets.blockchain.mintUsdbSolana({
  address: '7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5',
  amount: '1000000' // Amount in lamports
});

if (error) {
  console.error('Error minting USDB:', error.message);
  return;
}

console.log('USDB minted:', {
  success: data.success,
  signature: data.signature
});

Prepare Solana Delegation Transaction

const { data, error } = 
  await blindpay.wallets.blockchain.prepareSolanaDelegationTransaction({
    token_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
    amount: '1000000',
    owner_address: '7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5'
  });

if (error) {
  console.error('Error preparing delegation:', error.message);
  return;
}

console.log('Delegation transaction:', {
  success: data.success,
  transaction: data.transaction // Base64 encoded transaction
});

// Sign and submit the transaction with your Solana wallet

Traditional Wallet Verification Flow

For wallets that require signature verification:
1

Get message to sign

const { data: messageData, error } = 
  await blindpay.wallets.blockchain.getWalletMessage('re_000000000000');

if (error) {
  console.error('Error getting message:', error.message);
  return;
}

console.log('Message to sign:', messageData.message);
2

Sign message with wallet

Use your wallet library to sign the message:
// Example with ethers.js
// const signer = provider.getSigner();
// const signature = await signer.signMessage(messageData.message);
// const tx = await signer.sendTransaction({
//   to: '0xRecipient',
//   value: 0,
//   data: signature
// });
// const txHash = tx.hash;
3

Create wallet with signature

const { data: wallet, error } = await blindpay.wallets.blockchain.createWithHash({
  receiver_id: 're_000000000000',
  name: 'Verified Wallet',
  network: 'polygon',
  signature_tx_hash: '0x3c499c542cef5e3811e1192ce70d8cc03d5c3359'
});

console.log('Wallet verified and created:', wallet);

Complete Example

import { BlindPay } from '@blindpay/sdk';

const blindpay = new BlindPay({
  apiKey: process.env.BLINDPAY_API_KEY,
  instanceId: process.env.BLINDPAY_INSTANCE_ID
});

async function setupReceiverWallets(receiverId: string) {
  // Create wallets on multiple networks
  const wallets = await Promise.all([
    // Polygon for low fees
    blindpay.wallets.blockchain.createWithAddress({
      receiver_id: receiverId,
      name: 'Polygon USDC',
      network: 'polygon',
      address: '0xYourPolygonAddress'
    }),
    // Base for fast settlements
    blindpay.wallets.blockchain.createWithAddress({
      receiver_id: receiverId,
      name: 'Base USDC',
      network: 'base',
      address: '0xYourBaseAddress'
    }),
    // Solana for speed
    blindpay.wallets.blockchain.createWithAddress({
      receiver_id: receiverId,
      name: 'Solana USDC',
      network: 'solana',
      address: 'YourSolanaAddress'
    })
  ]);

  // Check for errors
  const failed = wallets.filter(w => w.error);
  if (failed.length > 0) {
    console.error('Some wallets failed:', failed);
  }

  // List all created wallets
  const { data: allWallets } = await blindpay.wallets.blockchain.list(receiverId);
  console.log('Total wallets:', allWallets.length);
  
  return allWallets;
}

// Usage
setupReceiverWallets('re_000000000000')
  .then(wallets => {
    wallets.forEach(w => {
      console.log(`${w.name}: ${w.address} on ${w.network}`);
    });
  })
  .catch(error => {
    console.error('Setup failed:', error);
  });

Error Handling

const { data: wallet, error } = await blindpay.wallets.blockchain.createWithAddress({
  receiver_id: 're_000000000000',
  name: 'My Wallet',
  network: 'polygon',
  address: '0xInvalidAddress'
});

if (error) {
  if (error.message.includes('invalid address')) {
    console.error('Invalid wallet address format');
  } else if (error.message.includes('network')) {
    console.error('Unsupported network');
  } else if (error.message.includes('receiver')) {
    console.error('Receiver not found or not approved');
  } else {
    console.error('Unknown error:', error.message);
  }
  return;
}

Best Practices

  1. Multiple Networks: Create wallets on multiple networks to give flexibility
  2. Naming Convention: Use descriptive names like “Polygon USDC Wallet” for clarity
  3. Account Abstraction: Prefer AA wallets for simpler UX
  4. Address Validation: Validate addresses client-side before API calls
  5. Network Matching: Ensure wallet network matches the payin/payout network
  6. Wallet Limits: There’s no hard limit on wallets per receiver, but keep it reasonable
  7. Default Wallet: Consider marking one wallet as “primary” in your application
  8. Gas Considerations: Choose networks with lower gas fees for small transactions

Network Recommendations

NetworkBest ForFeesSpeed
PolygonHigh volume, low feesVery LowFast
BaseCoinbase integrationLowVery Fast
SolanaSpeed & costVery LowVery Fast
EthereumMaximum securityHighModerate
ArbitrumDeFi integrationLowFast
OptimismEthereum L2LowFast
StellarCross-borderVery LowFast
For most use cases, start with Polygon (low fees) or Base (Coinbase ecosystem). Add other networks as needed.

Next Steps

  • Learn about virtual accounts that use blockchain wallets
  • Set up payins to receive stablecoins to these wallets
  • Create payouts to send from these wallets

Build docs developers (and LLMs) love