Calculation Time:
Executed daily at 00:05:00 UTC, using trade data from the previous UTC day (00:00:00 to 23:59:59).
Data Sources:
Trades are aggregated from: Biconomy, BingX, BitGet, BitMart, Coinex, and MEXC.
Calculation Logic:
Design Benefits:
Click on the API Endpoints or Example API Requests buttons below for information on how to access this data.
Calculation Time:
Price calculated hourly at {hour}:05:00 UTC, using trade data from the previous hour.
Data Sources:
Trades are aggregated from: Biconomy, BingX, BitGet, BitMart, Coinex, and MEXC.
Calculation Logic:
Design Benefits:
Click on the API Endpoints or Example API Requests buttons below for information on how to access this data.
wallywallet.org/_api/v0/now/dailyavg/usdt/nexawallywallet.org/_api/v0/dailyavg/usdt/nexa?time=< epoch seconds >wallywallet.org/_api/v0/now/hourlyavg/usdt/nexawallywallet.org/_api/v0/hourlyavg/usdt/nexa?time=< epoch seconds >wallywallet.org/_api/v0/now/oracle24wallywallet.org/_api/v0/now/oracle30Current Averages require no query parameters, and reflect price for the previous period - day or hour - as of the time the request is made. If a price was not calculated for that period, the previous period's price is returned. Prices are calculated 5 minutes after the day or hour. All times are given in UTC. Prices are in units per Nexa Satoshi.
Historic Averages require one query parameter: time (in epoch seconds). The time parameter must be less than or equal to current time, to be considered valid. These endpoints return a price for the previous period - day or hour (if one was calculated) - prior to the value of epoch seconds given. Prices are calculated 5 minutes after the day or hour. All times are given in UTC. Prices are in units per Nexa Satoshi.
{
"type": String,
"msg": {
"data": String (32 byte hex),
"signature": String (64 byte hex)
},
"epochSeconds": Long,
"price": String,
"pairPriceUnit": String
}
Example response:
{
"type": "Hourly Average",
"msg": {
"data": "4e455841000000005553445400000004f16ab6600000000b0b59ff905000000",
"signature": "2ae6eaddb3cd31842ceeb42079c7a25a86ec79f6e9c24c1b303007ee1dbeef24d313f90ba16a47b5e26106a904f4cfe86cea007c8373336382f490004999ab893"
},
"epochSeconds": 1722488399,
"price": "0.000002566283000",
"pairPriceUnit": "USDT/NEXA"
}
http://wallywallet.org/_api/v0/now/dailyavg/usdt/nexahttp://wallywallet.org/_api/v0/now/hourlyavg/usdt/nexahttp://wallywallet.org/_api/v0/dailyavg/usdt/nexa?time=1722489634http://wallywallet.org/_api/v0/hourlyavg/usdt/nexa?time=1722489634http://wallywallet.org/_api/v0/now/oracle24http://wallywallet.org/_api/v0/now/oracle30Example msg.data parsing with kotlin code.
Returns parsed data object with four fields:
tickerA, tickerB, epochSeconds, and price
@Serializable
data class OracleObject(
val type: String,
val msg: OracleMsg,
val epochSeconds: Long,
@Serializable(with = BigDecimalSerializer::class)val price: BigDecimal)
val pairPriceUnit: String
)
data class ParsedOracleData(
val tickerA: String,
val tickerB: String,
val epochSeconds: Long,
val price: Long
)
fun parseOracleData(data: ByteArray): ParsedOracleData {
require(data.size == 24) { "Data must be exactly 24 bytes" }
val tickerA = String(data.sliceArray(0..3)).trimEnd { it.toInt() == 0 }
val tickerB = String(data.sliceArray(4..7)).trimEnd { it.toInt() == 0 }
val longBuffer1 = ByteBuffer.wrap(data.sliceArray(8..15))
.order(ByteOrder.LITTLE_ENDIAN)
val epochSeconds = longBuffer1.long
val longBuffer2 = ByteBuffer.wrap(data.sliceArray(16..23))
.order(ByteOrder.LITTLE_ENDIAN)
val price = longBuffer2.long
return ParsedOracleData(tickerA, tickerB, epochSeconds, price)
}
val response = client.get("https://wallywallet.org/_api/v0/hourlyavg/usdt/nexa?
time=1724382065").bodyAsText()
val message = Json.decodeFromString<OracleObject>(response).msg
val data = message.data
val signature = message.signature
val byteArray = data.fromHex()
val parsedOracleData = parseOracleData(byteArray)
Example msg.signature validation with kotlin code.
class PriceDataPoint(name: String? = null, _nsl: NSL? = null): PackedStructure(name, _nsl)
{
constructor(_tickerA: String, _tickerB:String, _epochSeconds: Long, _priceAinB: Long):this()
{
tickerA.curVal = _tickerA.toPaddedByteArray(4)
tickerB.curVal = _tickerB.toPaddedByteArray(4)
epochSeconds.curVal = _epochSeconds
priceAinB.curVal = _priceAinB
}
val tickerA: Nexa.npl.NBytes by Nexa.npl.PBytes(4)
val tickerB: Nexa.npl.NBytes by Nexa.npl.PBytes(4)
val epochSeconds: Nexa.npl.NInt by Nexa.npl.PInt(8)
val priceAinB: Nexa.npl.NInt by Nexa.npl.PInt(8)
}
val checkData = PriceDataPoint(
parsedOracleData.tickerA,
parsedOracleData.tickerB,
parsedOracleData.epochSeconds,
parsedOracleData.price
).toByteArray()
val hashedData = libnexa.sha256(checkData)
// use wallywallet.org pubkey
val pubKey = "well-known pubKey goes here"
val pubKeyBytes = pubKey.fromHex()
val verify = libnexa.verifySignedHashSchnorr(hashedData, pubKeyBytes, signature.fromHex())
assertTrue(verify)
03b4a3ebc12e7c6a35c3e7dc2385713059c3429f6efdc302f410346712a66fffef
Data is stored in a 24-byte packed structure, which consists of the following:
Since decimal values are prone to rounding errors, the 1e16 multiplier is used to transfer a more stable Long value. An 8-byte Kotlin Long can support values up to about 9.22 x 1e18, therefore providing support of prices up to about 922 units of a given currency, per Nexa Satoshi.
msg.data is this 24-byte packed structure, converted to a hex string.
Once msg.data has been parsed (see example at right), the tickerA and tickerB values should reflect the asset types from the endpoint queried (in all capitals, "NEXA" always tickerA). The parsed epochSeconds value should match the epochSeconds field returned in the response from the http request. The parsed price value divided by 1e16 should match the price field returned in the response from the http request. Price units are specified per Nexa Satoshi.
The parsed oracle data must first be loaded into the PriceDataPoint data structure.That data is then hashed. The published wallywallet.org wallet's public key (in bytes form), the hashed data, and the signature provided from the API (in bytes form) are all passed to verifySignedHashSchnorr() available in the libnexakotlin library. This function should return TRUE for any valid signature.
Click to copy URL
https://wallywallet.org/_api/v0/now/nex/usdthttps://wallywallet.org/_api/v0/now/change24hhttps://wallywallet.org/_api/v0/day/usdt/nexahttps://wallywallet.org/_api/v0/daykline/usdt/nexa?site=mexc.com&start=1759320000&interval=900https://wallywallet.org/_api/v0/pdq/usdt/nexa?site=bitget.com&start=1759320000&count=288&interval=120https://wallywallet.org/_api/v0/volume-15m/usdt/nexa?start=1759320000&count=96https://wallywallet.org/_api/v0/volume-daily/usdt/nexa?start=1759320000&count=30https://wallywallet.org/_api/v0/now/depth/usdt/nexa?site=mexc.com/_api/v0/now/nex/usdt
Volume-weighted average Bid, Ask, Last price across all exchanges. 24H Volume in NEXA
Response: { Bid, Ask, Last, Volume } - All BigDecimal strings
/_api/v0/now/change24h
Price 24h ago, current price, percent change, 24h high/low.
Response: { price24hAgo, currentPrice, changePct, high24h, low24h }
/_api/v0/day/usdt/nexa
Mid-prices ((bid+ask)/2) for last 24 hours, one per minute.
Response: { price: ["0.000000580", ...] } - Array of price strings, most recent last
/_api/v0/daykline/usdt/nexa?site=&start=&interval=900
Exchange-specific 15-minute OHLCV candlestick data. Interval is fixed at 900 seconds.
Response: Array of { openTime, open, high, low, close, volume }
/_api/v0/pdq/usdt/nexa?site=&start=&count=&interval=
Exchange-specific price snapshots at configurable intervals.
Response: Array of { epochSeconds, min, max, last, bidmin, bidmax, bidlast, askmin, askmax, asklast, nsamples }
/_api/v0/volume-15m/usdt/nexa?start=&count=96
15-minute volume buckets. Use count=96 for 24 hours of data. Add /{exchange} for per-exchange data.
Response: Array of { epochSeconds, volume }
/_api/v0/volume-daily/usdt/nexa?start=&count=30
Daily volume totals across all exchanges. Use count=30 for one month of data.
Response: Array of { epochSeconds, volume }
/_api/v0/now/depth/usdt/nexa?site=
Current bid/ask order book for specified exchange.
Response: { timestamp, bids: [{p, v}...], asks: [{p, v}...] }
Where p = price, v = volume (NEXA)
Supported exchanges (site param): mexc.com, bingx.com, coinex.com, bitmart.com, bitget.com, biconomy.com
Wally Wallet is a self custodial digital wallet empowering users to easily send, receive, and manage digital assets like $NEXA, tokens, and NFTs. With integrated NFT viewing, comprehensive transaction history, and specialised features like split a bill or multi-account support, Wally makes managing your digital world secure, and effortless.



