LUMA/Docs
Developer Docs

LUMA Oracle

LUMA lets you push any external API data directly onto Solana. You configure a feed once — LUMA fetches, parses, and writes it on-chain automatically on your schedule.

Overview

Each feed is a Solana program account (PDA) that stores a JSON payload. LUMA's backend fetches a URL you specify, extracts the fields you select, and calls the write_data instruction on your feed account. The data is then publicly readable on-chain by any program or client.

Any APIREST endpoints, crypto prices, weather, sports — anything that returns JSON.
AutomatedRuns on your schedule. Loop every N seconds or trigger at an exact UTC time.
On-chainData lands in a Solana account — verifiable by any smart contract.

Creating a feed

Open the Dashboard, connect your Solana wallet, and click Create new. Fill in the form:

NameA unique identifier for your feed. Becomes part of the on-chain PDA seed — cannot be changed later.
URLThe API endpoint to fetch. Supports GET and POST requests.
Headers / BodyOptional. Add auth tokens, API keys, or POST body parameters.
JSON path(s)Dot-notation paths to the fields you want stored. Run the request inline and click fields directly in the response tree.
ScheduleLoop mode runs every N seconds. Daily mode triggers once at a fixed UTC time.

Your wallet pays a small one-time SOL rent to create the on-chain account, plus ongoing transaction fees for each write. Keep your wallet topped up to avoid pausing the feed.

How it works

Once a feed is active, LUMA's scheduler checks it every second and executes the following pipeline:

01
FetchLUMA calls your URL with the configured method, headers, and body.
02
ParseThe JSON response is traversed using your selected dot-notation paths. Only the selected values are extracted.
03
Sign & writeA write_data transaction is built and signed by both LUMA's admin key and your payer wallet key, then submitted to Solana.
04
ConfirmAfter confirmation, the transaction signature and fee are logged in the dashboard under Recent Writes.

Reading on-chain data

Each feed is stored in a PDA (Program Derived Address) owned by the LUMA program. You can read the latest data at any time — from a smart contract or an off-chain client.

The feed PDA is derived from three seeds:

seeds = ["feed", owner_pubkey, feed_name]
program_id = LUMApBfHYJyS8cykrVKxCZgkTeHkS8t1TDiHwynT96C

From a TypeScript / JavaScript client using @solana/web3.js:

import { PublicKey } from "@solana/web3.js";

const PROGRAM_ID = new PublicKey("LUMApBfHYJyS8cykrVKxCZgkTeHkS8t1TDiHwynT96C");

const [feedPda] = PublicKey.findProgramAddressSync(
  [
    Buffer.from("feed"),
    ownerPublicKey.toBuffer(),
    Buffer.from(feedName),          // the name you gave the feed
  ],
  PROGRAM_ID
);

const accountInfo = await connection.getAccountInfo(feedPda);
// accountInfo.data contains the raw account bytes

The data payload starts at byte offset 8 (after the 8-byte Anchor discriminator). The next 4 bytes are a little-endian u32 length prefix, followed by the UTF-8 encoded JSON string:

const raw  = accountInfo.data;
const len  = raw.readUInt32LE(8);           // 4 bytes after discriminator
const json = raw.slice(12, 12 + len).toString("utf8");
const data = JSON.parse(json);
// e.g. { "price": 68412, "volume": 1234567 }

From a Solana program (Rust / Anchor), pass the feed account as a remaining account and deserialize the data field directly from the account bytes.

Feed structure

The on-chain account layout (Anchor account):

pub struct Feed {
    pub owner:   Pubkey,    // wallet that created the feed
    pub name:    String,    // feed name (PDA seed, max 32 chars)
    pub data:    String,    // latest JSON payload (UTF-8)
    pub bump:    u8,        // PDA bump seed
}

The data field is a JSON object whose keys are the paths you selected when creating the feed:

// Example — paths selected: "bitcoin.usd", "bitcoin.usd_24h_change"
{
  "bitcoin.usd": 68412,
  "bitcoin.usd_24h_change": 2.14
}

The LUMA dashboard shows you the exact Feed PDA address for each feed. Copy it from the feed detail page.

Scheduling

LUMA supports two scheduling modes:

Loop

Runs every N seconds continuously. Good for real-time price feeds or frequently updated data. Minimum interval: 1 second.

mode: loop, time: 30 → every 30 seconds
Daily

Triggers once per day at a fixed UTC time. Good for daily settlement prices, sports results, or low-frequency data.

mode: date, time: 14:00 → every day at 14:00 UTC

You can pause or resume any feed from the dashboard at any time. Paused feeds stop making requests but keep their on-chain account and data intact.

© 2026 LUMA. Built on Solana.

@LUMAoracle