æternity Documentation Hub
Aeternity.comAeternity GitHub
  • æternity Hub
  • Developer Documentation
  • Aeternity Expansions
    • PULL_REQUEST_TEMPLATE
    • AEX X
    • AEXS
      • AEX 1
      • aex-10
      • AEX 11 Fungible Token Standard
      • AEX-130: æpps Metadata Format Specification
      • aex-141
      • AEX 2
      • AEX-3
      • AEX-4
      • AEX 5
      • AEX 7
      • AEX 8
      • aex-9
    • .github
      • ISSUE_TEMPLATE
        • aexpansion
  • AeMdw - Aeternity Middleware
    • Changelog
    • docs
      • AE MDW Architecture
      • AeMdw Hyperhain Setup Documentation
      • AeMdw Docker Setup Documentation
  • Æternity <> Ethereum Bridge
    • Changelog
  • aepp-cli-js
    • CHANGELOG
    • Contributor guide
    • reference
    • user-guide
    • .github
      • ISSUE_TEMPLATE
  • Hyperchain Bridge
    • Changelog
  • æternity's JavaScript SDK
    • Installation
      • Changelog
      • Compatibility Table
      • Quick Start
      • Transaction options
      • Development
        • Releases
      • guides
        • The range of possible address length
        • AENS (æternity naming system)
        • Batch Transactions
        • How to build a wallet
        • Connect an æpp to a wallet
        • Contract Events
        • Contracts
        • Error Handling
        • JWT usage
        • Ledger Hardware Wallet
        • Low vs High level API
        • Aeternity snap for MetaMask
        • Oracles
        • PayingForTx (Meta-Transactions)
        • Typed data hashing and signing
        • Usage with TypeScript
        • migration
          • Migration to 10.0.0
          • Migration to 11.0.0
          • Migration to 12.0.0
          • Migration to 13.0.0
          • Migration to 14.0.0
          • Migration to 7.0.0
          • Migration to 9.0.0
      • tutorials
        • vuejs
          • Vue.js HelloWorld
    • Examples
      • How to connect wallet to æpp using æternity's JS SDK
        • Sample æpp for contracts
        • iframe-based wallet
        • WebExtension-based wallet
    • .github
      • ISSUE_TEMPLATE
        • bug_report
        • feature_request
  • AEproject
    • Changelog
    • docs
      • Quick Start
      • AEproject Library
      • Migration from 3.x.x to 4.x.x
      • Migration from 4.x.x to 5.x.x
      • Upcoming Version Support
      • cli
        • Local Environment
        • Project Initialization
        • Unit Testing
    • .github
      • ISSUE_TEMPLATE
        • bug_report
        • feature_request
  • aerepl
    • Changelog
  • aescan
    • Changelog
    • Contributor Covenant Code of Conduct
    • Aescan Contributing Guide
    • LICENSE
    • .github
      • pull_request_template
      • ISSUE_TEMPLATE
        • bug_report
        • feature_request
    • docs
      • BRANCHING_STRATEGY
  • Sophia Support for Visual Studio Code
    • Changelog
  • aesophia
    • Changelog
    • Contributing to Sophia
    • docs
      • aeso_aci
      • aeso_compiler
      • Introduction
      • sophia
      • Contract examples
      • Features
      • Standard library
      • Syntax
  • aesophia_cli
    • Changelog
  • aesophia_http
    • Changelog
  • Æ Studio - Formerly known as 🔥 Fire Editor ! Aeternity's easy to use editor for writing smart contr
    • ideas
  • aeternity
    • .github
      • The Æternity Code of Conduct
      • Contributing to the Aeternity node
      • ISSUE_TEMPLATE
        • bug_report
        • feature_request
    • Welcome to Aeternity node documentation
      • Summary
      • Node API
      • Introduction
      • Build from source
      • Configuration
      • CUDA Miner
      • debian_ubuntu_packaging
      • Docker
      • Fork resistance in Aeternity nodes
      • Garbage Collection
      • Hacking the Aeternity Codebase
      • Hardware Requirements
      • hyperchains
      • Installation
      • Network Monitoring
      • Operation
      • Rebar Quick Guide
      • Stratum
      • Testing
      • Update
      • release-notes
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • About this release
        • next-ceres
          • GH-3706-micro_block_gas_limit_used_gas
          • GH-4009-allow_contract_call_by_name
          • GH-4056-add_raw_data_pointers_to_AENS
          • GH-4080-wildcard_aens_delegation_signature
          • GH3417-tamper_protection_on_ga_meta_tx
          • aega_only_allow_attach_for_fresh_accounts
          • aens_auction_adjustments
          • aens_preclaim_optional
          • deprecate_swagger
          • fate_extensions
        • next
          • GH-3088-db_direct_access-as-default
          • GH-4087_http_endpoint_info_inner_txs
          • GH4157-control-mempool-sync-start
    • Emergency patching of OTP modules
    • rosetta
    • apps
      • aehttp
        • priv
          • rosetta_README
    • data
      • aecore
        • Token migration contract
  • Hyperchains whitepaper
    • Hyperchains: Bridging Security and Scalability Through Periodic Synchronization
    • LICENSE
    • Periodically-Syncing-HyperChains
    • generations
    • Glossary
    • Hyperchain Properties
    • staking
  • æternity protocol
    • æternity naming system
    • Gossip
    • Stratum
    • SYNC
    • Serialization formats
    • State Channels
      • Off-chain
      • On-chain
      • Authentication
      • Channel off-chain state
    • æternity consensus protocol
      • Bitcoin-NG for æternity
      • Coinbase at height
      • consensus
      • Coins locking
    • Smart Contracts
      • The æternity Ethereum virtual machine (AEVM)
      • contract_state_tree
      • Contract Transactions
      • Virtual machines on the æternity blockchain
      • contracts
      • Events
      • fate
      • The Solidity Language
      • sophia
      • sophia_stdlib
    • Generalized accounts
      • Generalized accounts - explained
      • generalized_accounts
    • Oracles
      • Oracle life cycle examples
      • Oracle state tree
      • Oracle transactions
      • oracles
    • Sync
      • P2P messages
      • Mempool/TX-pool synchronization
    • node
      • æternity node API
        • Account management - intended usage
        • Encoding scheme for API identifiers and byte arrays
        • State channel WebSocket API
        • Channels - intended usage
        • Contracts - intended usage
        • Mining - intended usage
        • Naming System - intended usage
        • Oracles - intended usage
        • Spending coins - intended usage
        • examples
          • æternity node channel WebSocket API examples
            • json-rpc
              • sc_ws_basic_open_close
              • sc_ws_basic_open_close_server
              • sc_ws_broken_open_params
              • sc_ws_close_mutual
              • sc_ws_close_solo
              • sc_ws_leave_reconnect
              • sc_ws_leave_reestablish
              • sc_ws_leave_reestablish_responder_stays
              • sc_ws_leave_reestablish_wrong_fsm_id
              • sc_ws_min_depth_is_modifiable
              • sc_ws_min_depth_not_reached_timeout
              • sc_ws_opening_ping_pong
              • sc_ws_reconnect_early
              • sc_ws_slash
              • sc_ws_snapshot_solo
              • sc_ws_timeout_open
              • sc_ws_update_with_meta
              • abort_updates
                • sc_ws_abort_deposit
                • sc_ws_abort_offchain_update
                • sc_ws_abort_settle
                • sc_ws_abort_shutdown
                • sc_ws_abort_slash
                • sc_ws_abort_snapshot_solo
                • sc_ws_abort_withdraw
                • sc_ws_can_not_abort_while_open
              • assume_min_depth
                • sc_ws_basic_open_close
              • both_sign
                • init_per_group
                • conflicts
                  • sc_ws_conflict_deposit_and_offchain_update
                  • sc_ws_conflict_two_deposits
                  • sc_ws_conflict_two_offchain_updates
                  • sc_ws_conflict_two_withdrawals
                  • sc_ws_conflict_withdrawal_and_deposit
                  • sc_ws_conflict_withdrawal_and_offchain_update
              • changeable_fee
                • sc_ws_optional_params_close_solo
                • sc_ws_optional_params_create
                • sc_ws_optional_params_deposit
                • sc_ws_optional_params_settle
                • sc_ws_optional_params_slash
                • sc_ws_optional_params_snapshot
                • sc_ws_optional_params_withdrawal
                • sc_ws_set_fee_close_mutual
                • sc_ws_set_fee_close_solo
                • sc_ws_set_fee_create
                • sc_ws_set_fee_deposit
                • sc_ws_set_fee_settle
                • sc_ws_set_fee_slash
                • sc_ws_set_fee_snapshot
                • sc_ws_set_fee_withdrawal
              • changeable_fee_higher_than_gas_price
                • sc_ws_optional_params_close_solo
                • sc_ws_optional_params_create
                • sc_ws_optional_params_deposit
                • sc_ws_optional_params_settle
                • sc_ws_optional_params_slash
                • sc_ws_optional_params_snapshot
                • sc_ws_optional_params_withdrawal
              • changeable_fee_lower_than_gas_price
                • sc_ws_optional_params_close_solo
                • sc_ws_optional_params_create
                • sc_ws_optional_params_deposit
                • sc_ws_optional_params_settle
                • sc_ws_optional_params_slash
                • sc_ws_optional_params_snapshot
                • sc_ws_optional_params_withdrawal
              • changeable_gas_price
                • sc_ws_optional_params_close_solo
                • sc_ws_optional_params_create
                • sc_ws_optional_params_deposit
                • sc_ws_optional_params_settle
                • sc_ws_optional_params_slash
                • sc_ws_optional_params_snapshot
                • sc_ws_optional_params_withdrawal
              • changeable_nonce
                • sc_ws_optional_params_fail_close_mutual
                • sc_ws_optional_params_fail_close_solo
                • sc_ws_optional_params_fail_create
                • sc_ws_optional_params_fail_deposit
                • sc_ws_optional_params_fail_force_progress
                • sc_ws_optional_params_fail_settle
                • sc_ws_optional_params_fail_slash
                • sc_ws_optional_params_fail_snapshot
                • sc_ws_optional_params_fail_withdrawal
              • continuous
                • init_per_group
                • sc_ws_deposit
                • sc_ws_failed_update
                • sc_ws_generic_messages
                • sc_ws_ping_pong
                • sc_ws_update_conflict
                • sc_ws_withdraw
              • contracts
                • init_per_group
                • sc_ws_basic_contracts
                • sc_ws_environment_contract
                • sc_ws_nameservice_contract
                • sc_ws_oracle_contract
                • sc_ws_remote_call_contract
                • sc_ws_remote_call_contract_refering_onchain_data
                • sc_ws_wrong_call_data
              • force_progress
                • sc_ws_force_progress_based_on_offchain_state
                • sc_ws_force_progress_based_on_onchain_state
              • only_one_signs
                • init_per_group
                • sc_ws_conflict_on_new_offchain
                • sc_ws_conflict_snapshot_and_offchain_update
                • conflicts
                  • sc_ws_conflict_deposit_and_offchain_update
                  • sc_ws_conflict_two_deposits
                  • sc_ws_conflict_two_offchain_updates
                  • sc_ws_conflict_two_withdrawals
                  • sc_ws_conflict_withdrawal_and_deposit
                  • sc_ws_conflict_withdrawal_and_offchain_update
              • reconnect
                • sc_ws_basic_client_reconnect_i
                • sc_ws_basic_client_reconnect_i_w_reestablish
                • sc_ws_basic_client_reconnect_r
              • with_meta
                • init_per_group
                • sc_ws_deposit
                • sc_ws_remote_call_contract
                • sc_ws_withdraw
              • generalized_accounts
                • both
                  • sc_ws_basic_open_close
                • initiator
                  • sc_ws_basic_open_close
                • responder
                  • sc_ws_basic_open_close
  • Superhero Wallet
    • Changelog
    • Contributing & Guidelines
    • docs
      • Deep link URL Schema
    • .github
      • ISSUE_TEMPLATE
        • bug_report
        • feature_request
  • aerepl-web-bridge
    • AereplApi
    • aerepl_components
