# SmartBch REST API

SmartBch backend wallets wallets are designed after usual BCH mainnet.cash wallets to make it easy to reuse your developed code. Although SmartBch is based on Ethereum technology, we still use BCH (10 ** 18 SmartBch wei) and satoshi (10 ** 10 SmartBch wei) to denote the currency.

This documentation thus is mostly a duplication of a BCH mainnet.cash documentation.

# Introduction

Our REST API allows you to create advanced, performant, and secure financial applications without the usual complexity of blockchain development.

By deploying our REST API on your server, creating enterprise-level cryptocurrency applications becomes effortless.

Important! This tutorial shows calls to https://rest-unstable.mainnet.cash to ease the learning process. You can use it to learn, but for production use you are expected to run your own service (it's very lightweight, just one docker call), because otherwise you actually send us your private keys, which is absolutely insecure. Run your own service, you'll be ok.

This REST API is in production use on noise.cash and creates hundreds of thousands of transactions daily, it's pretty stable, but...

...this server is currently in a beta stage. Things may change randomly. There is no backward compatibility guarantee yet, even though we try not to break things too often.

# Let's get programming

Let's first create a test SmartBch wallet:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/create \
    -H "Content-Type: application/json" \
    -d '{"type": "seed", "network": "testnet"}'

See also: Full REST server API reference (opens new window).

Response:

{
  "name": "",
  "address": "0x983b322E56beA81d4Bb1d4843998aaD530F29578",
  "walletId": "seed:testnet:mango coil clean moral adapt wrist feature purse job produce nominee tail:m/44'/60'/0'/0/0",
  "seed": "mango coil clean moral adapt wrist feature purse job produce nominee tail",
  "derivationPath": "m/44'/60'/0'/0/0",
  "network": "testnet"
}

This creates a TestNet wallet. This has the address of the wallet, where you can send money, and the walletId. Note the walletId - we're going to need it later. This wallet will not be persisted. See below for persistent wallets.

walletId contains the private key

Keep walletId a secret as it contains the private key that allows spending from this wallet. WalletId, Seed phrase, PrivKey - all these are a form of a private key.

What is TestNet? Where to get TestNet money and a wallet?

TestNet is where you test your application. TestNet money has no price. Opposite of TestNet is MainNet, which is what people usually mean when they talk about Bitcoin Cash network.

You can get free TestNet money using our TestNet faucet (see below) or here (opens new window).

If you need a wallet that supports the TestNet install MetaMask browser extension and define a network with a following JSON-RPC endpoint https://moeing.tech:9545. See more here (opens new window).

To create a MainNet wallet (SmartBch production network):

curl -X POST https://rest-unstable.mainnet.cash/wallet/create \
    -H "Content-Type: application/json" \
    -d '{"type": "seed", "network": "mainnet"}'

Response:

{
  "name": "",
  "address": "0x82846Ed87a8fD261b5D1270c8e8431F12Ad52C7C",
  "walletId": "seed:mainnet:either marble skin denial tip depend napkin chunk tornado rigid visit click:m/44'/60'/0'/0/0",
  "seed": "either marble skin denial tip depend napkin chunk tornado rigid visit click",
  "derivationPath": "m/44'/60'/0'/0/0",
  "network": "mainnet"
}

Seed phrase wallets use the derivation path m/44'/60'/0'/0/0 by default (standard for Ethereum networks)

If you want to manually construct a walletId from a Private Key, just build a string like this:

privkey:mainnet:0xPRIVATEKEYHERE

Similarly, from a seed and a derivation path:

seed:mainnet:SEED WORDS HERE:m/DERIVATION/PATH

Networks: mainnet, testnet, regtest (see below)

Note: we generate bindings and packages for some programming languages, so that you don't have to do the REST calls manually, see here. You can generate bindings for nearly every other programming language easily.

# Named wallets (persistent)

Named wallets are used to save the private key inside the REST API server, so that you can refer to it by name and always get the same wallet.

To create a persistent wallet:

curl -X POST https://rest-unstable.mainnet.cash/wallet/create \
    -H "Content-Type: application/json" \
    -d '{"type": "seed", "network": "testnet", "name": "wallet_1"}'

Response:

