We Taught a Snowflake Warehouse to Judge World Cup Conviction and Write the Verdict Back to Solana

작성자

카테고리:

← 피드로
DEV Community · Soumyadeep Dey · 2026-07-13 개발(SW)

This is a submission for Weekend Challenge: Passion Edition

Target categories: Best use of Snowflake + Best use of Solana.

The single most common mistake in cross-platform hackathon projects is using
one platform as a database and the other as a logo. A dashboard that reads
Solana data through an API and renders it in a UI is not a Solana project.
It’s a dashboard.

The actual first question is: what can each platform do that the other
physically cannot?

Solana has behavioral data that exists nowhere else – every buy, sell, and
hold, public and permanent. But a blockchain cannot compute aggregates over
its own history; that’s not what the runtime is for. Snowflake can chew
through millions of decoded transactions with a declarative SQL DAG – but it
has no way to make a statement the rest of the on-chain world can read and
build on.

Strip away the World Cup framing and what I built is a pattern: a data
warehouse acting as a first-class blockchain participant.
Read state that
only exists on-chain, compute something the chain cannot compute about its
own history, and commit the answer back where other programs can consume it.

Solana (mainnet) --read--> Snowflake --compute--> Snowflake --write back--> Solana (devnet)
  live swaps and             streaming              conviction               an oracle account
  transfers, decoded         ingest + Dynamic       scoring + Cortex         any program can read
  by Helius                  Tables DAG             ML

Enter fullscreen mode Exit fullscreen mode

FERVOR is a real-time conviction oracle for World Cup fandom on Solana.
It tracks sixteen national token communities from the 2026 field – Argentina
to Japan, Morocco to Canada – wired into eight derby rivalries (ARG-BRA,
FRA-ENG, POR-ESP, GER-NOR, USA-MEX, NED-BEL, CRO-MAR, JPN-CAN), and it does
not measure hype, because following a crowd is cheap. It measures
conviction: the wallet that keeps buying its country’s token while the
price bleeds, the holder who never sells through a losing run. Passion,
defined mechanically: holding when it hurts.

World Cup Realtime Token Market Index

One thing up front, because it changes how you read every number below

The pipeline is real and running unattended. The fan wallets are not – yet.

Unofficial “national” meme tokens need per-mint liquidity vetting before you
point mainnet ingest at them, so the sixteen mints in REF.TEAM_TOKENS are
still PLACEHOLDER_MINT_*, and the wallet activity flowing through the DAG
is a labeled synthetic feed (_batch_id = 'DEMO_SEED').

What that means precisely: the seeder injects Helius-shaped transactions
upstream, into the raw landing table, and the real warehouse computes every
downstream number from there. Nothing in MARTS is hand-written. Nothing is
mocked below the landing zone. One UPDATE per row in REF.TEAM_TOKENS
points ingest at verified mints and the identical SQL scores real traders.

Full accounting in What’s real vs. what’s simplified at the bottom. I’d rather you
read the architecture knowing this than discover it in a footnote.

Verify this in 60 seconds – no keys, no clone

  1. The oracle is live. Snowflake’s output lands on devnet every 5 minutes, signed and confirmed. Watch the oracle account
  2. The warehouse is real. The Dynamic Tables DAG, live in Snowsight
    • the actual lineage, not the diagram. And no cron anywhere: every table declares TARGET_LAG and Snowflake works out the refresh order.
  3. The scoring is SQL. warehouse/03_marts_dt.sql
    • the conviction score is twelve lines, and it is the only place a wallet’s loyalty is decided.

Repo: github.com/SoumyaEXE/weekend-challenge

Every 5 minutes, a Snowflake task stages the freshly computed index and a
signing bridge writes it to Solana devnet as a confirmed transaction:

{
  "oracle": "FERVOR",
  "source": "Snowflake MARTS.TEAM_FERVOR_INDEX",
  "team_id": 10,
  "team": "NORWAY",
  "fervor_index": 236,
  "momentum": -21
}

Enter fullscreen mode Exit fullscreen mode

That JSON is Snowflake output living on a block explorer. fervor_index is a
SQL aggregate. momentum is a Cortex forecast – a machine-learning output
from inside the warehouse, published to a blockchain. Negative momentum means
the model expects the index to fall.

Solscan devnet transaction showing the FERVOR memo payload

And this is the league the warehouse produces:

League table: national conviction index

Snapshot. The index recomputes every minute; the on-chain writes are every five.

