Skip to main content

Query rewards for the last epoch

Use this example to grab the most recent mobile reward snapshot exposed at GET /v0/gateways/{address}. It prints the totals and category breakdown (data transfer vs. PoC) along with the reward rank information for that epoch.

Prerequisites

  • Node.js 18 or newer (ships with the Fetch API).
  • An API key exported as HELIUMGEEK_API_KEY.
  • A gateway address provided either as the GATEWAY_ADDRESS environment variable or as the first CLI argument.

Run the example

  1. Download mobile-last-epoch.js and save it next to where you plan to run the script.

  2. Export the required environment variables and run:

    export HELIUMGEEK_API_KEY="your-api-key"
    export GATEWAY_ADDRESS="your-gateway-address"
    node mobile-last-epoch.js

    Override the address inline if you prefer:

    HELIUMGEEK_API_KEY="your-api-key" node mobile-last-epoch.js <gateway-address>

Script

mobile-last-epoch.js
#!/usr/bin/env node

const BASE_URL = (process.env.HELIUMGEEK_API_BASE_URL ?? 'https://api.heliumgeek.com/v0').replace(/\/$/, '');
const API_KEY = process.env.HELIUMGEEK_API_KEY;
const GATEWAY_ADDRESS =
(process.argv[2] ?? process.env.GATEWAY_ADDRESS ?? '').trim();

if (!API_KEY) {
console.error('Set HELIUMGEEK_API_KEY before running this script.');
process.exit(1);
}

if (!GATEWAY_ADDRESS) {
console.error(
'Provide the gateway address as an argument or set GATEWAY_ADDRESS.'
);
process.exit(1);
}

async function main() {
const url = buildUrl(`/gateways/${encodeURIComponent(GATEWAY_ADDRESS)}`);
const response = await fetch(url, {
headers: {
'x-api-key': API_KEY,
},
});

if (!response.ok) {
throw new Error(`Request failed: ${response.status} ${response.statusText}`);
}

const gateway = await response.json();
const summary = gateway?.recent?.epoch?.mobileRewards;

if (!summary) {
console.log(
`Gateway ${GATEWAY_ADDRESS} did not earn mobile rewards in the most recent epoch.`
);
return;
}

const unit = (summary.unit ?? 'mobile').toUpperCase();
console.log(`Most recent mobile rewards for ${GATEWAY_ADDRESS}`);
console.log(`Epoch ending: ${formatEpoch(summary.endPeriod)}`);
printRank('Total', summary.total, unit);
printRank('Data', summary.data, unit);
printRank('PoC', summary.poc, unit);
}

function buildUrl(path, query = {}) {
const url = new URL(path.replace(/^\//, ''), `${BASE_URL}/`);
Object.entries(query).forEach(([key, value]) => {
if (value !== undefined && value !== null && value !== '') {
url.searchParams.set(key, String(value));
}
});
return url.toString();
}

function printRank(label, rank, unit) {
if (!rank) {
return;
}

console.log(
`${label.padEnd(7)}: ${formatAmount(rank.amount)} ${unit} (rank ${rank.rank}/${rank.total})`
);
}

function formatAmount(amount) {
return new Intl.NumberFormat('en-US', {
minimumFractionDigits: 4,
maximumFractionDigits: 4,
}).format(Number(amount));
}

function formatEpoch(epochEndSeconds) {
return new Date(epochEndSeconds * 1000).toISOString();
}

main().catch((error) => {
console.error(error.message);
process.exit(1);
});