{
  "name": "wallet_1",
  "address": "0x4A752A89B67A94e2f9d4853fFE62C47e42437a7d",
  "walletId": "named:testnet:wallet_1",
  "seed": "embrace protect ability wave music maximum quick average drink test either analyst",
  "derivationPath": "m/44'/60'/0'/0/0",
  "network": "testnet"
}

The wallet's private key will be stored in the PostgreSQL database of the REST API server.

Note that rest-unstable.mainnet.cash will not allow you to store mainnet private keys, you need to run your own service for that. We really don't want to store your private keys!

To check if a named wallet already exists in the storage, you can invoke:

curl -X POST https://rest-unstable.mainnet.cash/wallet/named_exists \
    -H "Content-Type: application/json" \
    -d '{"type": "seed", "network": "testnet", "name": "wallet_1"}'

Response:

{"result":true}

Say a user of your application wants to change the wallet info to a new seed. Their wallet on the REST server can be replaced (recovered) with the existing walletId:

curl -X POST https://rest-unstable.mainnet.cash/wallet/replace_named \
    -H "Content-Type: application/json" \
    -d '{"name": "wallet_1", "walletId": "seed:testnet:diary caution almost ...:m/44'\''/60'\''/0'\''/0/0", "type": "seed", "network": "testnet"}'

Response:

{"result":true}

If the wallet entry does not exist in the DB, it will be created. If it does - it will be replaced without exception.

# Watch-only wallets

Watch-only wallets do not have private keys and unable to send funds, however they are very useful to keep track of adress' balances, subscribe to its incoming and outgoing transactions, etc.

They are constructed from an address by building a walletId like this:

watch:testnet:0xE25ddbAF8DD61b627727e03e190E32feddBD1319

...and then doing the regular wallet querues like smartbch/wallet/balance.

# Getting the balance

To get the balance of your wallet you can do this (use the walletId that you got previously):

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/balance \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "named:testnet:wallet_1"
  }'

Response:

{"bch": 0.20682058, "sat": 20682058, "usd": 91.04}

Or you can use unit in the call to get just the number:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/balance \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "named:testnet:wallet_1",
    "unit": "sat"
  }'

Response:

20682058

You can ask for usd, sat, bch (or satoshi, satoshis, sats - just in case you forget the exact name).

  • 1 satoshi = 0.00000001 Bitcoin Cash (1/100,000,000th)
  • 1 Bitcoin Cash = 100,000,000 satoshis

usd returns the amount at the current exchange rate, fetched from CoinGecko or Bitcoin.com.

# Sending money

Let's create another wallet and send some of our money there.

Remember, that first you need to send some satoshis to the address of your original wallet (see the TestNet note above).

Check that the balance is there in the original wallet:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/balance \
-H "Content-Type: application/json" \
-d '{"walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45"}'
{"bch": 0.000100000, "sat": 10000, "usd": 0.02}

Now, we can send 100 satoshis to the ...z2pu address

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/send \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
    "to": [
      {
        "address": "0xA2263c06da00Ea7A7fBD5407ff8B8613F33369E6",
        "value": 100,
        "unit": "sat"
      }
    ],
    "options": {
      "queryBalance": true,
      "awaitTransactionPropagation": true
    },
    "overrides": {
      "gasPrice": 100000000000
    }
  }'

Note that you can send to many addresses at once. It is also possible to specify options.

Response:

{
  "txId": "0xc519c3b66955a598dd1f298fcfaf92530db39b70d6d4699c57ffc5faa5aa30f7",
  "balance": {"bch": 0.00009680, "sat": 9680, "usd": 0.02}
}

# Options

There is also an options parameter that specifies how money is spent.

  • queryBalance is a boolean flag (defaulting to true) to include the wallet balance after the successful send operation to the returned result. If set to false, the balance will not be queried and returned, making the send call faster.
  • awaitTransactionPropagation is a boolean flag (defaulting to true) to wait for transaction to propagate through the network and be registered in the bitcoind and indexer. If set to false, the send call will be very fast, but the wallet UTXO state might be invalid for some 500ms.

# Overrides

There is also an overrides parameter that specifies how network goes about your transaction.

  • gasPrice override the price of each gas unit consumed in the transaction.
  • gasLimit is the limit of the gas amount you allow this transaction to consume.

