๐ Common Issues & Solutions โ
Your troubleshooting guide for Fleet SDK development
Quick Diagnosis โ
| Symptom | Likely Cause | Quick Fix |
|---|---|---|
| "Insufficient funds" | Not enough ERG | Check balance, add more inputs |
| "Box value too small" | Output below minimum | Use SAFE_MIN_BOX_VALUE |
| "Invalid address" | Wrong network/format | Verify address format |
| "Height mismatch" | Outdated height | Fetch current height |
| "Token not found" | Wrong token ID | Verify 64-char hex ID |
๐ฐ Transaction Issues โ
Issue: "Insufficient Funds" โ
Symptoms:
Error: Insufficient inputs to cover outputsCause: Your input boxes don't have enough ERG to cover:
- Output amounts
- Network fee
- Minimum box value for change
Solution:
import { RECOMMENDED_MIN_FEE_VALUE, SAFE_MIN_BOX_VALUE } from "@fleet-sdk/core";
// Calculate total required
const totalRequired =
outputAmount +
RECOMMENDED_MIN_FEE_VALUE +
SAFE_MIN_BOX_VALUE; // For change box
// Verify before building
const totalInput = inputs.reduce((sum, box) => sum + box.value, 0n);
if (totalInput < totalRequired) {
throw new Error(`Need ${totalRequired} nanoERG, have ${totalInput}`);
}Prevention:
- Always check balance before transaction
- Include buffer for fees
- Account for change output minimum
Issue: "Box Value Too Small" โ
Symptoms:
Error: Output box value is below minimumCause: Ergo boxes must contain a minimum amount of ERG (~0.001 ERG)
Solution:
import { SAFE_MIN_BOX_VALUE } from "@fleet-sdk/core";
// Ensure output meets minimum
const outputValue = Math.max(yourAmount, SAFE_MIN_BOX_VALUE);
// For token-only transfers, still need ERG:
const tokenOutput = new OutputBuilder(
SAFE_MIN_BOX_VALUE, // Minimum ERG as "carrier"
recipientAddress
).addTokens({ tokenId, amount: tokenAmount });Key Values:
SAFE_MIN_BOX_VALUE = 1_000_000n; // 0.001 ERG (recommended)
RECOMMENDED_MIN_FEE_VALUE = 1_100_000n; // 0.0011 ERGIssue: "Invalid Address Format" โ
Symptoms:
Error: Invalid address encoding
Error: Address network mismatchCause:
- Address is malformed
- Using mainnet address on testnet (or vice versa)
- Missing or extra characters
Solution:
// Ergo addresses typically:
// - Start with "9" for mainnet P2PK
// - Start with "3" for P2S (script) addresses
// - Are 51-52 characters long
function validateAddress(address: string): boolean {
// Basic format check
if (address.length < 40 || address.length > 60) {
return false;
}
// Check network prefix
const validPrefixes = ["9", "3"]; // Mainnet
// For testnet, addresses also start with "9" or "3"
return validPrefixes.some(p => address.startsWith(p));
}Testnet vs Mainnet:
- Both use similar address formats
- Test with testnet first!
- Testnet faucet: https://testnet.ergoplatform.com/en/faucet/
๐ช Token Issues โ
Issue: "Token Not Found" โ
Symptoms:
Error: Token ID not found in inputs
Error: Cannot add non-existent tokenCause:
- Token ID is incorrect
- Token not present in input boxes
- Typo in 64-character hex string
Solution:
// Token IDs are exactly 64 hex characters
const TOKEN_ID = "03faf2cb329f2e90d6d23b58d91bbb6c046aa143261cc21f52fbe2824bfcbf04";
// Verify token exists in inputs
function findTokenInInputs(inputs: Box[], tokenId: string): bigint {
let total = 0n;
for (const box of inputs) {
const token = box.assets.find(a => a.tokenId === tokenId);
if (token) {
total += token.amount;
}
}
return total;
}
// Check before transfer
const available = findTokenInInputs(inputs, TOKEN_ID);
if (available < amountToSend) {
throw new Error(`Token balance: ${available}, need: ${amountToSend}`);
}Issue: "Token Amount Mismatch" โ
Symptoms:
Error: Token output amount exceeds inputCause: Trying to send more tokens than available in inputs
Solution:
// Calculate available tokens
const inputTokens = inputs
.flatMap(box => box.assets)
.filter(asset => asset.tokenId === targetTokenId)
.reduce((sum, asset) => sum + asset.amount, 0n);
// Ensure you're not creating tokens out of thin air
if (outputTokenAmount > inputTokens) {
throw new Error("Cannot send more tokens than you have");
}
// Remaining tokens go to change automatically
// Fleet SDK handles this when you use sendChangeTo()๐ Contract Issues โ
Issue: "Compilation Error" โ
Symptoms:
Error: ErgoScript compilation failed
Error: Syntax error at position XCause: Invalid ErgoScript syntax
Common Mistakes:
// โ WRONG: Missing val keyword
height > 1000000
// โ
CORRECT: Use sigmaProp wrapper
sigmaProp(HEIGHT > 1000000L)
// โ WRONG: Using = instead of ==
val condition = x = 5
// โ
CORRECT: Use == for comparison
val condition = x == 5
// โ WRONG: Lowercase height
sigmaProp(height > 1000)
// โ
CORRECT: HEIGHT is uppercase
sigmaProp(HEIGHT > 1000L)
// โ WRONG: Missing L suffix for Long
val amount = 1000000000
// โ
CORRECT: Add L for Long literals
val amount = 1000000000LIssue: "Cannot Spend from Contract" โ
Symptoms:
Error: Script validation failed
Error: Spending conditions not metCause: Contract conditions not satisfied
Debugging Steps:
// 1. Check HEIGHT condition
console.log(`Current height: ${currentHeight}`);
console.log(`Required height: ${contractUnlockHeight}`);
if (currentHeight < contractUnlockHeight) {
console.log("โ HEIGHT condition not met");
}
// 2. Check signature requirements
// Ensure you're signing with the correct key
// 3. Check OUTPUTS conditions
// Contract might require specific output structure
// 4. Use mock-chain for testing
import { MockChain } from "@fleet-sdk/mock-chain";
const chain = new MockChain();
// Test contract spending locally before mainnet๐ง Setup Issues โ
Issue: "Module Not Found" โ
Symptoms:
Error: Cannot find module '@fleet-sdk/core'Solution:
# Make sure packages are installed
npm install @fleet-sdk/core @fleet-sdk/wallet
# If using pnpm
pnpm add @fleet-sdk/core @fleet-sdk/wallet
# Clear node_modules and reinstall
rm -rf node_modules package-lock.json
npm installIssue: "TypeScript Errors" โ
Symptoms:
Error: Type 'bigint' is not assignable to type 'number'Solution:
// Fleet SDK uses BigInt for amounts
// Make sure to use n suffix for literals
const amount = 1_000_000_000n; // โ
BigInt
// Convert if needed
const amountNumber = Number(amount); // For display
const amountBigInt = BigInt(numberValue); // For transactions
// In tsconfig.json, ensure:
{
"compilerOptions": {
"target": "ES2020", // or higher for BigInt support
"lib": ["ES2020"]
}
}๐ Network Issues โ
Issue: "Connection Failed" โ
Symptoms:
Error: Failed to fetch from node
Error: Network timeoutSolution:
// Use multiple providers as fallback
const ENDPOINTS = [
"https://api.ergoplatform.com",
"https://ergo-explorer.anetabtc.io",
// Add backup endpoints
];
async function fetchWithFallback(path: string) {
for (const endpoint of ENDPOINTS) {
try {
const response = await fetch(`${endpoint}${path}`);
if (response.ok) return response;
} catch (e) {
console.log(`Endpoint ${endpoint} failed, trying next...`);
}
}
throw new Error("All endpoints failed");
}Issue: "Transaction Rejected" โ
Symptoms:
Error: Transaction rejected by mempool
Error: Double spending detectedCause:
- Input box already spent
- Invalid transaction format
- Fee too low
Solution:
// 1. Refresh input boxes before building tx
const freshInputs = await fetchCurrentBoxes(address);
// 2. Use adequate fee
import { RECOMMENDED_MIN_FEE_VALUE } from "@fleet-sdk/core";
// 3. Check box is unspent
async function isBoxUnspent(boxId: string): Promise<boolean> {
const response = await fetch(`/api/boxes/${boxId}`);
const box = await response.json();
return !box.spentTransactionId;
}๐ Debugging Tips โ
Enable Verbose Logging โ
// Add logging to understand transaction flow
function logTransaction(tx: any) {
console.log("๐ฆ Transaction Summary:");
console.log(` Inputs: ${tx.inputs.length}`);
console.log(` Outputs: ${tx.outputs.length}`);
let totalIn = 0n;
tx.inputs.forEach((input: any, i: number) => {
console.log(` Input[${i}]: ${input.boxId.slice(0, 16)}...`);
// Fetch box value if needed
});
tx.outputs.forEach((output: any, i: number) => {
console.log(` Output[${i}]: ${output.value} nanoERG`);
if (output.assets?.length > 0) {
console.log(` Tokens: ${output.assets.length}`);
}
});
}Test with Mock Chain โ
import { MockChain, mockUtxo } from "@fleet-sdk/mock-chain";
// Create test environment
const chain = new MockChain();
// Create mock boxes
const testBox = mockUtxo({
value: 10_000_000_000n,
address: "9f...",
});
// Test your transaction logic locally๐ Getting Help โ
Resources โ
Fleet SDK Documentation
Ergo Platform Docs
Discord Community
- https://discord.gg/ergo-platform
- Channels: #development, #fleet-sdk
GitHub Issues
When Asking for Help โ
Include:
- โ Error message (full text)
- โ Code snippet (minimal reproduction)
- โ Fleet SDK version
- โ What you expected vs what happened
- โ Steps you've already tried
๐ฏ Prevention Checklist โ
Before submitting any transaction:
- [ ] Verified sufficient ERG balance
- [ ] Checked token balances
- [ ] Validated all addresses
- [ ] Used current blockchain height
- [ ] Tested on testnet first
- [ ] Included adequate fee
- [ ] Handled all edge cases
- [ ] Added error handling
๐ก Pro Tip: Always test on testnet first! Get free testnet ERG from the faucet.