Powered by GitBook
On this page
  • Introduction
  • 1. Oracle: register
  • 2. Some party: query an oracle and poll for response
  • Query (preferred)
  • Post query (alternative)
  • Poll for response (alternative)
  • 3. Oracle: poll for queries and respond
  • Handle queries (preferred)
  • Poll for queries (alternative)
  • Respond to query (alternative)
  • 4. Oracle: extend
  • 5. Get the current state from the node
  • Example applications

Was this helpful?

Export as PDF
  1. æternity's JavaScript SDK
  2. Installation
  3. guides

Oracles

PreviousAeternity snap for MetaMaskNextPayingForTx (Meta-Transactions)

Last updated 1 month ago

Was this helpful?

Introduction

This guide shows you how to perform all the operations that you need within the lifecycle of using the SDK.

1. Oracle: register

Let's register an oracle that responds with the temperature of the city that is included in the query.

Firstly, you need to create an instance of Oracle class. This class requires an account that would be used to sign operations on behalf of the oracle. So one account can host only one oracle, and this oracle address would be the same as the corresponding account address except for a different prefix (ok_ instead of ak_). This means that it's not possible to manage multiple oracles using the same account.

import { AeSdk, Oracle } from '@aeternity/aepp-sdk'

// init an instance of the SDK using the AeSdk class
const aeSdk = new AeSdk({ ... })
// it should be an instance of AccountBase with non-zero balance
const oracleAccount = new AccountMemory(...)

