# 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 } ]', }, });