ForgeSdk v0.37.0 ForgeSdk View Source

Forge is a full fledge blockchain framework for developers to build decentralized applications easily. Forge gives the developers / operators the freedom to launch their own customized chains with their own application logic.

This is the Elixir / Erlang version of the SDK for Forge framework. To develop applications on top of the forge, you shall pick up a SDK. Forge SDK is intended to make the interaction with the chain built by Forge as easy as possible. All SDK APIs are organized into the following categories:

  • chain APIs: provide the client wrapper for chain related gRPC
  • wallet APIs: provide the client wrapper for wallet related gRPC
  • state APIs: provide the client wrapper for state related gRPC
  • subscription APIs: provide the client wrapper for subscription related gRPC
  • transaction APIs: the gRPC for transaction is send_tx, this set of APIs provide helper functions to make building and sending a tx easy.
  • misc APIs: parsing configuration, initialize sdk and more.

Link to this section Summary

Functions

Migrate a wallet from old address (as well as pk, sk) to a new address

Acquire an asset from an existing asset factory

One wallet can check in a daily basis to get some free tokens (for test chains only), nonce should be 0

Create a new asset

This will generate a wallet with default DID type: public key type is ED25519, hash type is sha3(256), and DID role type is account

You can pass in your own DID type in a map once you want to create a wallet with different settings

Declare a wallet to the chain

Deploy a new protocol into the chain at a given block height

Provide a display friendly result for a data structure

Return the state for an account, node, validator or application address

Return the state for an asset

Get a block by its height. All txs included in this block will be returned

Get a list of blocks between a range

Retrieve the current status of the chain

Return global state for forge

Retrieve the network info

Retrive the current status of the node

Return installed protocol state

Return an already processed transaction by its hash. If this API returns nil, mostly your tx hasn't been

Retrieve the current validator info

Display the wallet addresses that current forge node hosts

Load a node managed wallet by its address and passphrase from the keystore

Forge we support multisig for a tx, you can use this to endorse an already signed tx. ExchangeTx, ConsumeAssetTx and some other txs are using multisig technology

One wallet can poke in a daily basis to get some free tokens (for test chains only), nonce should be 0

If you know the type and the secret key of the wallet, you can recover it into the current forge node. This is useful when you want to switch your wallet from one node to another. This will generate a keystore file

Delete the keystore for a given wallet address. This is useful when you finished your work on the forge node and you'd remove the footprint for your wallet

Subscribe to a topic. You can event set a filter for the event that you'd listen

Transfer tokens or/and assets from one wallet to another

Terminate the subscription by the topic id

Update an existing asset

Upgrade the node to a new version at a given block height

Link to this section Functions

Link to this function

account_migrate(itx, opts) View Source
account_migrate(map(), Keyword.t()) :: String.t() | {:error, term()}

Migrate a wallet from old address (as well as pk, sk) to a new address.

Example

old_wallet = ForgeSdk.create_wallet()
declare_tx = ForgeAbi.DeclareTx.new(moniker: "sisyphus")
ForgeSdk.declare(declare_tx, wallet: old_wallet)
new_wallet = ForgeSdk.create_wallet()
itx = ForgeAbi.AccountMigrateTx.new(pk: new_wallet.pk, address: new_wallet.address)
ForgeSdk.account_migrate(itx, wallet: old_wallet)
Link to this function

acquire_asset(itx, opts) View Source
acquire_asset(map(), Keyword.t()) :: String.t() | {:error, term()}

Acquire an asset from an existing asset factory.

Example

w = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "theater"), wallet: w)
w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "tyr"), wallet: w)

# Note application shall already registered `Ticket` into Forge via `deploy_protocol`.
factory = %{
description: "movie ticket factory",
limit: 5,
price: ForgeAbi.token_to_unit(1),
template: ~s({
    "row": "{{ row }}",
    "seat": "{{ seat }}",
    "time": "11:00am 04/30/2019",
    "room": "4"
  }),
allowed_spec_args: ["row", "seat"],
asset_name: "Ticket",
attributes: %ForgeAbi.AssetAttributes{
  transferrable: true,
  ttl: 3600 * 3
  }
}

ForgeSdk.create_asset_factory("Avenerages: Endgame", factory, wallet: w)

specs =
  Enum.map(["0", "2"], fn seat ->
    apply(ForgeAbi.AssetSpec, :new, [%{data: ~s({"row": "15", "seat": "#{seat}"})}])
  end)