Argentina leads on conviction (109 average days held), Japan is the surprise
runner-up, England has the deepest bench of believers, and Norway folds under
pressure – on the seeded feed.

Norway is the transaction linked above. The prose, the league table, and the
block explorer are three views of one number, and none of them was written by
hand. And “folds under pressure” is the model’s verdict, not mine: the
momentum: -21 in that payload is Cortex forecasting Norway’s conviction to
slide another 21 points, and that projection is what got signed on-chain.

And that is the honest claim worth making. This table does not prove
Argentina’s fans are loyal. It proves the engine discriminates: sixteen
behavioral profiles go into the raw landing table, and the warehouse alone
decides who is a believer and who is a tourist. The ranking is an output, not
an input. Swap the mints and the same SQL judges real money.

The architecture, actually explained

Six stages. Every stage does load-bearing work; there is no component whose
only job is to name-drop a technology.

# Stage Tech Latency What it does 1 INGEST Node worker + Helius enhanced transactions 8 s batches Polls decoded mainnet activity for the 16 tracked country tokens 2 LAND micro-batch inserts seconds Raw VARIANT JSON into RAW.SOLANA_TX_LANDING 3 TRANSFORM Snowflake Dynamic Tables 1 min lag 7-table declarative DAG: decode, price, position, score 4 INTELLIGENCE Snowflake Cortex 5 min task ANOMALY_DETECTION, FORECAST, COMPLETE 5 WRITE-BACK Node signing bridge + Anchor 5 min task Queue staged in SQL, signed and confirmed on devnet 6 SERVE Streamlit-in-Snowflake live 8-tab analytics app, zero external hosting

FERVOR system architecture: the round trip

One database, six schemas, data flowing strictly left to right:

Schema Purpose Key objects REF hand-loaded seed TEAM_TOKENS (mint, decimals, rival_team_id), PARAMS RAW untouched VARIANT landing SOLANA_TX_LANDING STAGING decoded events (Dynamic Tables) TOKEN_TRANSFERS, SWAP_EVENTS, PRICE_TICKS MARTS conviction metrics (Dynamic Tables) WALLET_POSITIONS, WALLET_FERVOR, TEAM_FERVOR_INDEX, DEFECTION_FLOWS ML Cortex outputs + time series TEAM_INDEX_HISTORY, FERVOR_ANOMALIES, FERVOR_FORECAST ORACLE write-back queue + audit PUBLISH_QUEUE, PUBLISH_LOG

Warehouse structure: six schemas, lineage left to right

the Dynamic Tables DAG in Snowsight, lineage view - the real thing, as proof the diagram above is what Snowflake actually runs

Stage 1: ingest – a cursor trick that makes polling feel like streaming

Helius decodes raw Solana transactions into clean JSON, so I ingest
structured events instead of byte soup. The worker polls each tracked mint
every 8 seconds, but the until cursor means each poll returns only
transactions newer than the last one seen. Functionally, it’s a stream:

// ingest/poller.ts - the cursor is the whole trick
const cursor = new Map<string, string>(); // address -> newest seen signature

async function fetchNewTxs(address: string): Promise<EnhancedTx[]> {
  const until = cursor.get(address);
  const url =
    `https://api.helius.xyz/v0/addresses/${address}/transactions` +
    `?api-key=${HELIUS_API_KEY}&limit=50` +
    (until ? `&until=${until}` : "");
  const res = await fetch(url);
  const txs = (await res.json()) as EnhancedTx[];
  if (txs.length > 0) cursor.set(address, txs[0].signature); // newest first
  return txs;
}

Enter fullscreen mode Exit fullscreen mode

Landing is a multi-row INSERT ... SELECT PARSE_JSON(?) through the Node
connector. Honest note: true Snowpipe Streaming needs the Java ingest SDK.
8-second micro-batches demo identically (rows appear in Snowflake seconds
after they land on-chain) and were far more reliable to stand up in a
weekend.

Stage 3: the Dynamic Tables DAG – no cron, declared lag

I did not write a single scheduler for the transform layer. Each table
declares TARGET_LAG = '1 minute' and Snowflake works out the refresh order:

