Pour les développeurs / Actifs réels

Actifs réels

La couche est une couche de prix. 33 flux, dont 19 d'actifs réels, publiés dans le protocole et lisibles en un appel. Cette page explique comment obtenir la liste ; la suivante comment lire un prix.

Ce qui existe

La documentation en langage clair décrit trois couches. Exactement une d'entre elles a du code dans ce dépôt, et cette référence documente celle-là.

CoucheÉtat
A price, published in the protocolbuilt, and documented here33 feeds written by block production into a registry predeploy, with one Chainlink-shaped adapter per feed
Exposure to a priced assetdesigned, not present in this repositorya margin system denominated by a feed, with crypto collateral and crypto settlement. There is no contract to call
A registry admitting third-party tokenised assets as collateraldesigned, not present in this repositorywith risk parameters and haircuts. Pickle would admit such a token, not issue one

Donc : il y a des prix, et il y a des contrats qui les détiennent et les servent. Il n'y a pas de moteur de marge, pas de registre de collatéral et pas de contrat de position à appeler. Quand ceux-ci existeront, ils seront documentés ici comme des surfaces d'appel, pas comme des intentions.

Un prix, pas l'actif

A feed is the PRICE of a real-world asset. It is not the asset.

The chain publishes a number describing what something trades at somewhere else. It issues no tokenised share, holds no underlying instrument, offers no redemption and keeps no custody. Exposure measured against one of these prices is a claim on a margin system, not on an issuer, and this reference does not call it a tokenised asset. Nothing about a feed confers a shareholder right, and there is nothing to redeem.

Name it accordingly in your own interface. A contract reading XAU/USD is reading the price of gold; it is not holding gold, and a user who reads otherwise has been told something untrue.

C'est un énoncé sur ce que fait la chaîne, pas une clause de non-responsabilité vissée dessus. Rien dans le registre ne référence un émetteur, un dépositaire ou une réserve, parce qu'il n'y en a pas : Pickle n'émet aucun actif réel et n'en détient aucun. Un flux nommé AAPL/USD est un nombre décrivant ce à quoi cette action s'échange sur un marché ailleurs, publié sur cette chaîne et rien de plus.

Obtenir la liste des actifs

Trois façons, et la première est presque toujours la bonne. Elle ne demande ni ABI, ni adresse, ni clé.

VoieAppel
Over JSON-RPCpickle_pricesno params. Answers the whole registry: every feed with its symbol, feedId, adapter, decimals, class, policy, latest answer and age. One call, no ABI, no address
From a contractfeedCount() then feeds(offset, limit)on the price registry. limit is capped at 256; an offset past the end returns an empty array rather than reverting, so a reader can page blindly
From the sourceoracle/catalog.jsonthe live feed set in the repository: what the oracle service prints and what l2-feeds-init (scripts/sync-feeds.sh) reconciles the registry to. The authority for what the chain should hold after a sync, not proof of what it holds now
The genesis inputoracle/catalog-genesis.jsonthe frozen copy the genesis allocation was generated from, and the authority for what the chain was born with. It is never edited on its own: a change to it is a genesis regeneration, a new chain
bash
# Every feed the chain carries, with its adapter, decimals, answer and age.
curl -s $RPC_URL \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"pickle_prices","params":[]}' \
  | jq '.result.feeds[] | {symbol, feedId, adapter, decimals, price, statusName, staleOnchain}'

# The count alone, when you only want to know whether the catalog changed.
curl -s $RPC_URL \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"pickle_prices","params":[]}' \
  | jq '.result.feeds | length'

$RPC_URL est le point d'accès des paramètres réseau. La réponse porte aussi blockNumber, timestamp, ainsi que le publisher et l'owner que nomme le registre - lisez-les si vous voulez savoir qui aurait pu écrire ce que vous venez de lire.

Le catalogue est un état du registre, pas une constante

L'ensemble de genèse ci-dessous est celui avec lequel la chaîne est née. Des flux peuvent être ajoutés ensuite par le rôle propriétaire, donc un client qui code la liste en dur les manquera. Paginez le registre ou appelez pickle_prices et travaillez à partir de la réponse.

Les 33 flux

Classe d'actifsNombre
crypto14 feedsclass 1. ETH, BTC, SOL, XRP, DOGE, LINK, ADA, XLM, BCH, TRX, BNB, HYPE, ZEC, XMR - all quoted in USD
equity9 feedsclass 2. AAPL, MSFT, NVDA, AMZN, GOOGL, META, TSLA, SPY, JPM
commodity2 feedsclass 3. XAU/USD and XAG/USD - gold and silver
fx5 feedsclass 4. EUR/USD, GBP/USD, USD/JPY, USD/CHF, USD/CNH
index3 feedsclass 5. PYTHOIL/USD, BRENT/USD, NATGAS/USD - energy indices, which trade around the clock

19 des 33 sont des actifs réels. La séparation qui compte à l'usage en est une autre : 13 flux sont adossés à des places au comptant et 20 viennent de Pyth seul - c'est-à-dire tous les flux d'actifs réels plus XMR/USD, la seule paire crypto sans jambe de place.