The total network fee you must pay for the transaction to be processed by the network is gasAmount * gasPrice

# Getting balance

Let's print the balance of 0xA22... wallet:

{"bch": 0.00000100, "sat": 100, "usd": 0.00}

Great! You've just made your first transaction!

Now you can send all of your money somewhere else:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/send_max \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
    "cashaddr": "0xA2263c06da00Ea7A7fBD5407ff8B8613F33369E6"
  }'

This will send the maximum amount (minus the transaction fees). Note, that you can also use here the optional parameter options and overrides to steer the network interaction (see above).

# QR codes

Let's say you want to display a QR code for you user to pay you money and show an alert when money arrives?

Let's display a QR code:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/wallet/deposit_qr \
  -H "Content-Type: application/json" \
  -d '{
    "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45"
  }'

Response:

{"src":"data:image/svg+xml;base64,PD94bWwgdmVyc2...."}

You can use this src directly in the image tag:

<p style="text-align: center;">
    <img src="data:image/svg+xml;base64,PD94bWwgdmVyc2...." style="width: 15em;">
</p>

# Waiting for blockchain events

Coming soon.

# SEP20 (ERC20) token protocol

We currently fully support the SEP20 tokens specification (opens new window)

The interfaces were designed to be largely similar to those of BCH wallets and SLP protocol.

Note, that REST server uses strings for the token amounts in order not to lose precision or have floating point issues.

# Token creation - Genesis

To create your own token you should prepare and broadcast a special genesis transaction containing all the information about the token being created: token name, ticker, decimals - number of significant digits after comma, initial token amount. Some of these properties are optional.

With the endBaton parameter you can decide to keep the possibility of additional token creation, which is governed by so called minting baton or immediately discard this baton to make the token circulation amount to be fixed.

Note, that there might be many tokens with the same name. Remember, that only 42 character long string-ids do identify your token uniquely und unambiguously.

In the following example 10000.00 MNC tokens will be created.

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/genesis \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "name": "Mainnet coin",
  "ticker": "MNC",
  "initialAmount": "10000",
  "decimals": 2,
  "endBaton": false,
  "overrides": {
    "gasPrice": 100000000000
  }
}'

Response:

{
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e",
  "balance": {
    "name": "Mainnet Coin",
    "ticker": "MNC",
    "decimals": 8,
    "value": "10000",
    "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
  }
}

Optional tokenReceiverAddress and batonReceiverAddress allow to specify the receiver of tokens and minting baton.

# Looking up token information

If you want to get the genesis information of some token, you can simply call smartbch/sep20/token_info:

curl -X POST https://rest-unstable.mainnet.cash/wallet/sep20/token_info \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
}'

Response:

{
  "name": "Mainnet Coin",
  "ticker": "MNC",
  "decimals": 8,
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e",
  "totalSupply": "10000"
}

# Additional token creation - Minting

If you decide to increase the token circulation supply, you would need to mint more tokens. You are required to have the ownership of the minting baton to do so.

In the following example we issue 50 more tokens we just created in genesis:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/mint \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "value": "50",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e",
  "tokenReceiverAddress": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
  "overrides": {
    "gasPrice": 100000000000
  }
}'

Optional tokenReceiverAddress allow to specify the receiver of tokens.

Response:

{
  "txId": "0xc519c3b66955a598dd1f298fcfaf92530db39b70d6d4699c57ffc5faa5aa30f7",
  "balance": {
    "name": "Mainnet Coin",
    "ticker": "MNC",
    "decimals": 8,
    "value": "10050",
    "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
  }
}

# Sending tokens

Sending tokens around is easy and is very similar to sending BCH. You can include many send requests in one call too!

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/send \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "to": [
    {
      "address": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
      "value": 100,
      "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
    }
  ],
  "overrides": {
    "gasPrice": 100000000000
  }
}'

Response:

[{
  "txId": "0xc519c3b66955a598dd1f298fcfaf92530db39b70d6d4699c57ffc5faa5aa30f7",
  "balance": {
    "value": "19900",
    "ticker": "MNC",
    "name": "Mainnet coin",
    "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
  }
}]

Or you can send all tokens available with a simple smartbch/sep20/send_max method

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/send_max \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "address": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e",
  "overrides": {
    "gasPrice": 100000000000
  }
}'