RAW.SOLANA_TX_LANDING
    |- STAGING.TOKEN_TRANSFERS ----> MARTS.DEFECTION_FLOWS
    |- STAGING.SWAP_EVENTS -------> STAGING.PRICE_TICKS
    |- MARTS.WALLET_POSITIONS
           |- MARTS.WALLET_FERVOR ----> MARTS.TEAM_FERVOR_INDEX
                                             |- (1 min task) ML.TEAM_INDEX_HISTORY
                                             |- (5 min task) Cortex models
                                             |- (5 min task) ORACLE.PUBLISH_QUEUE

Enter fullscreen mode Exit fullscreen mode

The result is a per-minute index series where each of the sixteen nations
charts its own story:

Conviction index over time

Two pieces of the transform SQL earned their place the hard way.

Decoding BUY/SELL without per-DEX parsers. Helius does not emit a parsed
swap event for every venue, so I classify from token-balance movement: fee
payer receives the tracked token = BUY, sends it = SELL. Routed swaps get
their legs summed, and self-arbitrage transactions (fee payer both sends AND
receives the same token in one tx) are dropped entirely – an arb bot carries
zero conviction signal:

-- warehouse/02_staging_dt.sql (excerpt)
team_legs AS (
  SELECT l.signature,
         MIN(l.block_time)                  AS block_time,
         l.raw_payload:feePayer::string     AS wallet,
         tt.value:mint::string              AS mint,
         r.team_id,
         IFF(tt.value:toUserAccount::string = l.raw_payload:feePayer::string,
             'BUY', 'SELL')                 AS side,
         SUM(tt.value:tokenAmount::float)   AS token_amount
  FROM dedup l,
       LATERAL FLATTEN(input => l.raw_payload:tokenTransfers) tt
  JOIN REF.TEAM_TOKENS r ON r.mint = tt.value:mint::string
  WHERE tt.value:toUserAccount::string   = l.raw_payload:feePayer::string
     OR tt.value:fromUserAccount::string = l.raw_payload:feePayer::string
  GROUP BY l.signature, l.raw_payload:feePayer::string,
           tt.value:mint::string, r.team_id, side
  -- self-arb filter: a signature with BOTH a BUY and a SELL row for the
  -- same token makes this window count 2, and the tx is excluded
  QUALIFY COUNT(*) OVER (PARTITION BY l.signature, r.team_id) = 1
)

Enter fullscreen mode Exit fullscreen mode

The 24-hour price change that survives trading gaps. The naive version is
LAG(price, 24) over hourly buckets. That counts ROWS, not HOURS – one
quiet hour and your “24h change” silently becomes a 25h change. ASOF JOIN
matches each tick to the nearest tick at or before 24 hours earlier, with a
warm-up fallback for series younger than a day:

-- warehouse/02_staging_dt.sql (excerpt)
SELECT cur.team_id, cur.window_start, cur.price_usd,
       100.0 * (cur.price_usd - COALESCE(day_ago.price_usd, first_tick.price_usd))
             / NULLIF(COALESCE(day_ago.price_usd, first_tick.price_usd), 0)
         AS price_change_24h_pct
FROM hourly cur
ASOF JOIN hourly day_ago
  MATCH_CONDITION (DATEADD('hour', -24, cur.window_start) >= day_ago.window_start)
  ON cur.team_id = day_ago.team_id
LEFT JOIN ( -- warm-up: earliest tick, for series younger than 24h
  SELECT team_id, price_usd FROM hourly
  QUALIFY ROW_NUMBER() OVER (PARTITION BY team_id ORDER BY window_start) = 1
) first_tick ON first_tick.team_id = cur.team_id;

Enter fullscreen mode Exit fullscreen mode

That distinction is not pedantry. A dip is what conviction is measured
against, so a 25-hour “24h change” quietly reclassifies who was buying the
bleed. Prices use the hourly median, not VWAP – SOL-leg attribution is
heuristic, and one mis-attributed leg destroys a volume-weighted mean.

Hourly price paths with dips

The conviction score – the creative payload

Hype is a headcount. Conviction is a cost. Per wallet, per country, 0 to 100:

Component Max points What it rewards 25 x ln(1 + hold_days) / ln(366) 25 longevity of the relationship 30 x min(1, dip_buys / 5) 30 buying while THEIR token bled 5%+ in 24h 25 x min(1, underwater_buys / 5) 25 buying below their own average cost -20 x (sold within 3 days) -20 punishes paper hands
-- warehouse/03_marts_dt.sql (excerpt)
ROUND(GREATEST(0, LEAST(100,
      25 * LN(1 + a.hold_duration_days) / LN(1 + 365)
    + 30 * LEAST(1, COALESCE(c.buy_against_decline, 0) / 5.0)
    + 25 * LEAST(1, COALESCE(c.buy_at_loss, 0) / 5.0)
    - 20 * IFF(a.last_sell_time > DATEADD('day', -3, SYSDATE()), 1, 0)
)), 1) AS fervor_score