SymboleClasseSourcesPolitique de publicationMarché
ETH/USDcrypto5 places + PytheveryBlocktoujours ouvert
BTC/USDcrypto5 places + PytheveryBlocktoujours ouvert
SOL/USDcrypto5 places + PytheveryBlocktoujours ouvert
XRP/USDcrypto5 places + PytheveryBlocktoujours ouvert
DOGE/USDcrypto5 places + PytheveryBlocktoujours ouvert
LINK/USDcrypto5 places + PytheveryBlocktoujours ouvert
ADA/USDcrypto5 places + Pyth10 bps / 60 stoujours ouvert
XLM/USDcrypto5 places + Pyth10 bps / 60 stoujours ouvert
BCH/USDcrypto5 places + Pyth10 bps / 60 stoujours ouvert
TRX/USDcrypto5 places + Pyth10 bps / 60 stoujours ouvert
BNB/USDcrypto5 places + PytheveryBlocktoujours ouvert
HYPE/USDcrypto5 places + PytheveryBlocktoujours ouvert
ZEC/USDcrypto5 places + Pyth10 bps / 60 stoujours ouvert
XMR/USDcryptoPyth seulement10 bps / 60 stoujours ouvert
AAPL/USDactionsPyth seulementeveryBlockheures du NYSE
MSFT/USDactionsPyth seulement10 bps / 300 sheures du NYSE
NVDA/USDactionsPyth seulementeveryBlockheures du NYSE
AMZN/USDactionsPyth seulementeveryBlockheures du NYSE
GOOGL/USDactionsPyth seulement10 bps / 300 sheures du NYSE
META/USDactionsPyth seulementeveryBlockheures du NYSE
TSLA/USDactionsPyth seulementeveryBlockheures du NYSE
SPY/USDactionsPyth seulement10 bps / 300 sheures du NYSE
JPM/USDactionsPyth seulement10 bps / 300 sheures du NYSE
XAU/USDmatières premièresPyth seulementeveryBlockséance avec pause quotidienne
XAG/USDmatières premièresPyth seulement5 bps / 300 sséance avec pause quotidienne
PYTHOIL/USDindicePyth seulement10 bps / 300 stoujours ouvert
BRENT/USDindicePyth seulement10 bps / 300 stoujours ouvert
NATGAS/USDindicePyth seulement10 bps / 300 stoujours ouvert
EUR/USDdevisesPyth seulement2 bps / 300 ssemaine des changes
GBP/USDdevisesPyth seulement2 bps / 300 ssemaine des changes
USD/JPYdevisesPyth seulement2 bps / 300 ssemaine des changes
USD/CHFdevisesPyth seulement2 bps / 300 ssemaine des changes
USD/CNHdevisesPyth seulement2 bps / 300 sséance avec pause quotidienne
  • 5 places + Pyth. five spot venues, with a Pyth feed alongside as a cross-check and a stand-in
  • Pyth seulement. Pyth only - no venue is listed for this feed, so an absent Pyth credential leaves it unpublished

Colonne Marché : toujours ouvert - open every day, all day ; heures du NYSE - 09:30-16:00 New York, Monday to Friday, with the exchange holiday list ; semaine des changes - continuous Monday to Friday afternoon New York, closed Saturday, reopening Sunday evening ; séance avec pause quotidienne - a nearly-continuous session with a daily break and a closed Saturday. Les calendriers font l'objet des heures de marché, et les gérer n'est pas optionnel.

Cinq politiques de publication, pas trente-trois

PolitiqueFlux
everyBlock, no step capETH/USD, BTC/USD, SOL/USD, XRP/USD, DOGE/USD, LINK/USD, BNB/USD, HYPE/USDwritten on every EVM block the publisher can fill. No deviation trigger, no heartbeat, no step cap - the whole crypto class carries a step cap of 0 whether or not it is on this policy. Ring capacity 16,384 for ETH/USD and BTC/USD, 1,024 for the other six
everyBlock, with step capAAPL/USD, NVDA/USD, AMZN/USD, META/USD, TSLA/USD, XAU/USDthe six real-world feeds moved onto everyBlock still carry their class's step cap (2,000 bps for the equities, 1,000 bps for gold), so a move wider than that is skipped unless the market status changed in the same update. Ring capacity 1,024
10 bps / 60 sthe other 6 crypto feedsrepublished on a 10 bps move or after 60 s, whichever is first. No step cap. Ring capacity 1,024
10 bps / 300 s, step 2,000 bpsthe 4 remaining equities and the 3 energy indicesa move wider than 20 % is skipped by the contract unless the market status changed in the same update
5 bps / 300 s, step 1,000 bpsXAG/USDthe metal moves less, so the trigger is tighter and the implausible-move cap is 10 %. XAU/USD kept the same trigger shape until it moved to everyBlock
2 bps / 300 s, step 500 bpsthe 5 FX pairsthe tightest trigger in the set, and a 5 % cap - an FX pair that moves further in one update is not moving, it is wrong