Response:

{
  "txId": "0xc519c3b66955a598dd1f298fcfaf92530db39b70d6d4699c57ffc5faa5aa30f7",
  "balance": {
    "value": "0",
    "ticker": "MNC",
    "name": "Mainnet coin",
    "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
  }
}

# Token balances

You can get all token balances of your wallet or a balance of a specific token with the following methods:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/balance \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
}'

Response:

{
  "value": "10000",
  "ticker": "MNC",
  "name": "Mainnet coin",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
}

All balances:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/sep20/all_balances \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
}'

Response:

[{
  "value": "10000",
  "ticker": "MNC",
  "name": "Mainnet coin",
  "tokenId": "0xca4A3794Ba7761a480F1356CC1B22E35321C2b4e"
}]

smartbch/sep20/all_balances does a deep blockchain scan for tokens transferred to or from this address. Might take a long time to run and time out your request. Deep rescan will be skipped by default if a previous scan was performed for a particular wallet. If you know there were transactions including new tokens, use forceRescan: true. If you want to know the full list of tokens ever transferred to or from the address, use hideEmpty: false.

# Sep20 deposit address

You can get the token deposit address:

curl -X POST https://rest-unstable.mainnet.cash/wallet/sep20/deposit_address \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45"
}'

Response:

{
  "address": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319"
}

# Sep20 deposit QR code

You can get the deposit address embedded in a QR code image. The response is ready to be used in HTML src, title and alt attributes of an img node.

curl -X POST https://rest-unstable.mainnet.cash/wallet/sep20/deposit_qr \
  -H "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:testnet:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45"
}'

Response:

{
  "src": "data:image/svg+xml;base64,PD94bWwgdm... ==**",
  "title": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
  "alt": "A Bitcoin Cash Simple Ledger Protocol QR Code"
}

# Non-fungible tokens (NFT)

Coming soon.

# TestNet faucet

You can have some SmartBch TestNet satoshi or SEP20 tokens for your convenience. Visit our faucet refilling station at https://rest-unstable.mainnet.cash/faucet.html (opens new window)

Your address will be refilled up to 0.1 TestNet BCH or up to 10 SEP20 tokens upon a call. There are request rate limiters set up to prevent abuse.

We've integrated the faucet into the library so that you can do easy calls like the following.

# Get TestNet satoshis

curl -X POST https://rest-unstable.mainnet.cash/faucet/get_testnet_sbch \
  -H "Content-Type: application/json" \
  -d '{
  "address": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319"
}'

# Get TestNet SEP20 tokens

curl -X POST https://rest-unstable.mainnet.cash/faucet/get_testnet_sep20 \
  -H "Content-Type: application/json" \
  -d '{
  "address": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
  "tokenId": "0xdac17f958d2ee523a2206206994597c13d831ec7"
}'

Requesting testnet funds uses a queue for batch-processing. Hence, no txId is returned immediately. The request is usually settled in 1-3 blocks.

# Smart Contracts

Contracts are objects that allow one to interact with Smart Contracts already deployed on SmartBch network or to deploy new ones.

Note, that unlike the BCH contracts, SmartBch contract do not use nonce.

We allow to deploy solidity (opens new window) based contracts. Example SEP20 contract:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.2;

import "@openzeppelin/contracts/token/SEP20/SEP20.sol";

contract MyToken is SEP20 {
  constructor(string memory name, string memory symbol) SEP20(name, symbol) {}
}

# Creating a contract interface (contractId)

To interact with already deployed contracts you need the contract address and its ABI (Application Binary Interface). You can invoke the following method:

curl -X POST https://rest-unstable.mainnet.cash/smartbch/contract/create \
  -H  "Content-Type: application/json" \
  -d '{
  "address": "0xdac17f958d2ee523a2206206994597c13d831ec7",
  "abi": "[\"function name() view returns (string)\", \"function symbol() view returns (string)\"]",
  "network": "regtest"
}'

Resposnse:

{
  "contractId": "smartbchcontract:regtest:0xdac17f958d2ee523a2206206994597c13d831ec7:WyJmdW5jdGlvbiBuYW1lKCkgdmlldyByZXR1cm5zIChzdHJpbmcpIiwiZnVuY3Rpb24gc3ltYm9sKCkgdmlldyByZXR1cm5zIChzdHJpbmcpIl0=::W10=",
  "address": "0xdac17f958d2ee523a2206206994597c13d831ec7"
}

