Deployment Guide

Deploy a Pull Oracle network on Cardano using the Platform SDK with optional multisig governance.

Prerequisites

  • SDK installed (Setup Guide)
  • Configuration file prepared (oracle-config.yaml)
  • Funded wallet with sufficient ADA:
    • Testnet: ~100 ADA
    • Mainnet: ~150 ADA
  • For multisig: All party verification key hashes (hex format)

ADA Breakdown:

  • Reference script: ~64 ADA (one-time)
  • UTXO pairs: ~5 ADA per UTXO
  • Transaction fees: ~5-10 ADA
  • Buffer: ~20 ADA

Example cost calculation:

reward_count = 3, aggstate_count = 3
Total = 64 + (3 + 3) × 5 + 10 = 104 ADA

Step 1: Mint Platform Auth NFT

The Platform Auth NFT authorizes all platform operations and must be created before oracle deployment.

Single Signature (threshold = 1)

charli3 platform token mint --config oracle-config.yaml

Workflow:

  1. SDK builds minting transaction
  2. Transaction auto-signs with wallet
  3. Transaction auto-submits to blockchain
  4. NFT sent to platform address
  5. Policy ID displayed

Save the policy ID for your configuration:

tokens:
  platform_auth_policy: "<policy_id_from_output>"

Multisig (threshold > 1)

# Party 1: Build minting transaction
charli3 platform token mint --config party1-config.yaml
# Output: tx_platform_auth_mint.json
 
# Parties 2-N: Add signatures
charli3 platform token sign-tx \
  --config party2-config.yaml \
  --tx-file tx_platform_auth_mint.json
 
# Final party: Submit when threshold is met
charli3 platform token submit-tx \
  --config partyN-config.yaml \
  --tx-file tx_platform_auth_mint.json

After minting, update all configurations:

tokens:
  platform_auth_policy: "<policy_id_from_output>"

Step 2: Deploy Oracle Contracts

Automatic Deployment (threshold = 1)

charli3 oracle deploy --config oracle-config.yaml

The SDK automatically:

  1. Validates configuration parameters
  2. Creates reference script (~64 ADA) if create_reference: true
  3. Builds deployment transaction
  4. Mints oracle NFTs (CoreSettings, AggState, RewardAccount)
  5. Creates initial UTXO pairs
  6. Signs and submits transaction

Expected output:

✓ Configuration validated
✓ Reference script created
✓ Deployment transaction built
✓ Transaction signed and submitted
✓ Oracle policy ID: <policy_id>

Deployment successful!

Multisig Deployment (threshold > 1)

# Party 1: Build deployment transaction
charli3 oracle deploy --config party1-config.yaml
# Output: tx_oracle_deployment.json (saved, not submitted)
 
# Parties 2-N: Add signatures
charli3 oracle sign-tx \
  --config party2-config.yaml \
  --tx-file tx_oracle_deployment.json
 
# Final party: Submit when threshold is met
charli3 oracle submit-tx \
  --config partyN-config.yaml \
  --tx-file tx_oracle_deployment.json

Multisig coordination:

  1. Party 1 builds transaction with their config
  2. Transaction file is shared with other parties
  3. Each party signs with their own config and key
  4. Final party submits when threshold is met
  5. All parties should use identical oracle parameters

Step 3: Verify Deployment

Check Transaction Status

Wait for confirmation:

# If using Blockfrost
curl "https://cardano-preprod.blockfrost.io/api/v0/txs/<tx_id>" \
  -H "project_id: <project_id>"

Look for confirmation count > 0.

Query Oracle UTXOs

Using Blockfrost:

curl "https://cardano-preprod.blockfrost.io/api/v0/addresses/<script_address>/utxos" \
  -H "project_id: <project_id>"

Using Kupo:

curl "http://localhost:1442/matches/<script_address>/*"

Verify the following UTXOs were created:

NFTCountPurpose
C3CS1CoreSettings - holds oracle configuration
C3RANRewardAccount - manages reward distribution (N = reward_count)
C3ASNAggState - tracks aggregation states (N = aggstate_count)

Example verification:

# Count specific NFT type
curl "<oracle_address_utxos_endpoint>" | jq '[.[] | select(.amount[] | .unit | contains("C3RA"))] | length'