Le plafond de pas est la ligne la plus souvent mal lue. Il vaut 0, et est donc désactivé, sur chaque flux crypto, et il est actif sur chaque flux d'actif réel - une mise à jour d'actif réel qui bouge plus loin que le plafond en un pas est donc sautée par le contrat plutôt qu'écrite, sauf si le statut de marché a changé dans la même mise à jour. C'est cette exception qui laisse atterrir un écart de week-end.

Ce que porte l'enregistrement d'un flux

ChampValeur dans l'ensemble de genèse
symbolBASE/QUOTE^[A-Z0-9.]+/[A-Z]+$, at most 32 bytes, unique. The contract enforces the same shape
descriptionfree textthe Chainlink-style spaced form, "ETH / USD"; description() returns it and symbol() returns the canonical one
assetClasscrypto | equity | commodity | fx | indexstored as 1-5
decimals8every feed in the catalog. The field allows 0-18, so read it rather than assuming
capacityring length in rounds16,384 for ETH/USD and BTC/USD, 1,024 for every other feed - including the twelve other feeds now on everyBlock. Rounds older than this are overwritten
policypaused | everyBlock | deviationstored as 0, 1, 2. A paused feed is skipped rather than refused
deviationBps10, 5 or 2the move that triggers a republish. 0 on an everyBlock feed, which needs no trigger
heartbeatSecs60 or 300republish even without a move. 0 on an everyBlock feed
maxStepBps0, 500, 1,000 or 2,000the contract skips a move wider than this. 0 disables the check and is what every crypto feed carries; every real-world feed has it live. Bypassed whenever the status changed
minSources3 on an exchange-backed feed, 1 on a Pyth-only feedthe floor below which nothing is published
sources{ exchanges: {venue: productId}, pyth: id }the venue-native product id per venue, and the Pyth feed id without its 0x

Ces mêmes champs sont la configuration du flux on-chain, donc ce que vous lisez de pickle_prices ou de feeds(offset, limit) est cet enregistrement plus le dernier tour. decimals vaut 8 sur chaque flux aujourd'hui et le champ autorise 0 à 18 : lisez-le plutôt que de le supposer, parce que le coût d'une erreur est un prix faux de huit ordres de grandeur.

Les identifiants de flux

Un flux est indexé par un hash de son symbole, pas par un index et pas par une adresse :

solidity
bytes32 feedId = keccak256(bytes("ETH/USD"));

The canonical symbol, upper case, with a single slash - keccak256("ETH/USD"), not "ETH-USD" and not "eth/usd". The same 32 bytes key the contract's mappings, name the feed on the RPC, and appear as the indexed topic of every FeedUpdated log. You can compute it offline with any keccak-256 implementation; nothing has to be fetched to know it.

The node and the service both accept ETH/USD, ETH-USD, eth-usd or 0x<64 hex feed id and normalise before looking up, so a URL-safe spelling costs nothing.

Résoudre les adresses

Cette référence n'imprime aucune adresse de contrat

Le registre et les adaptateurs par flux sont des prédéploiements canoniques, fixés à la genèse pour la vie de la chaîne - ce qui est exactement le cas où publier le littéral est le pire. Un CALL EVM vers un compte sans code réussit : une adresse mal tapée ne revert pas, elle ne renvoie rien et se lit comme un prix de zéro. Ce site documente donc le mécanisme de résolution à la place.

The price registry and one adapter per feed are predeploys: their addresses are fixed at genesis and canonical for the life of the chain. That is precisely why this reference resolves them instead of printing them.

  • pickle_prices answers with the registry's address in core and each feed's adapter in feeds[].adapter, checksummed. That is the shortest path and it needs no ABI.
  • pickle_price(feed) carries that feed's adapter; pickle_ethUsdPrice carries the adapter, the registry and, under contract, the adapter again, which is what a Chainlink reader should be pointed at.
  • On chain, adapterOf(feedId) returns the deployed adapter and adapterAddress(feedId) recomputes it: the adapter is CREATE2 from the registry with salt = feedId, so its address is a pure function of the registry address and the symbol.
  • The first-party applications resolve every address they use at runtime rather than compiling one in - shared-ui/config.js merges the deployment's address files into config.addresses at load.
  • The explorer shows that address as an account, with its code and its activity, which is the human-readable cross-check that something is deployed there. It publishes no source and no ABI: the repository is not public yet, and the explorer verifies no contract.
bash
# The registry and one feed's adapter, resolved from the chain itself.
curl -s $RPC_URL \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"pickle_price","params":["ETH-USD"]}' \
  | jq '{adapter: .result.adapter, feedId: .result.feedId}'

# Then prove the address has code before you call it.
curl -s $RPC_URL \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["<adapter>","latest"]}'

Verify a resolved address with an eth_getCode before your first call. A CALL to an account with no code succeeds and returns nothing, so a wrong address does not revert - it reads as a price of zero.