# Deploying a contract

This contract may be used over the REST interface by passing the contract script, constructor parameters and network to the smartbch/contract/deploy endpoint.

curl -X POST https://rest-unstable.mainnet.cash/smartbch/contract/deploy \
  -H  "Content-Type: application/json" \
  -d '{
  "walletId": "privkey:regtest:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "script": "\n    // SPDX-License-Identifier: MIT\n    pragma solidity ^0.8.2;\n\n    import \"@openzeppelin/contracts/token/SEP20/SEP20.sol\";\n\n    contract MyToken is SEP20 {\n      constructor(string memory name, string memory symbol) SEP20(name, symbol) {\n        _mint(msg.sender, 10000);\n      }\n    }",
  "parameters": [
    "MyToken",
    "MTK"
  ],
  "overrides": {
    "gasPrice": 10000000000
  }
}'

Response:

The response is a serialized contract, (storing the network, raw script, and constructor parameters), as well as the deposit address for the contract.

{
  "contractId": "smartbchcontract:regtest:0x904b57B6870be5528f398643fFAD655a7332D0Ee:Wy...iwiTVRLIl0=",
  "address": "0x904b57B6870be5528f398643fFAD655a7332D0Ee",
  "txId": "0xb029176d543a9850162434595d954acc38346f742007adf40e12ff48c9ba2d08",
  "receipt": {
    "to": "0x0000000000000000000000000000000000000000",
    "from": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
    ...
    "gasUsed": {
      "type": "BigNumber",
      "hex": "0x1309c0"
    },
    ...
    "blockNumber": 13420,
    "confirmations": 1,
  }
}
}

# Calling a contract function

Using with the contractId and a walletId, it is fairly straight-forward to call the contract function:

curl -X POST "https://rest-unstable.mainnet.cash/smartbch/contract/call" \
  -H  "Content-Type: application/json" \
'{
  "walletId": "privkey:regtest:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "contractId": "smartbchcontract:regtest:0x904b57B6870be5528f398643fFAD655a7332D0Ee:Wy...iwiTVRLIl0=",
  "function": "transfer",
  "arguments": [
    "0xbDDb9c288C0fF0803a9d56644464A00978ff7616",
    10000
  ],
  "overrides": {
    "gasPrice": 10000000000
  }
}'

Response:

{
  "txId": "0x15aa9de7e3d0ec76a11feadf2ba803544ea22084c62c4c23078f7636cb5bd6b5",
  "receipt": {
    "to": "0xbDDb9c288C0fF0803a9d56644464A00978ff7616",
    "from": "0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
    ...
    "gasUsed": {
      "type": "BigNumber",
      "hex": "0x8fe0"
    },
    ...
    "blockNumber": 13168,
    "confirmations": 1,
  }
}

# Obtain contract information

If a contractId refers to a contract created by another party, or it's necessary for another party to confirm details of a contract, the contract information endpoint is available to return details of a contract, given a contractId.

Depending upon contractId creation (create or deploy) the information about contract script and constructor arguments may be unavailable (create method).

curl -X POST "https://rest-unstable.mainnet.cash/contract/info" \
   -H  "Content-Type: application/json" \
'{
  "contractId": "smartbchcontract:regtest:0x24CC5bb26a2c9F0e6428F155532878Be276CFf89:WyJj...CB9:WyJNeVRva2VuIiwiTVRLIl0=",

}'

This will return all the arguments to reconstruct or verify a contract.

