Test Vectors
Static canonical strings with pre-computed SHA-256 digests for every signed attestation type — price, econ, indices, gas, and weather. Use these to verify your parsing, hashing, and signature verification implementation.
For each type: (1) UTF-8 encode the canonical string, (2) compute SHA-256, (3) compare to the expected digest. If your digest matches, your hashing implementation is correct. Field positions are shown for parsing verification. See Signature Verification for full code examples.
PRICE — Crypto / FX / Metals
v1|PRICE|BTCUSD|84231.50|USD|2|binance,binance_us,bitfinex,bitstamp,coinbase,gateio,gemini,kraken,okx|median|1741514400|482910
40ca32bf0d7f8b0fb43051b3ae7f8c7bcbe6532c00d56e6e8b48fab022291ad2
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | PRICE |
2 | PAIR | BTCUSD |
3 | PRICE | 84231.50 |
4 | CURRENCY | USD |
5 | DECIMALS | 2 |
6 | SOURCES | binance,binance_us,bitfinex,bitstamp,coinbase,gateio,gemini,kraken,okx |
7 | METHOD | median |
8 | TIMESTAMP | 1741514400 |
9 | NONCE | 482910 |
10 fields. Sources are lexicographically sorted. Price zero-padded to DECIMALS precision.
ECON — US / EU Economic Indicators
v1|ECON|US|CPI|326.785|index198284100|2026-02|2026-03-14|BLS|CUUR0000SA0|directapi|1741514400|830114
9fb45f3fed7075bb0733e12d304a49d7477d732a98425bb9aba3b22f09ceae65
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | ECON |
2 | REGION | US |
3 | INDICATOR | CPI |
4 | VALUE | 326.785 |
5 | UNIT | index198284100 |
6 | PERIOD | 2026-02 |
7 | VINTAGEDATE | 2026-03-14 |
8 | SOURCEAGENCY | BLS |
9 | SERIESID | CUUR0000SA0 |
10 | SOURCEMODEL | directapi |
11 | TIMESTAMP | 1741514400 |
12 | NONCE | 830114 |
13 fields. COMMODITIES use the same structure with REGION=COMMODITIES and INDICATOR=SYMBOL (e.g. WTI).
COMMODITIES — via ECON type
v1|ECON|COMMODITIES|WTI|94.65|usdperbarrel|2026-03-09|2026-03-15|EIA|DCOILWTICO|directapi|1741514400|402341
6fd0776144fdc7c602ac18fed2d71e53750bee1933c210b4c9b8380ff6b2dfb3
13 fields. Same structure as ECON. TYPE=ECON, REGION=COMMODITIES, INDICATOR=WTI. SOURCEMODEL is always directapi.
VOLATILITY — MSVI Index
v1|VOLATILITY|BTCUSD|MSVI|15.65|index|30D|RV:38.99:0.3,IV:38.39:0.25,TS:0.909:0.15,FR:20.02:0.2,PCR:0.651:0.1|CONFIDENCE:0.6765|METHOD:v1|1744416000|291847
2c86e6520888d7fd08bc0acf3fb0c68710c4b04d101d46a80da94e708058f0e7
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | VOLATILITY |
2 | PAIR | BTCUSD |
3 | INDEX | MSVI |
4 | VALUE | 15.65 |
5 | UNIT | index (lowercase) |
6 | WINDOW | 30D |
7 | COMPONENTS | RV:38.99:0.3,IV:38.39:0.25,TS:0.909:0.15,FR:20.02:0.2,PCR:0.651:0.1 |
8 | CONFIDENCE | CONFIDENCE:0.6765 |
9 | METHOD | METHOD:v1 |
10 | TIMESTAMP | 1744416000 |
11 | NONCE | 291847 |
VOLATILITY has 30D window field at position 6 and no REGIME field. UNIT is lowercase index. Component values are raw (not normalized). See Canonical Format for precision rules.
SENTIMENT — MSXI Index
v1|SENTIMENT|BTCUSD|MSXI|-9.88|INDEX|FR:-0.00:0.3,SKEW:-4.12:0.25,PCR:0.863:0.2,TS:0.923:0.15,BASIS:0.049:0.1|REGIME:NEUTRAL|CONFIDENCE:1.0000|METHOD:v1|1744416000|382910
d4b14525eb4b1ad4e811363ad087c591d0fbad37c6779f7c25c019002ce8b8c4
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | SENTIMENT |
2 | PAIR | BTCUSD |
3 | INDEX | MSXI |
4 | VALUE | -9.88 |
5 | UNIT | INDEX (uppercase) |
6 | COMPONENTS | FR:-0.00:0.3,SKEW:-4.12:0.25,PCR:0.863:0.2,TS:0.923:0.15,BASIS:0.049:0.1 |
7 | REGIME | REGIME:NEUTRAL |
8 | CONFIDENCE | CONFIDENCE:1.0000 |
9 | METHOD | METHOD:v1 |
10 | TIMESTAMP | 1744416000 |
11 | NONCE | 382910 |
12 fields. Has REGIME (unlike VOLATILITY). UNIT is uppercase INDEX. Values can be negative (bearish positioning).
STRESS — MSSI Index
v1|STRESS|MARKET|MSSI|64.32|INDEX|VOL:61.81:0.35,STBL:0.00:0.3,FR:38.57:0.35|REGIME:HIGH|CONFIDENCE:1.0000|METHOD:v1|1744416000|571923
c3278af823048e30cf09d47ab0cb5477da82e36ee97fb336a3a4b19ff2cb45ac
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | STRESS |
2 | SCOPE | MARKET |
3 | INDEX | MSSI |
4 | VALUE | 64.32 |
5 | UNIT | INDEX |
6 | COMPONENTS | VOL:61.81:0.35,STBL:0.00:0.3,FR:38.57:0.35 |
7 | REGIME | REGIME:HIGH |
8 | CONFIDENCE | CONFIDENCE:1.0000 |
9 | METHOD | METHOD:v1 |
10 | TIMESTAMP | 1744416000 |
11 | NONCE | 571923 |
12 fields. Same structure as SENTIMENT. SCOPE is always MARKET (not per-pair). Regimes: CALM, ELEVATED, HIGH, EXTREME.
GAS — Single Chain
v1|GAS|ethereum|14.523100|12.100000|0.456789|2450.00|4|median|1744416000
04bb5d3a852712bedf66d1fceed3e9160130c388df50a3f162538b0d4eb51d3d
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | GAS |
2 | CHAIN | ethereum |
3 | GAS_GWEI | 14.523100 (6dp) |
4 | BASE_FEE | 12.100000 (6dp) |
5 | TX_COST_USD | 0.456789 (6dp) |
6 | NATIVE_PRICE_USD | 2450.00 (2dp) |
7 | SOURCE_COUNT | 4 |
8 | METHOD | median |
9 | TIMESTAMP | 1744416000 |
GAS canonicals do not include a nonce. Timestamp is the last field. Gas/fee values use 6 decimal places; native price uses 2.
GAS_INDEX — Cross-Chain Index
v1|GAS_INDEX|6|arbitrum|arbitrum:0.001234,base:0.002100,optimism:0.003456,polygon:0.004200,bsc:0.012300,ethereum:0.456789|1744416000
18fcfca3b12d7e1c74d1dcfaf2e039159f328dbc1f7fc7fbc7f6d94d16f5a4bd
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | GAS_INDEX |
2 | CHAIN_COUNT | 6 |
3 | CHEAPEST | arbitrum |
4 | CHAIN_SUMMARIES | arbitrum:0.001234,base:0.002100,... |
5 | TIMESTAMP | 1744416000 |
6 fields. No NONCE. Chain summaries are comma-separated chain:txCostUsd pairs sorted by cost ascending.
WEATHER — WRSI (Drought Index)
v1|WEATHER|51.51,-0.13|WRSI|0.72|RAIN:45.2mm|ET0:62.8mm|30D|ADEQUATE|1744416000|291847
8bdca45f119d2443a702b9965b44601d944eaccde309d4acd7953c7177ab6159
| Position | Field | Value |
|---|---|---|
0 | VERSION | v1 |
1 | TYPE | WEATHER |
2 | COORDS | 51.51,-0.13 |
3 | SUBTYPE | WRSI |
4 | VALUE | 0.72 |
5 | RAIN | RAIN:45.2mm |
6 | ET0 | ET0:62.8mm |
7 | WINDOW | 30D |
8 | STATUS | ADEQUATE |
9 | TIMESTAMP | 1744416000 |
10 | NONCE | 291847 |
11 fields. Status values: ADEQUATE, STRESSED, DROUGHT, SEVERE_DROUGHT. Trigger: WRSI < 0.50.
WEATHER — Rainfall
v1|WEATHER|51.51,-0.13|RAINFALL|45.2mm|MAX:12.3mm|DRY:8d|30D|1744416000|382910
ba17de905c7393c437370deb1b24ca99dd28e976fd2b3364bcd6c38fba4e5bc6
10 fields. Total rainfall with max daily and dry day count.
WEATHER — Temperature
v1|WEATHER|51.51,-0.13|TEMPERATURE|TMAX:24.5C|TMIN:-2.1C|FROST:3d|HEAT:0d|30D|1744416000|571923
9f8da3ca90bd1c99db7ebceb653263b5997d8e07728018d665c81ad5904d1629
11 fields. Frost trigger: TMIN < 0°C. Heat stress trigger: TMAX > 35°C.
WEATHER — Wind
v1|WEATHER|51.51,-0.13|WIND|MAX:78.4kmh|MEAN:22.1kmh|STORM:0d|GALE:1d|14D|1744416000|402341
97e9578affb6c465174ec2604c0f782e484a7968d8f88d659de6bb77756cfcab
11 fields. Storm trigger: > 117 km/h. Gale trigger: > 62 km/h.
Marine, COT, DLC
Marine and COT endpoints do not currently produce pipe-delimited canonical strings. DLC uses binary TLV encoding (Oracle Attestation v3) per the DLC specification — see the DLC Oracle guide for that format.
Verification Pseudocode
import hashlib
# 1. Take the canonical string from the response
canonical = response["canonical"]
# 2. UTF-8 encode and SHA-256 hash
digest = hashlib.sha256(canonical.encode("utf-8")).digest()
hex_digest = digest.hex()
# 3. Compare to expected test vector digest
assert hex_digest == "40ca32bf0d7f8b0fb43051b3ae7f8c7bcbe6532c00d56e6e8b48fab022291ad2"
# 4. Parse fields
fields = canonical.split("|")
type_id = fields[1] # "PRICE"
price = fields[3] # "84231.50"
sources = fields[6].split(",") # ["binance", ...]
# 5. Verify signature (Ed25519 over the digest, not raw canonical)
# See /docs/verification/ for full implementationEd25519 signatures are computed over SHA-256(canonical), not the raw canonical bytes. This is non-standard — most Ed25519 libraries expect raw input. You must hash first, then pass the 32-byte digest to the verify function. See Signature Verification for copy-paste code.
Component Precision Reference
| Component | Decimal Places | Types |
|---|---|---|
RV, IV, FR, SKEW, VOL, STBL | 2 | VOLATILITY, SENTIMENT, STRESS |
PCR, TS | 3 | VOLATILITY, SENTIMENT |
BASIS | 4 | SENTIMENT |
| Index VALUE | 2 | All index types |
| CONFIDENCE | 4 | All index types |
| Unavailable component | — | KEY:NA:weight |
Field Count Summary
| Type | Fields | Has REGIME | Has WINDOW | Has NONCE |
|---|---|---|---|---|
PRICE | 10 | No | No | Yes |
ECON | 13 | No | No | Yes |
VOLATILITY | 12 | No | Yes (30D) | Yes |
SENTIMENT | 12 | Yes | No | Yes |
STRESS | 12 | Yes | No | Yes |
GAS | 10 | No | No | No |
GAS_INDEX | 6 | No | No | No |
WEATHER (WRSI) | 11 | No | Yes | Yes |
WEATHER (RAINFALL) | 10 | No | Yes | Yes |
WEATHER (TEMPERATURE) | 11 | No | Yes | Yes |
WEATHER (WIND) | 11 | No | Yes | Yes |