Enter fullscreen mode Exit fullscreen mode

Two engineering decisions worth stealing:

  1. Tenure in fractional days (DATEDIFF('second', ...) / 86400.0). Whole-day granularity freezes longevity at zero for 24 hours and flat-lines the index on launch day.
  2. Zero-signal wallets are excluded from the national average. The raw swap feed is dominated by one-shot MEV bots whose score is 0 by construction. Averaging them in measures bot traffic, not the fan base:
ROUND(( COALESCE(AVG(IFF(f.fervor_score > 0, f.fervor_score, NULL)), 0) * 0.6
      + LEAST(100, COUNT_IF(f.fervor_score >= 60) / 10.0) * 0.4 ) * 10, 0)
  AS fervor_index   -- 0 to 1000, this exact number goes on-chain

Enter fullscreen mode Exit fullscreen mode

And the emotional centerpiece, MARTS.DEFECTION_FLOWS: the same wallet
selling one country and buying another within 24 hours. Selling ARGENTINA to
buy BRAZIL is not a portfolio rebalance. It is treason, and it gets its own
Sankey:

Defection flows between rival countries

Stage 4: Cortex – and the rule that the LLM never produces a number

One rule governs every metric in this system: SQL and fitted models compute
the numbers. The LLM only writes prose.
Nothing an LLM says reaches the
index, the league table, or the chain.

Three Cortex models, retrained every 5 minutes by a task.

ANOMALY_DETECTION – with a strict train/detect split.