itx = ForgeAbi.AcquireAssetTx.new(to: address, specs: specs)

ForgeSdk.acquire_asset(itx, wallet: w1)
Link to this function

approve_tether(itx, opts) View Source

Link to this function

checkin(opts) View Source
checkin(Keyword.t()) :: String.t() | {:error, term()}

One wallet can check in a daily basis to get some free tokens (for test chains only), nonce should be 0.

Example

w = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w)
ForgeSdk.checkin(wallet: w)
Link to this function

create_asset(itx, opts) View Source
create_asset(map(), Keyword.t()) :: String.t() | {:error, term()}

Create a new asset.

Example

wallet = ForgeSdk.create_wallet()
declare_tx = ForgeAbi.DeclareTx.new(moniker: "sisyphus")
ForgeSdk.declare(declare_tx, wallet: wallet)
ticket = ForgeAbi.Ticket.new(row: "K", seat: "22", room: "3A", time: "03/04/2019 11:00am PST",
name: "Avengers: Endgame")
itx = ForgeAbi.CreateAsset.new(data: ForgeSdk.encode_any!(ticket), readonly: true,
transferrable: true, ttl: 7200)
ForgeSdk.create_asset(itx, wallet: wallet)
Link to this function

create_asset_factory(moniker, factory, opts) View Source
create_asset_factory(String.t(), map(), Keyword.t()) ::
  String.t() | {:error, term()}

Create a new asset factory.

Example

w = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "theater"), wallet: w)
w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "tyr"), wallet: w)

# Note application shall already registered `Ticket` into Forge via `deploy_protocol`.
factory = %{
  description: "movie ticket factory",
  limit: 5,
  price: ForgeAbi.token_to_unit(1),
  template: ~s({
      "row": "{{ row }}",
      "seat": "{{ seat }}",
      "time": "11:00am 04/30/2019",
      "room": "4"
    }),
  allowed_spec_args: ["row", "seat"],
  asset_name: "Ticket",
  attributes: %ForgeAbi.AssetAttributes{
    transferrable: true,
    ttl: 3600 * 3
  }
}

ForgeSdk.create_asset_factory("Avenerages: Endgame", factory, wallet: w)
Link to this function

create_tx(request, conn_name \\ "") View Source
create_tx(ForgeAbi.RequestCreateTx.t() | Keyword.t(), String.t() | atom()) ::
  ForgeAbi.Transaction.t() | {:error, term()}

Create tx.

Example

w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w1)
w2 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "bob"), wallet: w2)
data = Google.Protobuf.Any.new(type_url: "test_asset", value: "hello world")
itx = ForgeSdk.encode_any!(TransferTx.new(to: w2.address, value: new_unit(100)))
req = RequestCreateTx.new(itx: itx, from: w1.address, nonce: 2, walllet: w1)
tx = ForgeSdk.create_tx(req)

This will generate a wallet with default DID type: public key type is ED25519, hash type is sha3(256), and DID role type is account.

Example

ForgeSdk.create_wallet()
Link to this function

create_wallet(request, conn_name \\ "") View Source
create_wallet(
  ForgeAbi.RequestCreateWallet.t() | Keyword.t(),
  String.t() | atom()
) :: {ForgeAbi.WalletInfo.t(), String.t()} | {:error, term()}

You can pass in your own DID type in a map once you want to create a wallet with different settings.

Example

w1 = ForgeSdk.create_wallet()
ForgeSdk.create_wallet(moniker: "alice", passphrase: "abcd1234")
Link to this function

declare(itx, opts) View Source
declare(map(), Keyword.t()) :: String.t() | {:error, term()}

Declare a wallet to the chain.

Example

wallet = ForgeSdk.create_wallet()
declare_tx = ForgeAbi.DeclareTx.new(moniker: "sisyphus")
ForgeSdk.declare(declare_tx, wallet: wallet)
Link to this function

declare_node(request, conn_name \\ "") View Source

Link to this function

deploy_protocol(itx, opts) View Source
deploy_protocol(map(), Keyword.t()) :: String.t() | {:error, term()}

Deploy a new protocol into the chain at a given block height.

Example

itx = data |> Base.url_decode64!(padding: false) |> ForgeAbi.DeployProtocolTx.decode()
ForgeSdk.deploy_protocol(itx, wallet: wallet)
Link to this function

