Signed and recountable today. The Solana feeds go live at deploy.
$UNEMP
US unemployment rate
Latest signedNone yetFirst print pending
UpdatesMonthlySigned at 15:10 UTC
SettleableYesSource terms allow it
SourcesNone yetOfficial: the BLS API
On Solana
- Feed account
- FNCxcTp2LuX7vp9XNuHagocnKAd5U1xzPcxHbqx6joaSLive at deploy
- Program
- 838cdWMpb2WeAT4stt7rgaBcwEcJh5ziS9P9RKLeTw7oSolana mainnet
- Rule
- Version 1 Rule JSON
- Rule hash
4b17d1f22013f9b44f044929eed136f4e108854a087e6b34620edbdf915ad556
Last 10 signed
No signed numbers yet. The oracle signs at 15:10 UTC, daily.
Read this feed
The feed account holds prints once the program is deployed. Until then, read the signed report: /api/indices/unemp/report.
TypeScript
// $UNEMP on Solana: the newest print in its feed account.
const FEED = "FNCxcTp2LuX7vp9XNuHagocnKAd5U1xzPcxHbqx6joaS";
const PROGRAM = "838cdWMpb2WeAT4stt7rgaBcwEcJh5ziS9P9RKLeTw7o";
const res = await fetch("https://api.mainnet-beta.solana.com", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: 1, method: "getAccountInfo",
params: [FEED, { encoding: "base64", commitment: "finalized" }] }),
});
const { result } = await res.json();
if (result.value?.owner !== PROGRAM) throw new Error("not a Tickerz feed");
const d = Buffer.from(result.value.data[0], "base64").subarray(8); // after the 8 byte discriminator
const decimals = d[52], grade = d[54], head = d[55], count = d[56];
if (count === 0) throw new Error("no print yet");
const o = 72 + 72 * head; // prints[head], the newest
const print = {
period_start: Number(d.readBigInt64LE(o)), // UTC seconds
value: d.readBigInt64LE(o + 8), // value / 10 ** decimals
published_at: Number(d.readBigInt64LE(o + 16)),
report_hash: d.subarray(o + 32, o + 64).toString("hex"),
status: ["provisional", "final", "corrected"][d[o + 64]],
};
const settleable = grade === 1 && print.status !== "provisional";Rust (Anchor)
use anchor_lang::prelude::*;
// $UNEMP on Solana.
pub const TICKERZ_ORACLE: Pubkey = Pubkey::from_str_const("838cdWMpb2WeAT4stt7rgaBcwEcJh5ziS9P9RKLeTw7o");
pub const FEED: Pubkey = Pubkey::from_str_const("FNCxcTp2LuX7vp9XNuHagocnKAd5U1xzPcxHbqx6joaS");
#[derive(Accounts)]
pub struct ReadTickerz<'info> {
/// CHECK: address and owner checked; layout at tickerz.com/methodology#the-solana-feed
#[account(address = FEED, owner = TICKERZ_ORACLE)]
pub feed: UncheckedAccount<'info>,
}
/// The newest print, refused unless a market may settle on it (grade 1, status 1 final or 2 corrected).
/// Returns (period_start, value, status); value / 10^decimals in the index's unit.
pub fn latest_settled(feed: &AccountInfo) -> Result<(i64, i64, u8)> {
let data = feed.try_borrow_data()?;
let d = &data[8..]; // after the 8 byte discriminator
let (grade, head, count) = (d[54], d[55] as usize, d[56]);
require!(count > 0, ErrorCode::AccountNotInitialized);
let o = 72 + 72 * head; // prints[head]
let at = |i: usize| i64::from_le_bytes(d[i..i + 8].try_into().unwrap());
let (period_start, value, status) = (at(o), at(o + 8), d[o + 64]);
require!(grade == 1 && status != 0, ErrorCode::ConstraintRaw);
Ok((period_start, value, status))
}Layout: methodology. Checking a report's signature: the signer file.