Glittr
  • Introduction
  • Protocol Overview
  • Contract Primitives
    • MOAs - Mint Only Assets
    • MBAs - Mint and Burn Assets
      • Vaults
    • Spec Contracts
    • Oracle Commitments
  • Building on Glittr
    • Setup
    • Faucet
    • Glittr SDK
    • Glittr Transactions
    • Glittr Contracts
    • Installing Glittr Wallet
    • Local Development Guide
  • GLIP
  • Node
    • Run a Bitcoin Node
    • Run a Glittr Node
  • Examples & Guide
    • Creating Tokens
    • Contract Custody
    • Complex Tokens
    • Vesting and Freemint Contract
    • Wrapped BTC Contract
    • USD Contract
    • Oracle Implementation Guide
    • Glittr Output Structure
    • AMM Contract
  • API Reference
    • Getting Assets API
  • APP EXAMPLES
    • Freemint App (NextJS)
    • Freemint App (React + Vite)
    • NFT App (React + Vite)
Powered by GitBook
On this page
  1. Examples & Guide

Oracle Implementation Guide

PreviousUSD ContractNextGlittr Output Structure

Last updated 4 months ago

Glittr contracts can require an oracle commitment to verify an off-chain agreement. Oracle commitments can be leveraged in any contract type, and serve as a modifier to that contract. There is a liveness assumption on part of the designated oracle signer, as these commitments are pre-signed and included directly in the Glittr transaction. See the oracle commitment page for more overview.

The data format of the oracle commitment contains the signature (Schnorr) and the oracle message. Represented in typescript format, it looks like this:

type OracleMessageSigned = { // Oracle Commitment
    signature: Vec<u8>,
    message: OracleMessage,
}

The signature is Schnorr signature of sha256(bytes(JSON.stringified(message))).

The oracle message contains the following, which field you need to fill is entirely dependent on the application. The OracleMessage below is a structure of a simple price oracle, e.g. the oracle is saying that 1 BTC = $100,000. The asset_id is optional here for the dApp to verify if the ratio is for the correct currency pair.

type OracleMessage = {
    asset_id: string | null;
    // ratio of 
    ratio: Fraction | null;
    // the bitcoin block height when the message is signed
    block_height: number;
}

type Fraction = (number, number);

Example:

At blockheight 878000 the price of 1 MeowToken is 80 USD. The oracle message is:

{
  "signature": [56, 12, 242, ...],
  "message": {
    "asset_id": "MeowToken-USD",
    "ratio": (1, 80),
    "block_height": 878000
  }
}

The dApp then will wrap the whole message into a part of a valid Glittr transaction and use this for example to mint a MeowToken-collateralized USD.

Example implementation

The example below is written using TypeScript and imports the glittr-sdk package and @noble/secp256k1 for the digital signature. The oracle here informs how much sats (bitcoin) is worth in USD. The glittr contract can use this to create collateralized USD, see the USD Contractexample for more.

import { OracleMessage, OracleMessageSigned } from "@glittr-sdk/sdk/dist/transaction/calltype/types";
import { schnorr, utils, getPublicKey } from "@noble/secp256k1";
import { sha256 } from "bitcoinjs-lib/src/crypto";

const main = async () => {
  // ORACLE
  // Generate a random private key
  const oraclePrivateKey = new Uint8Array([
    155, 112, 1, 86, 197, 238, 25, 119, 90, 109, 241, 199, 214, 248, 145, 209,
    253, 107, 11, 21, 162, 36, 125, 70, 42, 12, 110, 21, 177, 251, 9, 79,
  ]);

  // Get the corresponding public key
  const oraclePubkey = Array.from(getPublicKey(oraclePrivateKey, true)).slice(
    1
  );
  console.log("Oracle public key:", Buffer.from(oraclePubkey).toString("hex"));

  // Bitcoin block height, fetch this from RPC
  const blockHeight = 870000;

  const oracleMessage: OracleMessage = {
    asset_id: "sats-usd",
    ratio: [70000, 1], // 70000 sats = 1 usd
    block_height: blockHeight,
  };

  const signature = await schnorr.sign(
    sha256(Buffer.from(JSON.stringify(oracleMessage), "ascii")).toString("hex"),
    oraclePrivateKey
  );

  const oracleCommitment: OracleMessageSigned = {
    signature: Array.from(signature),
    message: oracleMessage,
  };

  console.log(`Oracle Commitment: ${JSON.stringify(oracleCommitment)}`)
};

main()

Result:

Oracle public key: 261f9b464d547bc49ba6695f6fd18cc39b9387b79ffdb9300604f400b982aa4f
Oracle Commitment: {"signature":[193,127,135,233,152,254,69,153,86,222,123,21,97,235,29,221,166,25,246,150,63,63,25,138,98,233,86,34,40,120,249,37,46,95,80,169,49,68,221,58,56,151,150,194,168,82,199,2,237,208,5,139,128,11,17,97,244,27,98,22,198,210,174,246],"message":{"asset_id":"sats-usd","ratio":[70000,1],"block_height":870000}}

The method to communicate between Oracle and dApp is not standardized, Oracle can for example provide an API or even communicate using other channels. As long as the message and signature are correct, dApp can use the oracle message as price information on glittr.

During contract execution, the glittr contract must specify which oracle public key to trust, so make sure as an Oracle you have published the public key.

Oracle Commitments
USD Contract