{
  "contractId": "contractId": "smartbchcontract:regtest:0x24CC5bb26a2c9F0e6428F155532878Be276CFf89:WyJj...CB9:WyJNeVRva2VuIiwiTVRLIl0=",
  "address": "0x24CC5bb26a2c9F0e6428F155532878Be276CFf89",
  "abi": [
    "constructor(string name, string symbol)",
    "event Approval(address indexed owner, address indexed spender, uint256 value)",
    "event Transfer(address indexed from, address indexed to, uint256 value)",
    "function allowance(address owner, address spender) view returns (uint256)",
    "function approve(address spender, uint256 amount) returns (bool)",
    "function balanceOf(address account) view returns (uint256)",
    "function decimals() view returns (uint8)",
    "function decreaseAllowance(address spender, uint256 subtractedValue) returns (bool)",
    "function increaseAllowance(address spender, uint256 addedValue) returns (bool)",
    "function name() view returns (string)",
    "function symbol() view returns (string)",
    "function totalSupply() view returns (uint256)",
    "function transfer(address recipient, uint256 amount) returns (bool)",
    "function transferFrom(address sender, address recipient, uint256 amount) returns (bool)"
  ],
  "script": "\n    // SPDX-License-Identifier: MIT\n    pragma solidity ^0.8.2;\n\n    import \"@openzeppelin/contracts/token/SEP20/SEP20.sol\";\n\n    contract MyToken is SEP20 {\n      constructor(string memory name, string memory symbol) SEP20(name, symbol) {\n        _mint(msg.sender, 10000);\n      }\n    }",
  "parameters": [
    "MyToken",
    "MTK"
  ]
}

# Estimate contract function fees

You can ask the network to estimate the gas amount of a certain contract function to be executed. Total fee is then gasAmount * gasPrice

curl -X POST "https://rest-unstable.mainnet.cash/smartbch/contract/estimate_gas" \
   -H  "Content-Type: application/json" \
'{
  "walletId": "privkey:regtest:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "contractId": "smartbchcontract:regtest:0x24CC5bb26a2c9F0e6428F155532878Be276CFf89:WyJj...CB9:WyJNeVRva2VuIiwiTVRLIl0=",
  "function": "transfer",
  "arguments": [
    "0x24CC5bb26a2c9F0e6428F155532878Be276CFf89",
    10000
  ],
  "overrides": {
    "gasPrice": 10000000000
  }
}'

Response:

```json
{
  "gas": {
    "type": "BigNumber",
    "hex": "0xde0c"
  }
}

Note, that non state-changing functions will return 0 as a result.

# Utilities

Certain tools common in bitcoin-like currencies may not be in a standard library.

# Currency conversions

Need to find out how many BCH are there currently in 1 USD, or find out how many satoshis are there in 100 USD? Easy!

curl -X POST https://rest-unstable.mainnet.cash/util/convert \
  -H "Content-Type: application/json" \
  -d '{
  "value": 100,
  "from": "usd",
  "to": "sat"
}'

returns something like:

...
28067024
...

# Signed Messages

One of the perks of having a wallet is the ability to sign message text or verify the signatures of other parties using their public key.

Full-nodes and SPV wallets often include this feature as standard.

# Signing a message with a wallet

Let's try signing with an example from a common test case:

curl -X POST "https://rest-unstable.mainnet.cash/smartbch/wallet/signed/sign" \
-H  "accept: application/json" \
-H  "Content-Type: application/json" \
-d '{
  "walletId": "privkey:regtest:0x758c7be51a76a9b6bc6b3e1a90e5ff4cc27aa054b77b7acb6f4f08a219c1ce45",
  "message": "Chancellor on brink of second bailout for banks"
}'


Where the response is:

{
  "signature": "0x60dc03b4f31f174f9c0577ea8140b6b13e57a0141fc27238a0c53971066fcb02511bc4aacbc8728c7f5c6cd3a9854960975968601c8381ee483580d1d57c1bd21c"
}

# Verifying a message with a wallet

To verify the above signature (without having access to the private key), by using a watchOnly wallet to represent the party in the example above.

curl -X POST "https://rest-unstable.mainnet.cash/wallet/signed/verify" \
-H  "accept: application/json"  \
-H  "Content-Type: application/json" \
-d '{
  "walletId": "watch:regtest:0xE25ddbAF8DD61b627727e03e190E32feddBD1319",
  "message": "Chancellor on brink of second bailout for banks",
  "signature": "0x60dc03b4f31f174f9c0577ea8140b6b13e57a0141fc27238a0c53971066fcb02511bc4aacbc8728c7f5c6cd3a9854960975968601c8381ee483580d1d57c1bd21c"
}'

where response is:

{
  "valid": true
}

# RegTest wallets

See reference

# Webhooks

Coming soon.

# WebSocket API reference

Coming soon.