deposit_tether(itx, opts) View Source

Link to this function

display(data, expand? \\ false) View Source
display(any(), boolean()) :: any()

Provide a display friendly result for a data structure.

Examples

req = ForgeAbi.RequestGetAccountState.new(address: "z1QNTPxDUCbh68q6ci6zUmtnT2Cj8nbLw75")
account_state = ForgeSdk.get_account_state(req)
ForgeSdk.display(account_state)
Link to this function

encode_any(data, type_url \\ nil) View Source

Link to this function

encode_any!(data, type_url \\ nil) View Source

Link to this function

exchange_tether(itx, opts) View Source

Link to this function

finalize_consume_asset(tx, opts) View Source
finalize_consume_asset(ForgeAbi.Transaction.t(), Keyword.t()) ::
  {:error, any()} | ForgeAbi.Transaction.t()

Link to this function

finalize_exchange(tx, opts) View Source
finalize_exchange(ForgeAbi.Transaction.t(), Keyword.t()) ::
  {:error, term()} | ForgeAbi.Transaction.t()

Link to this function

get_account_state(request, conn_name \\ "") View Source

Return the state for an account, node, validator or application address.

Example

req = ForgeAbi.RequestGetAccountState.new(address: "z1QNTPxDUCbh68q6ci6zUmtnT2Cj8nbLw75")
ForgeSdk.get_account_state(req)
Link to this function

get_asset_state(request, conn_name \\ "") View Source

Return the state for an asset.

Example

req = ForgeAbi.RequestGetAssetState.new(address: "zjdjh65vHxvvWfj3xPrDoUDYp1aY6xUCV21b")
ForgeSdk.get_asset_state(req)

Get a block by its height. All txs included in this block will be returned.

Example

req = ForgeAbi.RequestGetBlock.new(height: 1000)
ForgeSdk.get_block(req)
Link to this function

get_blocks(request, conn_name \\ "") View Source

Get a list of blocks between a range.

Example

page_info = ForgeAbi.PageInfo.new
range_filter = ForgeAbi.RangeFilter.new(from: 1000, to: 1015)
req = ForgeAbi.RequestGetBlocks.new(empty_excluded: true, height_filter: range_filter,
paging: page_info)
ForgeSdk.get_blocks(req)
Link to this function

get_chain_info(conn_name \\ "") View Source
get_chain_info(String.t()) :: ForgeAbi.ChainInfo.t() | {:error, term()}

Retrieve the current status of the chain.

Example

ForgeSdk.get_chain_info()
Link to this function

get_config(request, conn_name \\ "") View Source

Link to this function

get_delegate_state(request, conn_name \\ "") View Source

Link to this function

get_forge_state(conn_name \\ "") View Source
get_forge_state(String.t() | atom()) ::
  ForgeAbi.ForgeState.t() | {:error, term()}

Return global state for forge.

Example

ForgeSdk.get_forge_state()
Link to this function

get_forge_stats(requests, conn_name \\ "") View Source

Link to this function

get_health_status(request, conn_name \\ "") View Source

Link to this function

get_net_info(conn_name \\ "") View Source
get_net_info(String.t()) :: ForgeAbi.NetInfo.t() | {:error, term()}

Retrieve the network info.

Example

ForgeSdk.get_net_info()
Link to this function

get_node_info(conn_name \\ "") View Source
get_node_info(String.t()) :: ForgeAbi.NodeInfo.t() | {:error, term()}

Retrive the current status of the node.

Example

ForgeSdk.get_node_info()
Link to this function

get_parsed_config(name \\ "") View Source

Return installed protocol state.

Example

req = ForgeAbi.RequestGetProtocolState.new(address: "z2E3zCQTx5dPQeimQvJWz3vJvcDv9Ad6YgaPn")
ForgeSdk.get_protocol_state(req)
Link to this function

get_stake_state(request, conn_name \\ "") View Source

Link to this function

get_swap_state(request, conn_name \\ "") View Source

Link to this function

get_tether_state(request, conn_name \\ "") View Source

Return an already processed transaction by its hash. If this API returns nil, mostly your tx hasn't been.

Example

hash = ForgeSdk.send_tx(tx: tx)
ForgeSdk.get_tx(hash: hash)
Link to this function

get_tx_protocols(forge_state, address) View Source

Link to this function

get_unconfirmed_txs(request, conn_name \\ "") View Source

Link to this function

