Spark (Privacy)
Spark is Firo's built-in privacy protocol. It lets you convert regular (transparent) FIRO into private coins whose sender, receiver, and amount are hidden from outside observers.
This section covers four groups of Spark methods:
- Anonymity Set — the pool of private coins used to hide your transactions
- Names — human-readable names that map to Spark addresses
- Balances & Addresses — managing your private funds and addresses
- Mints & Spends — the lifecycle of private coins
All Spark methods require
mobile=1in yourfiro.conf.
Anonymity Set
The anonymity set is the pool of all existing Spark coins on the network. When you spend a private coin, your transaction is mixed with others from this set, making it impossible to tell which coin was actually spent.
flowchart LR
A[Your Spark Coin] --> P[Anonymity Pool]
B[Other Coins] --> P
C[Other Coins] --> P
P --> T[Private Transaction\nIndistinguishable from others]
getSparkLatestCoinId()
Returns the ID of the current coin group (sector). Coin groups are created periodically as more Spark coins accumulate.
const latestId = await client.getSparkLatestCoinId();
getSparkAnonymitySet(coinGroupId, startBlockHash)
Returns all Spark coins in a given group starting from a specific block. Used by light wallets to sync the anonymity set without downloading the full blockchain.
const set = await client.getSparkAnonymitySet(1, startHash);
console.log(`Coins in set: ${set.coins.length}`);
getSparkAnonymitySetMeta(coinGroupId)
Returns lightweight metadata about a coin group — its hash and size — without downloading the full coin list.
const meta = await client.getSparkAnonymitySetMeta(latestId);
console.log(`Set size: ${meta.size}`);
getSparkAnonymitySetSector(coinGroupId, latestBlock, startIndex, endIndex)
Returns a slice of the anonymity set for a given index range. Useful for paginated syncing in bandwidth-constrained environments.
const sector = await client.getSparkAnonymitySetSector(1, blockHash, 0, 100);
console.log(`Sector coins: ${sector.coins.length}`);
getMempoolSparkTxIds()
Returns the IDs of Spark transactions currently waiting in the mempool (not yet confirmed).
const sparkTxids = await client.getMempoolSparkTxIds();
getMempoolSparkTxs(txids)
Returns full details for a list of Spark transactions in the mempool.
const txs = await client.getMempoolSparkTxs(sparkTxids);
Spark Names
Spark Names are human-readable identifiers (like alice.spark) that map to a Spark address. Instead of sharing a long cryptographic address, you can share a simple name.
sequenceDiagram
participant Sender
participant Network
participant Receiver
Sender->>Network: getSparkNameData("alice")
Network-->>Sender: Spark address for "alice"
Sender->>Network: sendSpark to that address
Network-->>Receiver: Private funds received
getSparkNames(fOnlyOwn?)
Lists Spark names. Pass true to see only names registered to your wallet.
const allNames = await client.getSparkNames();
const myNames = await client.getSparkNames(true);
for (const n of myNames) {
console.log(`${n.name} → ${n.address} (valid until block ${n.validUntil})`);
}
getSparkNameData(sparkname)
Looks up the Spark address and registration details for a given name.
const data = await client.getSparkNameData('alice');
console.log(`Address: ${data.address}`);
console.log(`Valid until block: ${data.validUntil}`);
registerSparkName(name, sparkAddress, years, additionalData?)
Registers a new Spark name pointing to one of your Spark addresses. Returns the transaction ID of the registration.
const txid = await client.registerSparkName('alice', mySparkAddress, 2);
console.log(`Registered! txid: ${txid}`);
requestSparkNameTransfer(name, newSparkAddress, years, oldSparkAddress, additionalData?)
Initiates a transfer of a Spark name from one address to another. The original owner must approve the transfer using transferSparkName.
const requestHash = await client.requestSparkNameTransfer(
'alice',
newAddress,
2,
oldAddress,
);
transferSparkName(oldSparkAddress, requestHash)
Completes a name transfer that was previously requested. Must be called by the current owner.
const txid = await client.transferSparkName(oldAddress, requestHash);
getSparkNameTxDetails(txid)
Returns the Spark name registration details for a given registration transaction.
Only available via direct node RPC — not supported on ElectrumX.
const details = await client.getSparkNameTxDetails(registrationTxid);
Balances & Addresses
getSparkBalance()
Returns your wallet's total Spark (private) balance, broken down into available, unconfirmed, and full amounts.
const balance = await client.getSparkBalance();
console.log(`Available: ${balance.availableBalance} FIRO`);
console.log(`Unconfirmed: ${balance.unconfirmedBalance} FIRO`);
console.log(`Full: ${balance.fullBalance} FIRO`);
getSparkAddressBalance(address)
Returns the balance for a specific Spark address.
const balance = await client.getSparkAddressBalance(mySparkAddress);
getTotalBalance()
Returns your combined transparent + Spark balance as a single number.
const total = await client.getTotalBalance();
getPrivateBalance()
Returns only the Spark (private) portion of your balance.
const private_ = await client.getPrivateBalance();
getNewSparkAddress()
Generates a new Spark address from your wallet. Spark addresses are longer and start with a different prefix than regular Firo addresses.
const [address] = await client.getNewSparkAddress();
getSparkDefaultAddress()
Returns your wallet's default Spark address.
const [defaultAddr] = await client.getSparkDefaultAddress();
getAllSparkAddresses()
Returns all Spark addresses your wallet has generated, keyed by their diversifier index.
const addresses = await client.getAllSparkAddresses();
console.log(`Total Spark addresses: ${Object.keys(addresses).length}`);
dumpSparkViewKey()
Exports your Spark view key — a special key that allows read-only access to your Spark transaction history without the ability to spend.
Keep this key private. Anyone with it can see your Spark transaction history.
const viewKey = await client.dumpSparkViewKey();
Mints & Spends
"Minting" converts transparent FIRO into private Spark coins. "Spending" converts them back or sends them to another Spark address.
flowchart LR
T[Transparent FIRO] -->|mintSpark| M[Spark Mint\n private coin]
M -->|sendSpark| R[Recipient\nSpark Address]
M -->|listUnspentSparkMints| L[Unspent\nMint List]
mintSpark(recipients, subtractFeeFromAmount?)
Converts transparent FIRO into private Spark coins for one or more Spark addresses.
const txids = await client.mintSpark({
[mySparkAddress]: { amount: 10, memo: 'savings' },
});
console.log(`Minted in: ${txids}`);
autoMintSpark()
Automatically mints all available transparent funds into Spark. The node picks the optimal amounts.
const txids = await client.autoMintSpark();
sendSpark(recipients)
Sends private Spark coins to one or more Spark addresses. This is a fully private send — the amounts and addresses are not visible on-chain.
const txid = await client.sendSpark({
[recipientSparkAddress]: { amount: 1.5, subtractFee: false },
});
console.log(`Sent! txid: ${txid}`);
sendSpark returns a transaction ID as soon as the transaction is built — this does not mean it was successfully broadcast. Verify with getTransaction(txid) and check that confirmations > 0 before treating the send as final.
listSparkMints()
Lists all Spark mints your wallet knows about, including spent ones.
const mints = await client.listSparkMints();
for (const mint of mints) {
const status = mint.isUsed ? 'spent' : 'unspent';
console.log(`${mint.txid}: ${mint.amount} FIRO (${status})`);
}
listUnspentSparkMints()
Lists only the Spark coins that haven't been spent yet — your spendable private balance.
const unspent = await client.listUnspentSparkMints();
const total = unspent.reduce((sum, m) => sum + m.amount, 0);
console.log(`Spendable Spark: ${total} FIRO across ${unspent.length} coins`);
listSparkSpends()
Lists all Spark coins your wallet has spent.
const spends = await client.listSparkSpends();
identifySparkCoins(txid)
Given a transaction ID, identifies which Spark coins in it belong to your wallet and updates your balance accordingly.
const result = await client.identifySparkCoins(txid);
console.log(`New available balance: ${result.availableBalance}`);
getSparkCoinAddr(txid)
Returns the Spark address, memo, and amount for each Spark output in a transaction that belongs to your wallet.
const coins = await client.getSparkCoinAddr(txid);
for (const coin of coins) {
console.log(`Address: ${coin.address}, Amount: ${coin.amount}, Memo: ${coin.memo}`);
}
getUsedCoinsTags(startIndex)
Returns a list of "tags" for spent Spark coins starting from a given index. Used by light wallets to detect which coins have been spent without revealing which ones.
const { tags } = await client.getUsedCoinsTags(0);
console.log(`Known spent coin tags: ${tags.length}`);
setSparkMintStatus(lTagHash, isUsed)
Manually marks a Spark coin as used or unused in your local wallet database. Use this if your wallet's state gets out of sync.
await client.setSparkMintStatus(lTagHash, true);
resetSparkMints()
Resets all Spark mint data in your wallet and rescans. Use this to recover from sync issues.
This erases your local Spark state and re-syncs from the chain. It may take time.
await client.resetSparkMints();
getSparkMintMetadata(coinHashes)
Returns metadata for specific Spark coins identified by their coin hashes (from the anonymity set).
const metadata = await client.getSparkMintMetadata([hash1, hash2]);