Should return reward_count for RewardAccount NFTs.

Inspect Transaction Details

cardano-cli transaction view --tx-file tx_oracle_deployment.json

Verify:

  • Correct number of outputs (1 CoreSettings + reward_count + aggstate_count)
  • Each output has appropriate NFT
  • ADA amounts match utxo_size_safety_buffer
  • Reference script output present (if create_reference: true)

Understanding UTXO Scaling

The reward_count and aggstate_count parameters determine initial capacity:

ParameterCreatesPurposeImpact
reward_countN RewardAccount UTXOsParallel reward distributionHigher throughput for rewards
aggstate_countN AggState UTXOsParallel aggregation trackingHigher throughput for aggregations

Capacity calculation:

  • Each UTXO pair enables one parallel transaction
  • reward_count: 3, aggstate_count: 3 = 3 parallel operations

Cost calculation:

Deployment cost = 64 (ref script) + (reward_count + aggstate_count) × 5 + fees

Recommendation:

  • Low volume (< 10 req/day): Start with reward_count: 1, aggstate_count: 1
  • Medium volume (10-100 req/day): Use reward_count: 2-3, aggstate_count: 2-3
  • High volume (> 100 req/day): Use reward_count: 5+, aggstate_count: 5+

You can scale up or down after deployment using governance commands.

Reference Script

The reference script allows validators to be referenced rather than included in each transaction, significantly reducing transaction sizes and fees.

Default behavior (create_reference: true):

  • SDK automatically creates reference script during deployment
  • Costs ~64 ADA (locked, recoverable)
  • Reduces per-transaction costs

If reference script creation fails:

# Manually create reference script
charli3 oracle create-reference-script --config oracle-config.yaml

Troubleshooting

“Platform auth NFT not found”

  • Cause: Platform auth NFT wasn’t minted or is at wrong address
  • Solution:
    1. Verify NFT exists: Query platform address for assets
    2. Check policy ID matches config: tokens.platform_auth_policy
    3. Ensure NFT is at correct address (platform or admin address)
    4. Re-mint if necessary: charli3 platform token mint

“Reference script creation failed”

  • Cause: Insufficient funds or network issue
  • Solution:
    1. Ensure wallet has ≥64 ADA available
    2. Check network connectivity (Blockfrost/Ogmios)
    3. Retry: charli3 oracle create-reference-script
    4. Or deploy without reference: Set create_reference: false in config

“Insufficient signatures”

  • Cause: Multisig threshold not met
  • Solution:
    1. Check signature count: cat tx_file.json | jq '.signed_by | length'
    2. Verify matches threshold: cat tx_file.json | jq '.threshold'
    3. Ensure each party signed exactly once (no duplicates)
    4. Check all parties have correct signing keys

“Transaction too large”

  • Cause: Too many UTXOs being created in single transaction
  • Solution:
    1. Reduce reward_count and aggstate_count in config
    2. Deploy with fewer UTXOs initially
    3. Scale up later using charli3 oracle scale-up

“Invalid configuration: reward_dismissing_period must be greater than pause_period”

  • Cause: Timing constraint violation
  • Solution: Update timing section in config:
    timing:
      pause_period: 3600000          # 1 hour
      reward_dismissing_period: 7200000  # Must be > pause_period

“Invalid node verification key hash format”

  • Cause: Node keys in wrong format
  • Solution: Node keys must be hex-encoded VKHs, not bech32:
    nodes:
      feed_vkh:
        - "007df380..."  # Correct: hex format
        # - "ed25519_pk1..."  # Wrong: bech32 format

“Wallet address mismatch”

  • Cause: Wallet in config doesn’t match platform address
  • Solution:
    1. Verify wallet derives to correct address
    2. Check network matches (testnet vs mainnet)
    3. Ensure mnemonic or signing key is correct

“Insufficient funds”

Post-Deployment Checklist

  • Verify oracle policy ID saved
  • Confirm all UTXOs created (CoreSettings, RewardAccount, AggState)
  • Reference script created and accessible
  • Test node operator connectivity
  • Document oracle parameters for team
  • Test aggregation submission (optional)

Next Steps