get_validators_info(conn_name \\ "") View Source
get_validators_info(String.t()) ::
  ForgeAbi.ValidatorsInfo.t() | {:error, term()}

Retrieve the current validator info.

Example

ForgeSdk.get_validators_info()
Link to this function

list_account(request, conn_name \\ "") View Source

Link to this function

list_asset_transactions(request, conn_name \\ "") View Source

Link to this function

list_assets(request, conn_name \\ "") View Source

Link to this function

list_blocks(request, conn_name \\ "") View Source

Link to this function

list_stakes(request, conn_name \\ "") View Source

Link to this function

list_swap(request, conn_name \\ "") View Source

Link to this function

list_tethers(request, conn_name \\ "") View Source

Link to this function

list_top_accounts(request, conn_name \\ "") View Source

Link to this function

list_transactions(request, conn_name \\ "") View Source

Link to this function

list_wallet(conn_name \\ "") View Source
list_wallet(String.t() | atom()) :: String.t() | {:error, term()}

Display the wallet addresses that current forge node hosts.

Example

ForgeSdk.list_wallet()
Link to this function

load_wallet(request, conn_name \\ "") View Source
load_wallet(ForgeAbi.RequestLoadWallet.t() | Keyword.t(), String.t() | atom()) ::
  String.t() | {:error, term()}

Load a node managed wallet by its address and passphrase from the keystore.

Example

{w, t} = ForgeSdk.create_wallet(moniker: "alice", passphrase: "abcd1234")
req = ForgeAbi.RequestLoadWallet.new(address: w.address, passphrase: "abcd1234")
ForgeSdk.load_wallet(req)
Link to this function

multisig(request, conn_name \\ "") View Source
multisig(ForgeAbi.RequestMultisig.t() | Keyword.t(), String.t() | atom()) ::
  ForgeAbi.Transaction.t() | {:error, term()}

Forge we support multisig for a tx, you can use this to endorse an already signed tx. ExchangeTx, ConsumeAssetTx and some other txs are using multisig technology.

Example

w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w1)
w2 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "bob"), wallet: w2)
data = Google.Protobuf.Any.new(type_url: "test_asset", value: "hello world")
hash = ForgeSdk.create_asset(ForgeAbi.CreateAssetTx.new(data: asset_data), wallet: w2)
asset_address = ForgeSdk.get_address(hash)
sender_info = ForgeAbi.ExchangeInfo.new(value: ForgeSdk.token_to_unit(1))
receiver_info = ForgeAbi.ExchangeInfo.new(assets: [asset_address])
itx = ForgeAbi.ExchangeTx.new(to: w2.address, sender: sender_info, receiver: receiver_info)
tx = ForgeSdk.prepare_exchange(itx, wallet: w1)
tx1 = ForgeSdk.multisig(tx, w2)
ForgeSdk.send_tx(tx: tx1)

One wallet can poke in a daily basis to get some free tokens (for test chains only), nonce should be 0.

Example

w = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w)
itx = ForgeAbi.PokeTx.new(date: "2019-03-13", address: "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")
req = ForgeAbi.RequestCreateTx.new(from: w.address, itx: ForgeAbi.encode_any!(:poke, itx),
nonce: 0, token: t, wallet: w)
tx = ForgeSdk.create_tx(req)
hash = ForgeSdk.send_tx(tx: tx)
Link to this function

prepare_consume_asset(itx, opts) View Source
prepare_consume_asset(map(), Keyword.t()) ::
  ForgeAbi.Transaction.t() | {:error, term()}

Link to this function

prepare_exchange(itx, opts) View Source
prepare_exchange(map(), Keyword.t()) ::
  ForgeAbi.Transaction.t() | {:error, term()}

Link to this function

recover_wallet(request, conn_name \\ "") View Source
recover_wallet(ForgeAbi.RequestRecoverWallet.t(), String.t()) ::
  {ForgeAbi.WalletInfo.t(), String.t()} | {:error, term()}

If you know the type and the secret key of the wallet, you can recover it into the current forge node. This is useful when you want to switch your wallet from one node to another. This will generate a keystore file.

Example

{w, t} = ForgeSdk.create_wallet(moniker: "alice", passphrase: "abcd1234")
request = RequestRecoverWallet.new(data: w.sk, type: w.type, passphrase: "abcd1234")
ForgeSdk.recover_wallet(req)
Link to this function