const oracle = new Oracle(oracleAccount, aeSdk.getContext())

To register an oracle on-chain you need to provide a queryFormat and a responseFormat to the register function of Oracle class. In addition to the common transaction options you can provide the oracle specific options queryFee and oracleTtlValue, see .

// set TTL with a delta of 1000 blocks
const oracleTtlOptions = { oracleTtlType: ORACLE_TTL_TYPES.delta, oracleTtlValue: 1000 };
// OR set a specific block height to expire
const oracleTtlOptions = { oracleTtlType: ORACLE_TTL_TYPES.block, oracleTtlValue: 555555 };

// queryFee is optional and defaults to 0
// oracleTtlValue is optional and defaults to 500
// oracleTtlType is optional and defaults to ORACLE_TTL_TYPES.delta
const options = { queryFee: 1337, ...oracleTtlOptions };

// the first argument is the queryFormat and the second is the responseFormat
await oracle.register('{"city": "str"}', '{"temperature": "int"}', options);

Note:

  • By default the oracle will exist for the next 500 key blocks.

  • If you intend to keep your oracle running longer you should increase the oracleTtlValue and/or set up a service that automatically extends the TTL before it expires.

2. Some party: query an oracle and poll for response

Query (preferred)

After the oracle has been registered and as long as it isn't expired, everybody that knows the oracleId can query it.

