Skip to content

Sign Transactions

Learn how to sign and broadcast transactions with Cave Wallet.

Basic Transaction

Send Tokens

javascript
const tx = {
  to: 'g1recipientaddress...',
  amount: '1000000ugnot', // 1 GNOT
  memo: 'Payment for services'
};

try {
  const result = await wallet.signAndBroadcast(tx);
  console.log('TX Hash:', result.hash);
} catch (error) {
  console.error('Transaction failed:', error);
}

Transaction Types

Token Transfer

javascript
const transferTx = {
  type: 'transfer',
  to: 'g1recipient...',
  amount: '1000000ugnot',
  memo: 'Optional memo'
};

await wallet.signAndBroadcast(transferTx);

Contract Call

javascript
const contractTx = {
  type: 'call',
  contract: 'g1contract...',
  function: 'Transfer',
  args: ['g1recipient...', '1000000'],
  gasLimit: 100000
};

await wallet.signAndBroadcast(contractTx);

Multiple Messages

javascript
const multiTx = {
  messages: [
    {
      type: 'transfer',
      to: 'g1addr1...',
      amount: '500000ugnot'
    },
    {
      type: 'transfer',
      to: 'g1addr2...',
      amount: '500000ugnot'
    }
  ]
};

await wallet.signAndBroadcast(multiTx);

Sign Without Broadcasting

Sometimes you need to sign without broadcasting:

javascript
// Just sign
const signedTx = await wallet.signTransaction(tx);
console.log('Signed TX:', signedTx);

// Broadcast later
const result = await wallet.broadcast(signedTx);

Message Signing

Sign Arbitrary Data

javascript
const message = 'Hello, Cave Wallet!';
const signature = await wallet.signMessage(message);

console.log('Signature:', signature);

Verify Signature

javascript
const isValid = await wallet.verifySignature(
  message,
  signature,
  account.address
);

console.log('Valid:', isValid);

Gas Estimation

Estimate Before Sending

javascript
const gasEstimate = await wallet.estimateGas(tx);

console.log('Estimated gas:', gasEstimate);

// Send with buffer
tx.gasLimit = Math.ceil(gasEstimate * 1.2);
await wallet.signAndBroadcast(tx);

Error Handling

Common Errors

javascript
try {
  await wallet.signAndBroadcast(tx);
} catch (error) {
  switch (error.code) {
    case 4001:
      console.log('User rejected transaction');
      break;
    case -32000:
      console.log('Insufficient funds');
      break;
    case -32603:
      console.log('Internal error');
      break;
    default:
      console.log('Unknown error:', error.message);
  }
}

Transaction Status

javascript
const result = await wallet.signAndBroadcast(tx);

// Check status
const status = await wallet.getTransactionStatus(result.hash);

if (status.confirmed) {
  console.log('Transaction confirmed!');
} else if (status.failed) {
  console.log('Transaction failed:', status.error);
} else {
  console.log('Transaction pending...');
}

Best Practices

1. Always Estimate Gas

javascript
const gas = await wallet.estimateGas(tx);
tx.gasLimit = gas + 10000; // Add buffer

2. Show Clear UI

javascript
// Show loading state
setLoading(true);

try {
  const result = await wallet.signAndBroadcast(tx);
  showSuccess(`Transaction sent: ${result.hash}`);
} catch (error) {
  showError(error.message);
} finally {
  setLoading(false);
}

3. Validate Before Sending

javascript
function validateTx(tx) {
  if (!tx.to) throw new Error('Recipient required');
  if (!tx.amount) throw new Error('Amount required');
  if (parseFloat(tx.amount) <= 0) throw new Error('Invalid amount');
}

validateTx(tx);
await wallet.signAndBroadcast(tx);

Complete Example

javascript
async function sendPayment(recipient, amount) {
  // Validate
  if (!recipient || !amount) {
    throw new Error('Missing parameters');
  }
  
  // Prepare transaction
  const tx = {
    to: recipient,
    amount: `${amount}ugnot`,
    memo: 'Payment'
  };
  
  // Estimate gas
  const gasEstimate = await wallet.estimateGas(tx);
  tx.gasLimit = Math.ceil(gasEstimate * 1.2);
  
  // Sign and broadcast
  const result = await wallet.signAndBroadcast(tx);
  
  // Wait for confirmation
  let confirmed = false;
  while (!confirmed) {
    const status = await wallet.getTransactionStatus(result.hash);
    if (status.confirmed) {
      confirmed = true;
    } else if (status.failed) {
      throw new Error(status.error);
    }
    await sleep(1000);
  }
  
  return result;
}

Next Steps

The Gno.land Wallet