remove_wallet(request, conn_name \\ "") View Source
remove_wallet(
  ForgeAbi.RequestRemoveWallet.t() | Keyword.t(),
  String.t() | atom()
) :: :ok | {:error, term()}

Delete the keystore for a given wallet address. This is useful when you finished your work on the forge node and you'd remove the footprint for your wallet.

Example

{w, t} = ForgeSdk.create_wallet(moniker: "alice", passphrase: "abcd1234")
request = RequestRemoveWallet.new(address: w.address)
ForgeSdk.remove_wallet(request)
Link to this function

retrieve_swap(itx, opts) View Source

Link to this function

revoke_tether(itx, opts) View Source

Link to this function

search(request, conn_name \\ "") View Source

Link to this function

send_tx(request, conn_name \\ "") View Source
send_tx(ForgeAbi.RequestSendTx.t() | Keyword.t(), String.t() | atom()) ::
  String.t() | {:error, term()}

Send tx.

Example

w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w1)
w2 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "bob"), wallet: w2)
data = Google.Protobuf.Any.new(type_url: "test_asset", value: "hello world")
itx = ForgeSdk.encode_any!(TransferTx.new(to: w2.address, value: new_unit(100)))
req = RequestCreateTx.new(itx: itx, from: w1.address, nonce: 2, walllet: w1, token: t)
tx = ForgeSdk.create_tx(req)
hash = ForgeSdk.send_tx(tx: tx)
Link to this function

stake_for_node(address, amount, opts) View Source

Link to this function

subscribe(request, conn_name \\ "", opts \\ []) View Source

Subscribe to a topic. You can event set a filter for the event that you'd listen.

Example

req = ForgeAbi.RequestSubscribe.new(topic: "fg:t:declare")
ForgeSdk.Rpc.subscribe(req)
Link to this function

token_to_unit(tokens, name \\ "") View Source

Link to this function

transfer(itx, opts) View Source
transfer(map(), Keyword.t()) :: String.t() | {:error, term()}

Transfer tokens or/and assets from one wallet to another.

Example

w1 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: w1)
w2 = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "bob"), wallet: w2)
data = Google.Protobuf.Any.new(type_url: "test_asset", value: "hello world")
itx = ForgeSdk.encode_any!(TransferTx.new(to: w2.address, value: new_unit(100)))
ForgeSdk.transfer(req, wallet: w1)
Link to this function

unit_to_token(units, name \\ "") View Source

Link to this function

unsubscribe(request, conn_name \\ "", opts \\ []) View Source
unsubscribe(ForgeAbi.RequestUnsubscribe.t(), String.t() | atom(), Keyword.t()) ::
  :ok | {:error, term()}

Terminate the subscription by the topic id.

Example

req = ForgeAbi.RequestSubscribe.new(topic: "fg:t:declare")
stream_declare = ForgeSdk.Rpc.subscribe(req)
[topic: topic] = Enum.take(stream_declare, 1)
req = ForgeAbi.RequestUnsubscribe.new(topic: topic)
ForgeSdk.Rpc.unsubscribe(req)
Link to this function

update_asset(itx, opts) View Source
update_asset(map(), Keyword.t()) :: String.t() | {:error, term()}

Update an existing asset.

Example

wallet = ForgeSdk.create_wallet()
ForgeSdk.declare(ForgeAbi.DeclareTx.new(moniker: "alice"), wallet: wallet)
post = ForgeAbi.Post.new(title: "a new post", content: "hello world!")
itx = ForgeAbi.CreateAsset.new(itx: ForgeSdk.encode_any!(post))
hash = ForgeSdk.create_asset(itx, wallet: wallet)
address = ForgeSdk.get_address(hash)
new_post = ForgeAbi.Post.new(title: "a new post", content: "Yeah!")
itx = ForgeAbi.UpdateAssetTx.new(data: ForgeSdk.encode_any!(post), address: address)
ForgeSdk.get_asset_state(address: address)
Link to this function

update_type_url(forge_state) View Source

Link to this function

upgrade_node(itx, opts) View Source
upgrade_node(map(), Keyword.t()) :: String.t() | {:error, term()}

Upgrade the node to a new version at a given block height.

Example

itx = ForgeAbi.UpgradeNodeTx.new(version: "0.26.0", height: 12000)
ForgeSdk.upgrade_node(itx, wallet: wallet)
Link to this function

withdraw_tether(itx, opts) View Source