import { OracleClient } from '@aeternity/aepp-sdk';

const oracleId = 'ok_...';
const options = {
  queryFee: 1337, // should cover the requested fee of the oracle and defaults to 0
  queryTtlType: ORACLE_TTL_TYPES.delta, // optional and defaults to ORACLE_TTL_TYPES.delta
  queryTtlValue: 20, // optional and defaults to 10
  responseTtlType: ORACLE_TTL_TYPES.delta, // optional and defaults to ORACLE_TTL_TYPES.delta
  responseTtlValue: 50, // optional and defaults to 10
  interval: 6000, // response polling interval
};

// to query an oracle you need to instantiate the OracleClient object first
const oracleClient = new OracleClient(oracleId, aeSdk.getContext());
const response = await oracleClient.query('{"city": "Berlin"}', options);
console.log('Decoded oracle response', response);

Note:

Alternatively, you can post query and poll for response using separate methods from below.

Post query (alternative)

To post a query without waiting for a response do the below.

const { queryId } = await oracleClient.postQuery('{"city": "Berlin"}'); // oq_...

console.log('Oracle query ID', queryId);

Poll for response (alternative)

Now you have query ID that can be used to poll for the response:

const response = await oracleClient.pollForResponse(queryId);

console.log('Decoded oracle response', response);

3. Oracle: poll for queries and respond

Handle queries (preferred)

Typically, the oracle itself polls for its own queries and responds as soon as possible:

const stopHandling = await oracle.handleQueries(
  (query) => {
    if (query.decodedQuery === '{"city": "Berlin"}') {
      return '{"temperature": 27.5}';
    }
    return '{"error": "Unknown request"}';
  },
  { interval: 1000 }, // polling interval in milliseconds
);

stopHandling();

This way, the oracle would respond with the temperature in a requested city. It needs to be done before the query's TTL expires.

Note:

  • Of course, the oracle itself would either use an API to get the current temperature for a certain city or ideally directly communicate with measuring devices located in that specific city.

  • As far as Oracle class is bound to a specific account provided while creation, it is not necessary to pass the onAccount option.

The above is the simplest way to respond to queries, though you can manually subscribe for new queries and respond to them.

Poll for queries (alternative)

To subscribe to new queries without responding to them:

const stopPolling = await oracle.pollQueries(
  (query) => {
    console.log(query); // log a new query
  },
  { interval: 1000 }, // polling interval in milliseconds
);

stopPolling();

Respond to query (alternative)

If the oracle recognizes that it has been queried it can respond to the query.

const oracleId = 'ok_...';
const queryId = 'oq_...';
const options = { onAccount: 'ak_...' }; // only the account of the oracle can respond to the query

await oracle.respondToQuery(queryId, '{"temperature": 27.5}', options);

4. Oracle: extend

As mentioned above an Oracle has a certain TTL that can be specified when registering it. You might want to extend the TTL of the oracle before it expires. You can do that as follows:

// extend TTL by additional 500 blocks (based on current expiration height of the oracle)
const options = { oracleTtlType: ORACLE_TTL_TYPES.delta, oracleTtlValue: 500 };

// using the Oracle instance
await oracle.extend(options);

5. Get the current state from the node

Both Oracle and OracleClient have methods to get their state from the node.

Oracle:getState, OracleClient:getState returns the same value as Node:getOracleByPubkey, but without arguments (it uses the oracle address provided in the constructor).

Oracle:getQuery, OracleClient:getQuery corresponds to Node:getOracleQueryByPubkeyAndQueryId, adding decodedQuery, decodedResponse based on the oracle type. In the same way Oracle:getQueries, OracleClient:getQueries corresponds to Node:getOracleQueriesByPubkey.

Example applications

Again, take a look into the to see what (other) options you can provide.

NodeJS example that registers an oracle, extends it if required and responds to queries automatically.

application that registers an oracle to check the presence of an AE address at a specific page

ae-oracle-pricefeed
tipping-oracle-service
oracles
transaction options
transaction options