# SLPDB Examples
# Table of contents
- Introduction
- General Queries
- Get All Tokens
- Token Transaction History
- Look up Transaction by TXID
- Transactions in a Block
- Transactions in Mempool
- Look up Token By tokenIdHex
- Look up Multiple Tokens in one Query
- Look up All Addresses associated with a Token
- Token Mint History
- Token Burn History
- Address Burn History
- Get Burn History of all Tokens
- Token Child NFTs
- Recent transactions
- Transactions involving address
- Tokens by SLP Address
- Recently created tokens
- Counting
- Count Total Tokens
- Count Total Tokens Minted
- Count Unconfirmed Transaction History
- Count Transactions By Block
- Count Transactions in Mempool
- Count Total Mints for a Token
- Count Total Burned Tokens
- Count Total Satoshis Locked Up
- Count Total Tokens Minted
- Count Tokens Total Transactions
- Count UTXOs Involving a Token
- Count Total Addresses associated with a Token
- Count Token Burn Transactions
- Count an Addresses Total Burn Transactions
- Count Total Token Burn Transactions
- Count of Tokens an Address Holds
- Total Transactions by Address
- Count Address's Sent Transactions
- Count Address's Received Transactions
- Dividend Calculations
# Introduction
# How to Query SLPDB
The following examples assume a similar implementation as the following to query SLPDB. fetch_retry
is used to deal with occassional network errors, and btoa_ext
is a nice way to ensure we can handle the full range of possible characters (such as querying some Chinese characters). If you are using SLPDB from a browser, browserify, babel, and other tools provide a Buffer implementation.
The core idea to this is to take JSON and convert it into a string, then convert that to base64, and perform a GET request to a SLPServe server.
const fetch = require('node-fetch');
const fetch_retry = (url, options, n=5) => fetch(url, options).catch(function(error) {
if (n === 0) {
throw error;
}
return new Promise((resolve) => {
setTimeout(() => resolve(fetch_retry(url, options, n - 1)), 1000);
});
});
const btoa_ext = (buf) => Buffer.from(buf).toString('base64');
const query = (query) => new Promise((resolve, reject) => {
if (! query) {
return resolve(false);
}
const b64 = btoa_ext(JSON.stringify(query));
const url = 'https://slpdb.fountainhead.cash/q/' + b64;
console.log(url);
fetch_retry(url)
.then((r) => r = r.json())
.then((r) => {
if (r.hasOwnProperty('error')) {
reject(new Error(r['error']));
}
resolve(r);
});
});
# General Queries
# Get All Tokens
const all_tokens = (limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['t'],
'find': {},
'sort': {
'tokenStats.approx_txns_since_genesis': -1,
},
'limit': limit,
'skip': skip,
},
});
# Token Transaction History
const token_transaction_history_query_generator = (db, tokenIdHex, address=null, limit=100, skip=0) => {
const q = {
'v': 3,
'q': {
'db': [db],
'find': {
'$and': [
{'slp.valid': true},
{'slp.detail.tokenIdHex': tokenIdHex},
],
},
'sort': {'blk.i': -1},
'limit': limit,
'skip': skip,
},
};
if (address !== null) {
q['q']['find']['$query']['$or'] = [
{'in.e.a': address},
{'out.e.a': address},
];
}
return q;
};
const unconfirmed_token_transaction_history = (tokenIdHex, address=null, limit=100, skip=0) => {
return query(token_transaction_history_query_generator('u', tokenIdHex, address, limit, skip));
};
confirmed_token_transaction_history = (tokenIdHex, address=null, limit=100, skip=0) => {
return query(token_transaction_history_query_generator('c', tokenIdHex, address, limit, skip));
};
# Look up Transaction by TXID
const tx = (txid) => query({
'v': 3,
'q': {
'db': ['c', 'u'],
'aggregate': [
{
'$match': {
'tx.h': txid,
},
},
{
'$limit': 1,
},
{
'$lookup': {
'from': 'graphs',
'localField': 'tx.h',
'foreignField': 'graphTxn.txid',
'as': 'graph',
},
},
{
'$lookup': {
'from': 'tokens',
'localField': 'slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
],
'limit': 1,
},
});
# Transactions in a Block
const txs_by_block = (height, limit=150, skip=0) => query({
'v': 3,
'q': {
'db': ['c'],
'aggregate': [
{
'$match': {
'$and': [
{'slp.valid': true},
{'blk.i': height},
],
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
{
'$lookup': {
'from': 'tokens',
'localField': 'slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
],
'limit': limit,
},
});
# Transactions in Mempool
const txs_in_mempool = (limit=150, skip=0) => query({
'v': 3,
'q': {
'db': ['u'],
'aggregate': [
{
'$match': {
'slp.valid': true,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
{
'$lookup': {
'from': 'tokens',
'localField': 'slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
],
'limit': limit,
},
});
# Look up Token By tokenIdHex
const token = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['t'],
'find': {
'tokenDetails.tokenIdHex': tokenIdHex,
},
'limit': 1,
},
});
# Look up Multiple Tokens in one Query
const tokens = (tokenIdHexs) => query({
'v': 3,
'q': {
'db': ['t'],
'find': {
'tokenDetails.tokenIdHex': {
'$in': tokenIdHexs,
},
},
'limit': tokenIdHexs.length,
},
});
# Look up All Addresses associated with a Token
const token_addresses = (tokenIdHex, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': 'UNSPENT',
},
},
{
'$group': {
'_id': '$graphTxn.outputs.address',
'slpAmount': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
{
'$match': {
'slpAmount': {
'$gt': 0,
},
},
},
],
'sort': {
'slpAmount': -1,
},
'project': {
'address': '$_id',
'token_balance': '$slpAmount',
},
'limit': limit,
'skip': skip,
},
});
# Token Mint History
const token_mint_history = (tokenIdHex, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['u', 'c'],
'find': {
'slp.valid': true,
'slp.detail.tokenIdHex': tokenIdHex,
'$or': [
{
'slp.detail.transactionType': 'GENESIS',
},
{
'slp.detail.transactionType': 'MINT',
},
],
},
'sort': {
'blk.i': -1,
},
'limit': limit,
'skip': skip,
},
});
# Token Burn History
const token_burn_history = (tokenIdHex, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
},
{
'$lookup': {
'from': 'confirmed',
'localField': 'graphTxn.txid',
'foreignField': 'tx.h',
'as': 'tx',
},
},
{
'$sort': {
'tx.blk.i': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
],
},
});
# Address Burn History
const address_burn_history = (address, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'$or': [
{
'graphTxn.outputs': {
'$elemMatch': {
'address': address,
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
{
'graphTxn.inputs.address': address,
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
],
},
},
{
'$lookup': {
'from': 'confirmed',
'localField': 'graphTxn.txid',
'foreignField': 'tx.h',
'as': 'tx',
},
},
{
'$lookup': {
'from': 'tokens',
'localField': 'tx.slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
{
'$sort': {
'tx.blk.i': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
],
},
});
# Get Burn History of all Tokens
const total_burn_history = (limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
},
{
'$lookup': {
'from': 'confirmed',
'localField': 'graphTxn.txid',
'foreignField': 'tx.h',
'as': 'tx',
},
},
{
'$lookup': {
'from': 'tokens',
'localField': 'tx.slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
{
'$sort': {
'tx.blk.i': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
],
},
});
# Token Child NFTs
const token_child_nfts = (tokenIdHex, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['t'],
'aggregate': [
{
'$match': {
'nftParentId': tokenIdHex,
},
},
{
'$sort': {
'tokenStats.block_created': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
],
},
});
# Recent transactions
const recent_transactions = (limit=150, skip=0) => query({
'v': 3,
'q': {
'db': ['c', 'u'],
'aggregate': [
{
'$match': {
'slp.valid': true,
'slp.detail.transactionType': 'SEND',
},
},
{
'$sort': {
'_id': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
{
'$lookup': {
'from': 'tokens',
'localField': 'slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
],
'limit': limit,
},
});
# Transactions involving address
const transactions_by_slp_address = (db, address, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': [db],
'aggregate': [
{
'$match': {
'$and': [
{'slp.valid': true},
{
'$or': [
{'in.e.a': address},
{'out.e.a': address},
],
},
],
},
},
{
'$sort': {'blk.i': -1},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
{
'$lookup': {
'from': 'tokens',
'localField': 'slp.detail.tokenIdHex',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
{
'$lookup': {
'from': 'graphs',
'localField': 'tx.h',
'foreignField': 'graphTxn.txid',
'as': 'graph',
},
},
],
'limit': limit,
},
});
const unconfirmed_transactions_by_slp_address = (address, limit=100, skip=0) => {
return transactions_by_slp_address('u', address, limit, skip);
};
const confirmed_transactions_by_slp_address = (address, limit=100, skip=0) => {
return transactions_by_slp_address('c', address, limit, skip);
};
# Tokens by SLP Address
const tokens_by_slp_address = (address, limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.outputs.address': address,
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': 'UNSPENT',
'graphTxn.outputs.address': address,
},
},
{
'$group': {
'_id': '$tokenDetails.tokenIdHex',
'slpAmount': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
{
'$sort': {
'slpAmount': -1,
},
},
{
'$match': {
'slpAmount': {
'$gt': 0,
},
},
},
{
'$lookup': {
'from': 'tokens',
'localField': '_id',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
],
'sort': {
'slpAmount': -1,
},
'skip': skip,
'limit': limit,
},
});
# Recently created tokens
const recent_tokens = (limit=100, skip=0) => query({
'v': 3,
'q': {
'db': ['c'],
'aggregate': [
{
'$match': {
'slp.detail.transactionType': 'GENESIS',
'slp.valid': true,
},
},
{
'$lookup': {
'from': 'tokens',
'localField': 'tx.h',
'foreignField': 'tokenDetails.tokenIdHex',
'as': 'token',
},
},
{
'$sort': {
'blk.i': -1,
},
},
{
'$skip': skip,
},
{
'$limit': limit,
},
],
'limit': limit,
},
});
# Counting
# Count Total Tokens
const count_tokens = () => query({
'v': 3,
'q': {
'db': ['t'],
'aggregate': [
{
'$match': {},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Total Tokens Minted
const token_get_total_minted = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'$or': [
{'graphTxn.details.transactionType': 'GENESIS'},
{'graphTxn.details.transactionType': 'MINT'},
],
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$group': {
'_id': null,
'count': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
],
'limit': 10,
},
});
# Count Unconfirmed Transaction History
const count_unconfirmed_token_transaction_history = (tokenIdHex, address=null) => {
let match;
if (address == null) {
match = {
'$and': [
{'slp.valid': true},
{'slp.detail.tokenIdHex': tokenIdHex},
],
};
} else {
match = {
'$and': [
{'slp.valid': true},
{'slp.detail.tokenIdHex': tokenIdHex},
],
'$or': [
{'in.e.a': address},
{'out.e.a': address},
],
};
}
return {
'v': 3,
'q': {
'db': ['u'],
'aggregate': [
{
'$match': match,
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
};
};
# Count Transactions By Block
const count_txs_by_block = (height) => query({
'v': 3,
'q': {
'db': ['c'],
'aggregate': [
{
'$match': {
'$and': [
{'slp.valid': true},
{'blk.i': height},
],
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Transactions in Mempool
const count_txs_in_mempool = () => query({
'v': 3,
'q': {
'db': ['u'],
'aggregate': [
{
'$match': {
'slp.valid': true,
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Total Mints for a Token
const count_token_mint_transactions = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['c'],
'aggregate': [
{
'$match': {
'slp.valid': true,
'slp.detail.tokenIdHex': tokenIdHex,
'$or': [
{
'slp.detail.transactionType': 'GENESIS',
},
{
'slp.detail.transactionType': 'MINT',
},
],
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Total Burned Tokens
const token_get_total_burned = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
],
'limit': 1,
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Total Satoshis Locked Up
const token_get_total_satoshis_locked = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': '$graphTxn.outputs.bchSatoshis',
},
},
},
],
'limit': 1,
},
'r': {
'f': '[ .[] | {count: .count} ]',
},
});
# Count Total Tokens Minted
const token_get_total_minted = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'$or': [
{'graphTxn.details.transactionType': 'GENESIS'},
{'graphTxn.details.transactionType': 'MINT'},
],
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$group': {
'_id': null,
'count': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
],
'limit': 10,
},
});
# Count Tokens Total Transactions
const token_get_total_transactions = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': 1,
},
},
},
],
'limit': 1,
},
'r': {
'f': '[ .[] | {count: .count} ]',
},
});
# Count UTXOs Involving a Token
const token_get_total_utxos = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
'graphTxn.outputs.slpAmount': {
'$gt': 0,
},
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': 1,
},
},
},
],
'limit': 1,
},
'r': {
'f': '[ .[] | {count: .count} ]',
},
});
# Count Total Addresses associated with a Token
const token_get_total_addresses = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': {
'$in': [
'UNSPENT',
'BATON_UNSPENT',
],
},
'graphTxn.outputs.slpAmount': {
'$gt': 0,
},
},
},
{
'$group': {
'_id': '$graphTxn.outputs.address',
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': 1,
},
},
},
],
'limit': 1,
},
'r': {
'f': '[ .[] | {count: .count} ]',
},
});
# Count Token Burn Transactions
const count_token_burn_transactions = (tokenIdHex) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count an Addresses Total Burn Transactions
const count_address_burn_transactions = (address) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'$or': [
{
'graphTxn.outputs': {
'$elemMatch': {
'address': address,
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
{
'graphTxn.inputs.address': address,
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
],
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Total Token Burn Transactions
const count_total_burn_transactions = () => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.outputs': {
'$elemMatch': {
'status': {
'$in': [
'SPENT_NON_SLP',
'BATON_SPENT_INVALID_SLP',
'SPENT_INVALID_SLP',
'BATON_SPENT_NON_SLP',
'MISSING_BCH_VOUT',
'BATON_MISSING_BCH_VOUT',
'BATON_SPENT_NOT_IN_MINT',
'EXCESS_INPUT_BURNED',
],
},
'slpAmount': {
'$gt': 0,
},
},
},
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count of Tokens an Address Holds
const count_tokens_by_slp_address = (address) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.outputs.address': address,
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': 'UNSPENT',
'graphTxn.outputs.address': address,
},
},
{
'$group': {
'_id': '$tokenDetails.tokenIdHex',
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Total Transactions by Address
const count_total_transactions_by_slp_address = (address) => query({
'v': 3,
'q': {
'db': [
'c',
'u',
],
'aggregate': [
{
'$match': {
'$and': [
{
'$or': [
{'in.e.a': address},
{'out.e.a': address},
],
},
{'slp.valid': true},
],
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Address's Sent Transactions
const count_address_sent_transactions = (address) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.inputs.address': address,
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Count Address's Received Transactions
const count_address_recv_transactions = (address) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'graphTxn.inputs.address': {
'$ne': address,
},
'graphTxn.outputs.address': address,
},
},
{
'$group': {
'_id': null,
'count': {'$sum': 1},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});
# Dividend Calculations
# Calculate Dividends from Mempool
const dividend_calculate_bch_mempool = (tokenIdHex, slp_supply, bch_amount, ignoreAddresses) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': 'UNSPENT',
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': 'UNSPENT',
'graphTxn.outputs.address': {
'$nin': ignoreAddresses,
},
},
},
{
'$group': {
'_id': '$graphTxn.outputs.address',
'slpAmount': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
{
'$sort': {
'slpAmount': -1,
},
},
{
'$project': {
'_id': 1,
'bchAmount': {
'$divide': ['$slpAmount', slp_supply],
},
},
},
{
'$project': {
'_id': 1,
'bchAmount': {
'$multiply': ['$bchAmount', bch_amount],
},
},
},
{
'$limit': 10000,
},
{
'$match': {
'bchAmount': {
'$gte': 0.00000546,
},
},
},
],
'limit': 10000,
},
'r': {
'f': '[ .[] | { address: ._id, bchAmount: .bchAmount } ]',
},
});
# Dividend Ignore Amount from Mempool
const dividend_count_ignore_amounts = (tokenIdHex, addresses) => query({
'v': 3,
'q': {
'db': ['g'],
'aggregate': [
{
'$match': {
'tokenDetails.tokenIdHex': tokenIdHex,
'graphTxn.outputs.status': 'UNSPENT',
'graphTxn.outputs.address': {
'$in': addresses,
},
},
},
{
'$unwind': '$graphTxn.outputs',
},
{
'$match': {
'graphTxn.outputs.status': 'UNSPENT',
'graphTxn.outputs.address': {
'$in': addresses,
},
},
},
{
'$group': {
'_id': null,
'count': {
'$sum': '$graphTxn.outputs.slpAmount',
},
},
},
],
},
'r': {
'f': '[ .[] | {count: .count } ]',
},
});