-- warehouse/04_ml_cortex.sql (excerpt)
CREATE OR REPLACE SNOWFLAKE.ML.ANOMALY_DETECTION ML.FERVOR_ANOMALY_MODEL(
  INPUT_DATA => SYSTEM$QUERY_REFERENCE(
    'SELECT team_id, ts, fervor_index FROM FERVOR.ML.TEAM_INDEX_HISTORY
      WHERE NOT COALESCE(is_synthetic, FALSE)          -- never train on demo spikes
        AND ts < DATEADD(minute, -15, SYSDATE())'),    -- strict train/detect split
  SERIES_COLNAME => 'TEAM_ID', TIMESTAMP_COLNAME => 'TS',
  TARGET_COLNAME => 'FERVOR_INDEX', LABEL_COLNAME => '');

Enter fullscreen mode Exit fullscreen mode

The gotcha that cost an hour: my first version trained on ts < now and
detected on the last hour. Cortex rejected it –
All evaluation timestamps must be after the last timestamp in fitting data.
Training and detection must not overlap. Split both at the same boundary,
strict < on one side, >= on the other.

The is_synthetic flag is the honesty mechanism, and it is load-bearing. A
demo needs a passion spike on camera, so scripts/demo_spike.py injects
labeled rows that detection sees but training never fits. The detector
flags the surge because it genuinely is one – not because it was taught to.

FORECAST – and this one goes on-chain. Every nation’s index is projected
12 minutes out. The delta between that forecast and the live index is
momentum – the second field in the oracle payload. So a Snowflake Cortex ML
output is signed onto Solana every five minutes, next to the SQL aggregate it
predicts. The dashboard draws it as a dumbbell (live index → forecast) so you
read who is strengthening and who is cracking in one glance, with an explicit
label that it forecasts holding behavior, not token price.

COMPLETE – prose only. A scheduled task writes hype lines; the AI insights
tab calls Cortex on demand from inside the app – no external API, no key,
the LLM runs where the data lives:

SNOWFLAKE.CORTEX.COMPLETE('mistral-large2',
  'You are a crypto market analyst covering World Cup fan tokens. 3 bullets: '
  || 'one strength, one risk, one outlook. ' || team_name || ' index '
  || fervor_index || '/1000, ' || devoted_wallet_count
  || ' believer wallets, average hold ' || avg_hold_days || ' days.')

Enter fullscreen mode Exit fullscreen mode

Every number in that prompt was computed upstream, in SQL. The model is handed
facts and asked for sentences. It is never asked for arithmetic.

The market tabs render real 1-hour candlesticks built in SQL – no OHLC
API, just MIN_BY/MAX_BY over decoded swap executions:

SELECT TIME_SLICE(s.block_time, 1, 'HOUR')      AS h,
       MIN_BY(s.price_usd, s.block_time)        AS open,
       MAX(s.price_usd)                         AS high,
       MIN(s.price_usd)                         AS low,
       MAX_BY(s.price_usd, s.block_time)        AS close,
       SUM(s.sol_amount)                        AS volume
FROM STAGING.SWAP_EVENTS s
WHERE s.team_id = ? AND s.block_time >= DATEADD('hour', -72, CURRENT_TIMESTAMP())
GROUP BY 1 ORDER BY 1;

Enter fullscreen mode Exit fullscreen mode

And the USD leg is live: the bridge pushes the real SOL/USD rate into
REF.PARAMS every 60 seconds, so the whole DAG’s pricing tracks the market.

Stage 5: the write-back – where the trust boundary lives

The security property judges should check: the oracle keypair never touches
Snowflake.
The warehouse stages numbers in a queue table and nothing more. A
small Node bridge holds the key, signs, submits, and writes the audit trail
back:

-- warehouse/05_oracle.sql
CREATE OR REPLACE TABLE ORACLE.PUBLISH_QUEUE (
  publish_id   NUMBER IDENTITY,
  team_id      NUMBER, team_name STRING,
  fervor_index NUMBER,
  momentum     NUMBER DEFAULT 0,          -- Cortex forecast minus current index
  status       STRING DEFAULT 'PENDING',  -- PENDING -> SENT -> CONFIRMED | FAILED
  queued_at    TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
  tx_signature STRING, explorer_url STRING, last_error STRING
);

Enter fullscreen mode Exit fullscreen mode

Until the Anchor program is deployed the bridge writes signed Memo
transactions – real, confirmed, explorer-visible. Once FERVOR_PROGRAM_ID is
set it flips to the PDA oracle automatically: one account per country,
init_if_needed, so the first write creates it.

// oracle-program/programs/fervor_oracle/src/lib.rs (excerpt)
#[account]
pub struct FervorAccount {
    pub authority: Pubkey,   // first writer claims the PDA
    pub team_id: u16,
    pub fervor_index: u32,
    pub momentum: i32,
    pub updated_slot: u64,
}

Enter fullscreen mode Exit fullscreen mode

I also built the inbound design – a Snowpark procedure calling the bridge
directly over HTTPS, using an External Access Integration with a SECRET and a
NETWORK RULE. Snowflake trial accounts reject it
(509009: External access is not supported for trial accounts), so the
submission ships the queue-poll design. I verified the other path anyway – an
authenticated POST /publish through a cloudflared tunnel produced a confirmed
devnet transaction – and warehouse/06_external_access.sql runs as-is on a paid
account. Same on-chain result, one fewer moving part.

Here is the oracle’s actual output over one evening – every marker a confirmed
devnet transaction:

On-chain writes, step chart

Stage 6: the dashboard runs inside the warehouse

Streamlit-in-Snowflake, eight tabs (Standings, World Cup, Wallets and
rivalries, Market, Token markets, Head to head, AI insights, On-chain oracle),
national colors with SVG emblems, a rotatable 3D conviction scatter (days held
× dip buys × score, sized by SOL traded), a per-wallet drill-down. Zero
external hosting.
The app, the data, the ML and the LLM all live in the same
account – which is also why the oracle needs a bridge at all: the SiS sandbox
cannot reach the public internet.

dashboard, Standings tab

dashboard, On-chain oracle tab with Solscan links

The live World Cup, joined to on-chain conviction

The dashboard’s World Cup tab reads the real 2026 FIFA World Cup: fixtures,
scores with extra-time and penalty-shootout detail, the group tables, and the
live Golden Boot race – pulled from football-data.org and set directly beside
the conviction index.

Same constraint as the oracle, same solution: SiS cannot reach the internet, so
a host-side sync writes the tournament into Snowflake and the app only ever
reads a table.

# scripts/football_sync.py (excerpt) - three endpoints -> three REF tables
matches   = get("/matches",   KEY)   # scores, half-time, extra-time, penalties
standings = get("/standings", KEY)   # group tables: W/D/L, goals for/against, pts
scorers   = get("/scorers",   KEY)   # Golden Boot race: goals + assists
# every row maps the API country name to our REF.TEAM_TOKENS team_id via
# our_team(), so the real tournament joins straight onto on-chain conviction

Enter fullscreen mode Exit fullscreen mode

On the day I wrote this, France knocked Morocco out 2-0 in the quarter-final
and Argentina beat Switzerland 3-1 after extra time, setting up an England vs
Argentina semi-final. Mbappe and Messi were tied on eight.

That is not decoration. It is the join that makes the thesis falsifiable. A
conviction oracle exists to answer exactly one question – did the losing fan
base hold, or capitulate?
– and you cannot ask it without a real scoreline on
the other side of the join. The tournament is real today. Point the mints at
real tokens and both halves of that question are answerable at once.

dashboard, World Cup tab - real 2026 results beside the conviction index

The exact line between real and simplified

Stated at the top; itemised here.

Real and running unattended: the full 7-table Dynamic Tables DAG at
1-minute lag; the conviction scoring above; three Cortex models retraining on a
5-minute task; confirmed devnet transactions for all sixteen nations, one
publish cycle every 5 minutes, each with a clickable Solscan link in
ORACLE.PUBLISH_LOG; the live 2026 FIFA World Cup synced into REF.WC_MATCHES,
REF.WC_STANDINGS and REF.WC_SCORERS and joined to conviction; the 8-tab
dashboard inside Snowflake.

Simplified, with reasons:

Simplification Why Honest label Country token mints are placeholders pending verification unofficial “national” meme tokens need per-mint liquidity vetting before pointing mainnet ingest at them PLACEHOLDER_MINT_* in REF.TEAM_TOKENS; one UPDATE per row to go live, the poller skips placeholders Demo data seeded placeholder mints produce no organic feed yet every seeded row labeled: _batch_id = 'DEMO_SEED', wallets end in demo, is_synthetic history is excluded from model training, sample oracle rows carry is_demo = TRUE and are replaced by real bridge writes 8 s micro-batches, not Snowpipe Streaming SDK SDK is Java-only noted in code comments BUY/SELL from balance deltas, not per-DEX decoding Helius doesn’t parse every venue self-arb filter compensates Token prices decoded from swap legs, not a DEX API the pipeline must work from raw transactions alone USD via a LIVE SOL/USD rate the bridge refreshes into REF.PARAMS every 60 s Writes go to devnet; bridge is centralized this is an oracle BRIDGE, not a decentralized oracle network stated plainly

The seeder injects Helius-shaped transactions upstream, into the raw
landing table, and lets the real DAG compute every downstream number – each
nation with its own volatility, trend and fan-base depth, and a slowly drifting
sentiment so believers capitulate or buy the dip and the index genuinely moves
(which is what makes the Cortex forecast diverge). Nothing in MARTS is
hand-written.

These are unofficial Solana meme tokens named after national teams, not
licensed fan tokens (those live on Chiliz). FERVOR analyzes public on-chain
behavior only.

What this unlocks

The World Cup is the costume. Underneath it is a primitive: a data warehouse
that reads a chain, computes what the chain cannot compute about itself, and
signs the answer back where other programs can consume it
– with the key held
in a minimal, auditable bridge instead of the warehouse.

Proof-of-reserve attestations. Risk scores for lending protocols.
Activity-based airdrop eligibility. Sybil scoring. Every one of them is an
“aggregate off-chain, attest on-chain” problem, and every one of them currently
gets solved by a bespoke indexer somebody has to babysit.

They are all TARGET_LAG = '1 minute' and a queue table.

Run it yourself

git clone https://github.com/SoumyaEXE/weekend-challenge
cp .env.example .env             # Helius key, Snowflake creds, devnet keypair
npm install
python scripts/run_sql.py --all  # entire warehouse: schemas, DAG, tasks
python scripts/demo_seed.py      # labeled demo data through the real DAG
npm run bridge                   # queue -> signed devnet writes
python scripts/football_sync.py  # live World Cup -> matches, standings, scorers
python scripts/deploy_streamlit.py

Enter fullscreen mode Exit fullscreen mode

Within about two minutes the DAG refreshes, tasks snapshot history, and the
bridge confirms its first write. npm run publish:once forces a publish for
the impatient. python scripts/demo_spike.py makes the anomaly detector fire on
camera; --clean removes the evidence.

To go live on real trades: fill config/mints.json with verified mints, run
python scripts/set_mints.py (it auto-fetches each token’s decimals and logo),
then npm run ingest. Not one line of SQL changes.

Built with @dronzer2code within the challenge window with AI pair-programming. All simplifications and data labeling are documented above and in the README.

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다