Skip to content

Instantly share code, notes, and snippets.

@tjanez
Forked from lukaw3d/sapphire 2024.md
Created January 30, 2026 09:29
Show Gist options
  • Select an option

  • Save tjanez/f0cca840c22d563e6149c1b1796b01ce to your computer and use it in GitHub Desktop.

Select an option

Save tjanez/f0cca840c22d563e6149c1b1796b01ce to your computer and use it in GitHub Desktop.
end of 2024 notes on how to start using Sapphire on Oasis

end of 2024 notes on how to start using Sapphire on Oasis

Sapphire ParaTime is like a rollup on top of Oasis Consensus chain. Consensus handles governance. Sapphire handles solidity contracts with private variables/storage.

Setup an EVM wallet

Install MetaMask. Then click "Add to MetaMask" under "sapphire.oasis.io" https://docs.oasis.io/dapp/sapphire/network#rpc-endpoints

Get ROSE tokens

Check balance

Stake on Sapphire (earn ~2.5% per year until ~2030)

Sell ROSE

  • use an exchange that supports Sapphire ROSE (e.g. MEXC, XeggeX, KuCoin)
  • use an exchange that supports Consensus ROSE (e.g. coinbase, binance) and move ROSE through https://rose.oasis.io/move/ to Consensus

More security

Use private dApps


Developers: Create new private dApps

Use APIs:

  • Oasis gRPC: https://grpc.oasis.io

    reliable, hard to use, very few interesting endpoints, loadbalanced so nodes can possibly return different height

    use with npm @oasisprotocol/client-rt

    import * as oasis from '@oasisprotocol/client'
    import * as oasisRT from '@oasisprotocol/client-rt'
    import BigNumber from 'bignumber.js'
    
    export const sapphireConfig = {
      mainnet: {
        runtimeId: '000000000000000000000000000000000000000000000000f80306c9858e7279',
      },
      testnet: {
        runtimeId: '000000000000000000000000000000000000000000000000a6d1e3ebf60dff6c',
      },
      decimals: 18,
    }
    
    export async function getSapphireBalance(ethAddress: `0x${string}`) {
      const nic = new oasis.client.NodeInternal('https://grpc.oasis.io')
      const consensusWrapper = new oasisRT.consensusAccounts.Wrapper(oasis.misc.fromHex(sapphireConfig.mainnet.runtimeId))
      const underlyingAddress = await oasis.address.fromData(
        oasisRT.address.V0_SECP256K1ETH_CONTEXT_IDENTIFIER,
        oasisRT.address.V0_SECP256K1ETH_CONTEXT_VERSION,
        oasis.misc.fromHex(ethAddress.replace('0x', '')),
      )
    
      const balanceResult = await consensusWrapper
        .queryBalance()
        .setArgs({
          address: underlyingAddress,
        })
        .query(nic)
      const balance = oasis.quantity.toBigInt(balanceResult.balance)
      return {
        raw: balance,
        formatted: fromBaseUnits(balance, sapphireConfig.decimals),
      }
    }
    
    function fromBaseUnits(valueInBaseUnits: bigint, decimals: number): string {
      const value = new BigNumber(valueInBaseUnits.toString()).shiftedBy(-decimals) // / 10 ** decimals
      if (value.isNaN()) {
        throw new Error(`Not a number in fromBaseUnits(${valueInBaseUnits})`)
      }
      return value.toFixed()
    }
  • Oasis Explorer's API: https://nexus.oasis.io/v1/spec/v1.html

    not as reliable, some endpoints are slow and throw timeout errors, data can sometimes be a few minutes behind gRPC

  • Web3 gateway: https://sapphire.oasis.io

    many ethereum-compatible tools use this, but it only returns EVM transactions, (e.g. this would be missing https://explorer.dev.oasis.io/mainnet/sapphire/tx/cb54b077f856756e616002cd8a328dc97ae875dc6910664e36d9aed18511480c - moving ROSE from/to Consensus, making a Sapphire transfer using Oasis CLI, staking using Oasis CLI)

  • Rosetta API, without most useful optional endpoints: https://rosetta.oasis.io/api/block

    eww

  • other https://docs.oasis.io/dapp/sapphire/network#indexers

(You can also create a custom ParaTime, e.g. clone Sapphire, but only allow your compute nodes)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment