Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 473 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

Developer Documentation

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

AEX X

This is the suggested template for new AEXs.

Note that an AEX number will be assigned by an editor. When opening a pull request to submit your AEX, please use an abbreviated title in the filename,aex-draft_title_abbrev.md.

The title should be 44 characters or less.

Simple Summary

"If you can't explain it simply, you don't understand it well enough." Provide a simplified and layman-accessible explanation of the AEX.

Abstract

A short (~200 word) description of the technical issue being addressed.

Motivation

The motivation should clearly explain why existing specifications are inadequate to address the problem that the AEX solves. AEX submissions without sufficient motivation may be rejected outright.

Specification

The technical specification should describe the syntax and semantics of any new or changed feature. The specification should be detailed enough to allow competing, interoperable implementations.

Rationale

The rationale fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.

Backwards Compatibility

All AEXs that introduce backwards incompatibilities must include a section describing these incompatibilities and their severity. The AEX must explain how the author proposes to deal with these incompatibilities. AEX submissions without a sufficient backwards compatibility treatise may be rejected outright.

Implementation

The implementations, if applicable, must be completed before any AEX is given status "Last Call", and it needs be completed before the AEX is accepted. There is merit to the approach of reaching consensus on the specification and rationale before writing code, but the principle of "rough consensus and running code" is still useful when it comes to resolving many discussions of API details.

Copyright

Copyright and related rights go here if the License and License-Code fields don't cover the copyright requirements.

AEX: <to be assigned by editors>
Title: <AEX title>
Author: <a list of the author's or authors' name(s) and/or username(s), or name(s) and email(s), e.g. (use with the parentheses or triangular brackets): FirstName LastName (@GitHubUsername), FirstName LastName <[email protected]>, FirstName (@GitHubUsername) and GitHubUsername (@GitHubUsername)>
License: <license names, abbreviated>
License-Code (*optional): <license names, abbreviated>
Discussions-To: <URL>
Status: <Draft | Review | Last Call (yyyy-mm-dd to yyyy-mm-dd) | Final | Active | Updated | Superseded | Rejected | Withdrawn>
Type: <Interface | Informational | Meta>
Created: <date created on, in ISO 8601 (yyyy-mm-dd) format>
Requires (*optional): <AEX number(s)>
Replaces (*optional): <AEX number(s)>
Updates (*optional): <AEX number(s)>

Developer Documentation

Here you'll find a curated set of development resources spanning blockchain infrastructure, programming language support, cross-chain bridges, SDKs, and developer tooling. Whether you're a seasoned blockchain developer or just starting your journey with æternity, these tools are designed to streamline your development process and unlock the full potential of decentralized technology.

From our Sophia smart contract language support to JavaScript SDKs, middleware tools, and integration bridges, we provide a robust ecosystem that empowers developers to create cutting-edge blockchain applications with efficiency and ease.

Explore the sidebar to dive into specific tools and technologies, and start building with æternity today.

If you want to go back to other sections of the Documentation Hub, click one of the links below or click on "Documentation Hub" in the upper left corner at the top of the sidebar.

PULL_REQUEST_TEMPLATE

When opening a pull request to submit a new AEX, please use the suggested template:

https://github.com/aeternity/AEXs/blob/master/aex-X.md

Documentation Hub

.github

docs

ISSUE_TEMPLATE

Aeternity Expansions

The Aeternity Expansions (AEX), or aexpansions, are standards proposed by the community at large, i.e. everyone. Some of them can be mandatory in a specific context, e.g. AEX-1 describes the set of rules governing this repository, but are restricted to the application layer.

Quick Aexpansions filter

  • Recently updated

For open Aexpansions

Goals

The purpose of this repository is to provide a high quality and accessible set of specifications; ideally together with implementations ready to be used if applicable.

Contributing

If you want to contribute please follow these steps:

  1. Read

  2. Fork this repository

  3. Add your proposal to your fork, using the template provided

  4. Submit a pull request to the AEX repository

Each proposal should go into the AEXS directory. If you need to embed images or other assets add a subdirectory in the assets directory with the number of your proposal once assigned, e.g. assets/aex-1/image.png.

Everything beyond step 4 is governed by .

Status terms

Read for more details.

  • Draft - an AEX that is open for consideration and is undergoing rapid iteration and changes.

  • Review - an AEX that is done with its initial iteration and in review by a wide audience.

  • Last Call - In review by a wide audience - last call for accepting changes.

  • Final - an AEX that has been in Last Call for at least 2 weeks and all technical changes that were requested have been addressed by the author.

AEXs

Code
Status
Description

Copyright

This README is released under the license.

tutorials

.github

vuejs

guides

AEXS

cli

docs

ISSUE_TEMPLATE

feature_request

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

feature_request

Is your feature request related to a problem? Please describe. A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like A clear and concise description of what you want to happen.

Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.

Additional context Add any other context or screenshots about the feature request here.

.github

Active - proposal can be in constant flux. No unaddressed substantiated objections are left, crucial or cosmetic updates only.

  • Updated - signalling that an updating standard might have to be considered

  • Superseded - an AEX that is deprecated because other AEX supersedes it.

  • Rejected - editors deemed this proposal to be unworkable

  • Withdrawn - signalling that the proposal is no longer relevant.

  • Withdrawn

    Inter-Wallet Communication

    Withdrawn

    Data Serialization

    Draft

    Message Signing

    Review

    Fungible Token Standard

    Final

    Derivation path for deterministic wallets

    Draft

    æpps Meta Information Format

    Review

    Non-Fungible Token Standard

    AEX-1

    Active

    AEX process

    AEX-2

    Withdrawn

    Third-party Wallet Provider Support

    AEX-3

    Active

    Secret storage format

    AEX-4

    Withdrawn

    æternity wallet deep linking specification

    Help wanted
    Stage active
    Stage finalized
    All
    Most commented
    Least active
    AEX-1
    AEX-1
    AEX-1
    CC0-1.0

    aexpansion

    Discussions-To:

    Paste here the link to the topic on forum.aeternity.com

    Content URL

    Paste here the url where the content of the AEX can be found

    ATTENTION!

    If you would like to submit an AEX and it has already been written as a draft (see the for an example), please submit it as a .

    If you are considering a proposal but would like to get some feedback on the idea before submitting a draft, then continue opening an issue as a thread for discussion. Note that the more clearly and completely you state your idea the higher the quality of the feedback you are likely to receive.

    Keep in mind the following guidelines from :

    Each AEX must have a champion - someone who writes the AEX using the style and format described below, shepherds the discussions in the appropriate forums, and attempts to build community consensus around the idea. The AEX champion (a.k.a. Author) should first attempt to ascertain whether the idea is AEX- able. Posting to the the Protocol Discussion forum or opening an issue is the best way to go about this.

    Before you begin, vet your idea, this will save you time. Ask the Aeternity community first if an idea is original to avoid wasting time on something that will be be rejected based on prior research (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Aeternity is used. Examples of appropriate public forums to gauge interest around your AEX include the and the issues section of this repository. In particular, the issues section of this repository is an excellent place to discuss your proposal with the community and start creating more formalised language around your AEX.

    Once the champion has asked the Aeternity community as to whether an idea has any chance of acceptance, a draft AEX should be presented as a pull request. This gives the author a chance to flesh out the draft AEX to make properly formatted, of high quality, and to address initial concerns about the proposal.

    Aeternity snap for MetaMask

    This guide explains basic interactions on getting access to accounts on Aeternity snap for MetaMask using JS SDK.

    Prerequisite

    Run the code from below you need:

    • a MetaMask extension 12.2.4 or above installed in Chrome or Firefox browser;

    • to setup an account in MetaMask (create a new one or restore by mnemonic phrase).

    Usage

    Firstly, you need to create a factory of MetaMask accounts

    Using the factory, you can create instances of specific accounts by providing an index

    The private key for the account would be derived in the MetaMask browser extension using the provided index and the mnemonic phrase it was initialized with. The private key won't leave the extension.

    The complete examples of how to use it in browser can be found .

    Account persistence

    Account can be persisted and restored by saving values of index, address properties

    It can be used to remember accounts between app restarts.

    Account discovery

    In addition to the above, it is possible to get access to a sequence of accounts that already have been used on chain. It is needed, for example, to restore the previously used accounts in case the user connects MetaMask to an app that doesn't aware of them.

    Error handling

    If the user rejects an action (snap installation or connection, address retrieving or transaction/message signing) you will get an exception as a plain object with property code equals 4001, and message equals "User rejected the request.".

    If the snap downgrade is requested, the code will be -32602.

    Æternity <> Ethereum Bridge

    This application is created for interacting with the æternity <> EVM Bridge contracts provided by Acurast. Executing proper bridge actions using this application will result in moving the sent funds to the other chain.

    Getting started

    Before running the application, first project dependencies needs to be installed with the following command:

    Afterwards, to run the application locally in development mode, following command needs to be run at the project directory:

    Migration to 9.0.0

    This guide describes all breaking changes introduced with v9.0.0.

    drop waitMined static method

    If you used it like

    then you have to rewrite it using Stamp composition

    or pass it to specific methods, like

    or even

    Typed data hashing and signing

    Common structure

    The whole idea is heavily inspired by . To get a signature needed to calculate hash(hash(domain), hash(aci), hash(data)).

    hash function is blake2b.

    domain is a record containing not required properties:

    ISSUE_TEMPLATE

    Note: for support questions, please use the . This repository's issues are reserved for feature requests and bug reports.

    • Do you want to request a feature or report a bug?

    • What is the current behavior?

    • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem

    Sample æpp for contracts

    Overview

    This is a sample æpp that compiles contracts using the æternity JavaScript SDK.

    How it works

    Upcoming Version Support

    Aeproject can already be used for testing and setup with the upcoming node versions.

    Automatic update

    Use aeproject init --next to initialize a new project that has the necessary adjustments to use the latest versions.

    Use aeproject init --update --next to update an existing project with the adjustments to use the latest versions.

    bug_report

    Describe the bug A clear and concise description of what the bug is.

    To Reproduce Steps to reproduce the behavior:

    1. Go to '...'

    2. Click on '....'

    3. Scroll down to '....'

    Choose the wallet example from examples folder (the simplest is iframe-based wallet)

  • Start the wallet according to its readme

  • Start this æpp, which will start on port 9001

  • Connect this æpp to a choosed wallet according to its readme

  • Installation and running

    Prerequisite: refer SDK installation

    1. Install required dependencies with npm install

    2. Start the application npm run serve

    Manual update
    • change occurrences of utils.getSdk() to use utils.getSdk({ ignoreVersion: true }) if needed or use the same option for manually initialized sdk Node and CompilerHttp

    • update docker-compose.yml to use the latest node and compiler tags or specify it manually in running with aeproject env --nodeVersion latest --compilerVersion latest

    See error

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots If applicable, add screenshots to help explain your problem.

    Please tell us about your environment:

    • Node Version: v0.0.0

    • Protocol Version: 1

    • Compiler version: v0.0.0

    • VM Version: fate | fate2

    • SDK Version: v0.0.0

    • Python version: v3.7.0

    Other information (e.g. detailed explanation, stack traces, related issues, suggestions how to fix, links for us to have context, eg. forum, telegram, etc)

    template
    Pull Request
    AEX-1
    Aeternity forums
    AEX-5
    AEX-7
    AEX-8
    AEX-9
    AEX-10
    AEX-130
    AEX-141
  • What is the expected behavior?

  • What is the motivation / use case for changing the behavior?

  • Please tell us about your environment:

    • CLI Version: v0.0.0

    • Node Version: v0.0.0

    • NPM Version: v0.0.0

    • Protocol Version: 1

    • Compiler version: v0.0.0

  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. forum, telegram, etc)

  • forum

    .github

    ISSUE_TEMPLATE

    here

    Project Initialization

    aeproject init [folder]

    Optionally a folder can be specified for the project to be initialized in, otherwise the current directory is used.

    Creates a new project structure with a few folders in which the developer can create contracts and tests, as well as installing needed dependencies.

    Update existing project

    For upgrade from old AEproject versions check out Migration from 3.x.x to 4.x.x and Migration from 4.x.x to 5.x.x.

    aeproject init --update

    Updates the project structure and needed artifacts to the latest version, as well as installing needed dependencies.

    Upcoming Hard-fork initialization

    The additional parameter --next can be used to either initialize or update a project with changes for an upcoming hard-fork if available.

    Build and run the application

    This application doesn't contain any secrets and can be run by any machine with the following packages installed: node, npm, yarn

    Running locally

    After completing the Getting started successfully, following command will build the application and make it ready to be served either on a local machine or on a server:

    To serve the build, there is a need for an additional package called serve, can be installed via:

    with yarn:

    without yarn:

    Finally, to run the build:

    Running in a docker container

    Project has a Dockerfile in place. So, it can be easly run in a docker container with the following commands:

    build the container:

    and run:

    it should be served at localhost:3000

    Running on a cloud service

    If you want to run the bridge on free cloud service, following steps can be taken:

    1. Fork this repository

    2. Create an account for a cloud deployment service (Vercel, Netlify, AWS etc)

    3. Connect your GitHub account to your cloud platform selection

    4. Create a new app under your cloud service

    5. Configure your application using your forked repo with the standard node application deployment settings

    6. Deploy and self host your bridge application

    drop assertedType, use decode instead

    If you used it like

    then you have to rewrite it using decode method

    validator: recursive validator, simplify schema

    Instead of TransactionValidator stamp use verifyTransaction function. The function accepts a transaction, and a Node instance for validation (instead of network id), it doesn't return an unpacked transaction anymore, just an array of errors. Each error contains a verbose message (msg before), unique key (for easy comparison), checkedKeys array (txKey before). Usingnode instead of networkId allows to ensure transaction validation, so warnings are errors now (type field removed).

    SCHEMA doesn't contain validation schema anymore. This wasn't supposed to be used by external developers.

    simplify buildTxHash helper

    If you used buildHash like

    then use

    If you used it with a falsy raw then

    buildTxHash don't have raw switch anymore, it returns th_-encoded string in all cases, but it still accepts transactions as a string and as a buffer.

    enable verification in deep props instead of extra variable

    If you were passing verifyTx: false to sdk factory then use verify: false instead.

  • name as string,

  • version as integer,

  • networkId as string,

  • contractAddress as ct-encoded string.

  • aci is part of a complete contract ACI. It defines a type of data to sign. For example, the ACI

    corresponds to the data

    domain and data are fate-encoded before hashing. aci is prepared for hashing according to RFC8785.

    Implementation

    • AccountBase:signTypedData — calculates signature, supported in AccountMemory and in aepp-wallet connection;

    • hashTypedData — calculates the overall hash of typed data to sign;

    • hashJson — deterministic hashing of an arbitrary JS value, used to calculate hash(aci);

    • hashDomain — use for debugging or to prepare the hash value for smart contract.

    Examples

    • signing and verifying on aepp side

    • signing confirmation on wallet side

    • verifying a signature on contract side

    EIP-712
    import { AccountMetamaskFactory } from '@aeternity/aepp-sdk';
    
    const accountFactory = new AccountMetamaskFactory();
    const account = await accountFactory.initialize(0);
    console.log(account.address); // 'ak_2dA...'
    console.log(await account.signTransaction('tx_...')); // 'tx_...' (with signature added)
    import { AccountMetamask } from '@aeternity/aepp-sdk';
    
    const accountIndex = accountToPersist.index;
    const accountAddress = accountToPersist.address;
    
    const accountFactory = new AccountMetamaskFactory();
    const restoredAccount = new AccountMetamask(accountFactory.provider, accountIndex, accountAddress);
    import { Node } from '@aeternity/aepp-sdk';
    
    const node = new Node('https://testnet.aeternity.io');
    const accounts = await accountFactory.discover(node);
    console.log(accounts[0].address); // 'ak_2dA...'
    yarn
    yarn start
    yarn build
    yarn global add serve
    npm -g install serve
    serve -s build
    docker build -t aepp-bridge .
    docker run -d -p 3000:80 aepp-bridge
    const sdk = await Universal({ ... })
    sdk.waitMined(false)
    const sdk = await Universal.compose({
      deepProps: { Ae: { defaults: { waitMined: false } } }
    })({ ... })
    sdk.spend(amount, receiver, { waitMined: false });
    const sdk = await Universal({ ... })
    sdk.deepProps({ Ae: { defaults: { waitMined: false } } })
    const payload = Crypto.decodeBase64Check(Crypto.assertedType('tx_...', 'tx'));
    const payload = TxBuilderHelper.decode('tx_...', 'tx');
    const hash = TxBuilderHelper.buildHash('xx', Buffer.from([1, 2, 3]), { raw: true });
    const hash = Crypto.hash(Buffer.from([1, 2, 3]));
    const hash = TxBuilderHelper.encode(Crypto.hash(Buffer.from([1, 2, 3])), 'xx');
    {
      "record": [
        { "name": "foo", "type": "string" },
        { "name": "bar", "type": "int" }
      ]
    }
    { "foo": "test", "bar": 42 }

    AEX-4

    Simple Summary

    The document describes and defines the deep linking specification that every æternity supported wallet can implement and follow to redirect users to a specific activity or page inside the application.

    Motivation

    URI based deep linking enables websites or applications to interact with native applications registered to listen for aeternity URI scheme and trigger wallet actions like open wallet accounts directly from third-party applications.

    This also enables users to sign transaction using desktop or mobile based wallets without the need to copy or remember long addresses. This is especially beneficial for mobile wallet users as they can simply click on the wallet deep link to open the wallet app from the vendor app, confirm the transaction and return back to the vendor app through the callback url.

    Specification

    URI Scheme

    • ae:

    • aeternity:

    Methods

    1. View/Open Account in the wallet

      URI: aeternity:<wallet_address>

      Associated wallet app will:

      1. Open the wallet app

      2. Check if the address exists or not

    Reference

    • https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki

    • https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki

    • https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki

    • https://hackmd.io/s/BJObJntjQ

    Compatibility Table

    This package is expected to work in these environments:

    Environment
    Comment

    nodejs>=18.19

    Browser using script tag, umd

    webpack@4

    requires a fix to work with mjs build

    webpack@5

    @vue/cli@4 (webpack@4)

    Low vs High level API

    Interactions

    AeSdk is a general, high-level interface that wraps multiple low-level interfaces. A general interface is preferred for its simplicity and resilience to breaking changes.

    But there is also low-level interfaces. It's excellent for additional control, and as a teaching tool to understand the underlying operations. Most real-world requirements involves a series of low-level operations, so the SDK provides abstractions for these.

    Node API

    The aeternity node exposes . This API is described in the . SDK uses this document to generate a TypeScript client. The result client (implemented in ) a basically a mapping of all node endpoints as functions.

    So to get a transaction based on its hash you would invoke node.getTransactionByHash('th_fWEsg152BNYcrqA9jDh9VVpacYojCUb1yu45zUnqhmQ3dAAC6'). In this way the SDK is simply a mapping of the raw API calls into JavaScript.

    Transaction builder

    Any blockchain state change requires signing a transaction. Transaction should be built according to the . SDK implements it in , , and . requires fewer arguments than , but it expects the node instance provided in arguments.

    High-level SDK usage (preferable)

    Example spend call, using æternity's SDK abstraction:

    Low-level SDK usage

    The same spend execution, but using low-level SDK functions:

    Quick Start

    In this example we will send 1 AE coin from one account to another. For more specific information on setups with Frameworks and TypeScript, please refer to the installation instructions.

    1. Specify imports

    For the following snippets in the guide you need to specify multiple imports.

    2. Create a sender account

    3. Get some AE using the Faucet

    To receive some AE you can use the . Just paste sender's address, hit Top UP and you'll immediately get some test coins.

    4. Interact with the æternity blockchain

    This example shows:

    • how to create an instance of the SDK using the AeSdk class

    • how to spend (send) 1 AE from the account the SDK instance was initialized with to some other AE address

    Note:

    • You may remove code from Step 2 as this serves only for one-time creation

    • The spend function expects the amount to be spent in aettos (the smallest possible unit, 1 AE equal to 1 000 000 000 000 000 000 aettos)

    • See and track your transactions

    aex-10

    Simple Summary

    This aexpansion specify the derivation path used in the Aeternity blockchain for deterministic wallets

    Motivation

    The aexpansion is meant to avoid incompatibility with deterministic wallet implementations across the Aeternity landscape and to make it easy for the derivation path to be found.

    Specification

    Accounts derivation path is taken from , except that in all path segments hardened derivation is used since does not support public derivation.

    The derivation path (m/purpose'/coin_type'/account_index'/change'/address_index') is therefore:

    m/44H/457H/${account_index}H/0H/${address_index}H

    where account_index and address_index are integer starting from 0.

    The coin type value for Aeternity, 457, has been generated on random.org and is registered in .

    References

    iframe-based wallet

    Overview

    This is a sample wallet that expects an æpp to be loaded into its iframe.

    How it works

    1. Start this wallet, which will start on port 9000

    2. Start the , which will start on port 9001

    3. Visit to see the æpp included into this wallet

    Installation and running

    Prerequisite:

    1. Install required dependencies with npm install

    2. Start the application npm run serve

    Examples

    This folder contains examples of code samples that you can run autonomously. Create a new issue to suggest another example.

    Wallet connection

    Connect to a wallet

    • (VueJS)

    Build a wallet

    • (VueJS)

    NodeJS

    How to connect wallet to æpp using æternity's JS SDK

    Introduction

    In æternity ecosystem, the app that has access to user's private keys and grants other apps access to them is called wallet. Respectively, the app that is granted access is called aepp.

    This folder has been created to showcase the æternity SDK integration to both wallets and aepps.

    Setup info

    If you are trying these examples after checking out this repo, you want to first run npm install, from the repo root, to get all the SDK dependencies installed, and only then, move to individual apps installations.

    Available examples

    1. æpp

    The Sample project (Distributed App or dapp) shows how you can create a simple æternity æpp, dependent on a Wallet, in this case: offering the possibility to work with contracts.

    2. Wallet WebExtension

    The example project shows how you can create a simple æternity wallet as a Chrome/Firefox browser extension. This approach is actively used in.

    3. iframe-based wallet

    The example project shows how you can create a simple æternity wallet that opens æpps in iframe. This approach is actively used in .

    Migration to 7.0.0

    This guide describes the process of migrating to SDK version 7.0.0

    Step 1

    SDK will not accept url, internalUrl init arguments anymore:

    Before

    After

    Step 2

    Remove deprecated function setKeypair SDK will not accept keypair init argument anymore:

    Before

    After

    Step 3

    Change all of AENS method's first argument from nameId to name

    Before

    After

    Other Breaking Changes

    • Add new compiler methods to RPC communication (base-app update required)

    • Drop compiler version to version >= 4.0.0 && version < 5.0.0

    • Change node compatibility range to node >= 5.0.0 && node < 6.0.0

    WebExtension-based wallet

    Overview

    This is a sample wallet as an WebExtension. It works with æpp opened in a browser where it is installed.

    How it works

    1. Install this wallet to Chrome or Firefox

    2. Start the , which will start on port 9001

    3. Visit

    4. This wallet should attempt to connect to the æpp

    Installation and running in Google Chrome

    Prerequisite:

    1. Install required dependencies with npm install

    2. Start the build server in watch mode npm run serve

    3. Open

    4. Enable "Developer mode" at the right top conner

    Local Environment

    aeproject env

    The command is responsible for setting up a healthy local environment. The env command helps developers run a local node and a local compiler in dev-mode using docker. To spawn a fully functional environment it can take a couple of minutes depending on your system.

    If using Windows, WSL 2 needs to be used for AEproject to work normally, see https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-containers

    You can stop both the node and the compiler by running

    aeproject env --stop

    There are optional parameters --nodeVersion and --compilerVersion. To specify a specific version of node or compiler, or both

    This also applies to the commands aeproject node and aeproject compiler.

    To see whether you have running instances of the nodes along with a compiler you could run the following command

    Note: By default AEproject uses the latest-bundle tag of the official .

    Compatibility:

    • the sdk from @aeternity/aepp-sdk@14 >= v14.0.0 is compatible with NODE_TAG >= v7.1.0 and COMPILER_TAG >= v8.0.0

    • due to a bug in the devmode plugin, NODE_TAG = v7.1.0 is not compatible with aeproject

    Disclaimer

    • Firewalls and any other security feature can block your docker/docker-compose requests. Please check that docker/docker-compose is NOT in its blocked list or has permission to make requests.

    Contract Events

    The Sophia language also provides you the possibility to emit in your functions. On this page you will learn how to access and decode the event log of a specific transaction.

    EventEmitter contract

    This example contract that emits events will be used in the following examples:

    AEX-3

    Simple Summary

    The document describes and defines the secret storage approach used by æternity.

    Motivation

    The motivation for the AEX is to describe a standard way that is being used by æternity for secret storage.

    Migration from 3.x.x to 4.x.x

    Changes

    AEproject v4.0.0 underwent some bigger changes, is now available as official package of the æternity organization on NPM and is compatible to the recently published node .

    Install the new AEproject version

    The range of possible address length

    While base64-encoded strings have a constant length depending on the length of data to encode. In base58 it depends on the exact data to encode, e.g. it is shorter if encoded data have more leading zeroes.

    Building an aepp you may need to know the range of possible address lengths to validate an user-provided addresses (though better to use ) or for designs of address-related components. Doing manual tests you may conclude that account address length is between 52 and 53 chars, but it is not correct.

    Running the above code you would get something like { '51': 55, '52': 5021, '53': 4924 } depending on generated accounts. So, while the most of addresses have length between 52 and 53 chars, there is a ~0.55% chance to get an address of 51 chars.

    Theoretically there can be even shorter addresses if they lucky to be prefixed with a long sequence of 0.

    Running the above code you would get output like

    Therefore the minimum address length is 41 chars. All these addresses valid, for exampleak_11111111111111111111111111111111273Yts

    AeMdw Docker Setup Documentation

    Overview

    AeMdw is a middleware that acts as a caching and reporting layer for the . It responds to queries more efficiently than the node and supports additional queries.

    The middleware runs an Aeternity Node alongside it in the same Docker container and BEAM VM instance. This node can be configured using the aeternity.yaml file or by passing environment variables, just like configuring the node directly.

    Ledger Hardware Wallet

    This guide explains basic interactions on getting access to aeternity accounts on Ledger Hardware Wallet using JS SDK.

    Prerequisite

    Run the code from below you need:

    • a Ledger Hardware Wallet like Ledger Nano X, Ledger Nano S;

    How to build a wallet

    This guide shows how to build either an WebExtension Wallet or a iFrame-based Wallet.

    WebExtension wallet

    The full implementation of this example can be found here:

    Note:

    PayingForTx (Meta-Transactions)

    Introduction

    This guide explains you how to perform a PayingForTx (also known as meta-transaction) using the SDK.

    It is a very powerful and efficient solution that is crucial for onboarding new users into you ecosystem. By making use of the PayingForTx you will be able to cover the fees of your users.

    Unit Testing

    Run unit tests

    The test command helps developers run their unit tests for æternity projects. The command executes the tests scripts that are located in the test folder of your æternity project.

    Connect an æpp to a wallet

    This guide describes the 4 steps that are necessary to connect your application to a wallet using the RPC API.

    Prerequisites

    • Install for simplicity of example. You can build your own wallet in the next example

    bug_report

    Describe the bug A clear and concise description of what the bug is.

    To Reproduce Steps to reproduce the behavior:

    1. Go to '...'

    2. Click on '....'

    3. Scroll down to '....'

    Vue.js HelloWorld

    This tutorial shows you how to use the SDK in your Vue.js application. You will replace the content of the default HelloWorld component and display the current block height of the æternity testnet.

    1. Install Vue.js

    Migration from 4.x.x to 5.x.x

    AEproject v5.0.0 underwent some breaking changes.

    Install the latest AEproject version

    Various Changes

    • dropped commonjs support, newly created projects will be created as esm projects, old cjs projects will not continue to work with newer aeproject versions, to keep using old cjs projects,

    AEX: 4
    Title: æternity wallet deep linking specification
    Author: Shubhendu Shekhar (@shekhar-shubhendu), Andrea Giacobino (@noandrea)
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aex-4-aeternity-wallet-deep-linking-specification/3231
    Status: Withdrawn
    Type: Standards Track
    Created: 2019-04-03
    const { AeSdk, AccountMemory, Node } = require('@aeternity/aepp-sdk');
    AEX: 10
    Title: Derivation path for deterministic wallets
    Author: Andrea Giacobino (@noandrea), Denis Davidyuk (@davidyuk)
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aex-10-derivation-path-for-deterministic-wallets/3586
    License-Code: ISC
    Status: Final
    Type: Informational
    Created: 2019-03-04
    aeproject env --nodeVersion v7.2.0
    # or
    aeproject env --compilerVersion v8.0.0
    # or
    aeproject env --nodeVersion v7.2.0 --compilerVersion v8.0.0
    aeproject env --info

    If the account is found with the wallet, then the user is redirected to the account information page of the provided address.

  • If the account is not found then prompt the user with an account not found message.

  • Example

    aeternity:ak_2i2fioFMoEffBPeT3EBZEsxK1w579BuCgYE8WiMiADEQqUguU2

  • Payment

    URI: aeternity:<receiver_address>/<amount>/<vendor_identifier>?callback=<url>

    This URI scheme enables vendors to generate direct payment request URIs to user wallet.

    1. Vendor generates a address for receiving payment.

    2. Creates the URI substituting receiver_address with newly created address, amount with amount requested, vendor_identifier with a human readable identifier that can be used to correctly identify vendor and requested payment, and url with a callback URL that accepts a transaction id under txId query param.

    Example

    aeternity:ak_2gUJrd11cy65yqZ7mg1ULUG4kZ5r6v6vNqVtmA8HqUGKCf6kNf/125.12/myaeshop-ref9834?callback=https://myaeshop.com/verify

  • Sign and Broadcast

    URI: aeternity:<transaction>/<network_id>/<label>?return=<txId/tx>&callback=<url>

    This URI scheme enables users to sign (and broadcast) the transaction using deep linking enabled user wallet.

    1. The user generates the transaction to be signed

    2. Creates the URI substituting transaction and network_id with their respective value, label a human-readable text regarding the transaction and provides the query param return which indicates the return value type in the callback URL. It can contain only two possible values of string type:

      • txId: which indicates that the wallet needs to broadcast the transaction and return the transaction id

      • tx: means that the callback URL expects a signed transaction back.

    3. And at last, substitutes the query param url which contains a callback URL that accepts a transaction id under txId query param and signed transaction output under tx query param.

    Example

    aeternity:tx_+E0MAaEBK4bq9XiZ/0QVdOa8Hs9V18v6dGZYIa8XXNYFpQh6yq6hAR8To7CL8AFABmKmi2nYdfeAPOxMCGR/btXYTHiXvVCjCoJOIAADgFcJyZ8=/ae_uat/sample_tx?return=tx&callback=https://myaeshop.com/verify

  • How it works

    Typically somebody that you want to pay the transaction for (e.g. a new user of your decentralized aepp) signs the inner transaction (e.g. of type ContractCallTx) with a specific signature that is used for inner transactions.

    You can then collect the signed inner transaction, wrap it into a PayingForTx and broadcast it to the network.

    Usage examples

    We provided following two NodeJS examples which you can take a look at:

    • InnerTx: ContractCallTx

    • InnerTx: SpendTx

    Note:

    • A PayingForTx can wrap any kind of other transaction type supported by the protocol as inner transaction.

    UseCases

    • Game developers that want to quickly onboard new users.

    • Governance aepps that want people to vote on important proposals without having them to pay anything.

    • Custodians that want to offer an additional services to cover the transaction fees of their clients.

    • ... many more!

    See error

    Expected behavior A clear and concise description of what you expected to happen.

    Screenshots If applicable, add screenshots to help explain your problem.

    Please tell us about your environment:

    • Node Version: v0.0.0

    • Protocol Version: 1

    • Compiler version: v0.0.0

    • VM Version: fate | fate2

    • SDK Version: v0.0.0

    • Python version: v3.7.0

    Other information (e.g. detailed explanation, stack traces, related issues, suggestions how to fix, links for us to have context, eg. forum, telegram, etc)

    SLIP-0044: Registered coin types for BIP-0044
  • BIP32-Ed25519: Hierarchical Deterministic Keys over a Non-linear Keyspace

  • BIP-0044
    SLIP-0010
    SLIP-0044
    Deterministic wallets
    BIP-0032: Hierarchical Deterministic Wallets
    BIP-0044: Multi-Account Hierarchy for Deterministic Wallets
    SLIP-0010: Universal private key derivation from master private key
    sample contract æpp
    localhost:9000
    refer SDK installation
    Dry-run using debug endpoint
  • Oracle

  • æpp
    iframe-based Wallet
    Wallet WebExtension
    Contract interaction
    Transfer AE
    Paying for spend tx
    Paying for contract call tx
    æpp
    Wallet WebExtension
    Superhero Wallet
    wallet
    Base æpp

    Press "Load unpacked" button and choose the dist folder

    sample contract æpp
    localhost:9001
    refer SDK installation
    chrome://extensions
    docker images

    requires aliases to ESM versions of autorest deps vue-cli4

    @vue/cli@5 (webpack@5)

    vue@3

    AeSdk, Contract instances can't be reactive vue-3

    create-react-app@4 (webpack@4)

    mjs build is not compatible with webpack@4 cra-webpack-4

    create-react-app@5 (webpack@5)

    create-react-native-app@3 (webpack@4)

    mjs build is not compatible with webpack@4 cra-webpack-4

    meteor@2

    [email protected]

    requires an environment where Buffer is instanceof Uint8Array jest

    typescript>=4.8

    requires tsconfig.json adjustments typescript

    vite@3

    requires build.target: 'es2020' and bigint: true in vite.config.js vite

    webpack-4

    migration

    Faucet
    Testnet Explorer

    Always verify transactions before sending them to the node (can be disabled using the option verify: false)

    to collect AENS name fees.
    import { AccountMemory } from '@aeternity/aepp-sdk';
    
    const result = new Array(10000)
      .fill()
      .map(() => AccountMemory.generate().address.length)
      .reduce((p, n) => ({ ...p, [n]: (p[n] ?? 0) + 1 }), {});
    
    console.log(result);
    import { AccountMemory, Encoding, encode, decode } from '@aeternity/aepp-sdk';
    
    const publicKey = decode(AccountMemory.generate().address);
    
    for (let i = -1; i < publicKey.length; i += 1) {
      if (i >= 0) publicKey[i] = 0;
      const address = encode(publicKey, Encoding.AccountAddress);
      console.log(address.length, address);
    }
    isEncoded
    used
    @aeternity/aeproject@4
    will continue to work for now.
  • node@16 is no longer supported, please update to v18 or higher

  • updated to @aeternity/aepp-sdk@14 to the latest version, see the migration guide for additional reference.

    • the aeproject provided utils.getSdk({}) has to be adjusted to pass a reference to the sdk used utils.getSdk(AeppSdk, {}) where AeppSdk can be imported using import * as AeppSdk from "@aeternity/aepp-sdk";

    • @aeternity/aepp-sdk@14 requires aeternity node version >= 7.1.0

  • Removed from libs

    Following utils have been removed and cannot be used anymore:

    • utils.getFilesystem() discontinued, as it is now natively available in the sdk via import, e.g. const { getFileSystem } = require("@aeternity/aepp-sdk");

    Error Handling

    This guide shows you how to handle errors originating from the SDK. SDK by default exports the following error classes from file errors.ts

    Error Hierarchy

    Usage

    // import required error classes
    import {
      AeSdk,
      Node,
      AccountMemory,
      ArgumentError,
      InvalidAensNameError,
    } from '@aeternity/aepp-sdk';
    
    // setup
    const payerAccount = AccountMemory.generate();
    const newUserAccount = AccountMemory.generate();
    const node = new Node('https://testnet.aeternity.io');
    const aeSdk = new AeSdk({
      nodes: [{ name: 'testnet', instance: node }],
      accounts: [payerAccount, newUserAccount],
    });
    
    // catch exceptions
    try {
      const spendTxResult = await aeSdk.spend(-1, newUserAccount.address, { onAccount: payerAccount });
    } catch (err) {
      if (err instanceof ArgumentError) {
        console.log(`Amount specified is not valid, ${err.message}`);
      } else if (err instanceof InvalidAensNameError) {
        console.log(`Address specified is not valid, ${err.message}`);
      }
    }
    
    // using generic error classes
    import { AensError, TransactionError, BaseError } from '@aeternity/aepp-sdk';
    
    try {
      const spendTxResult = await aeSdk.spend(1, 'ak_2tv', { onAccount: payerAccount });
    } catch (err) {
      if (err instanceof AensError) {
        // address or AENS related errors
      } else if (err instanceof TransactionError) {
        // transaction errors
      } else if (err instanceof BaseError) {
        // match any errors from the SDK
      }
    }
    Decode events using ACI

    When initializing a contract instance using the source code and providing the ACI or obtaining it via http compiler (default) you will be able to access the emitEvents entrypoint of the Sophia contract above as follows:

    Note:

    • As you can see the event log will be automatically decoded in case you perform a ContractCallTx directly

    Of course it is also possible to decode the event log if you request the transaction details from the node for a transaction that has been mined already. You can request the transaction details by providing the tx-hash and then decode the event log using the contract as follows:

    contract EventEmitter =
    
        datatype event =
            FirstEvent(int)
            | AnotherEvent(indexed address, string)
    
        entrypoint emitEvents(value: int, msg: string) =
            Chain.event(FirstEvent(value))
            Chain.event(AnotherEvent(Call.caller, msg))
    Events

    The secret storage specification, although is being currently used for secret-key storage, should not be limited to it and should be used as a standard way of storing secret text/plain text (esp. user related or user-owned) in an encrypted format.

    Having a standard way for encryption and storage of data enables

    • Interoperability, not only between æternity and æpps but also between the æpps.

    • Easy migration from an aeternity-supported wallet to another.

    Specification

    • The data should always be stored in a .json file.

    • Each file should have a minimum of 1 JSON object with the following required fields

      • secret_type specifies the type of the encrypted data.

      • (optional) secret_format specifies the format of the encrypted data, if not specified then a consumer should assume raw bytes

      • symmetric_alg specifies the algorithm used for symmetric encryption of the secret. This should be authenticated encryption and the only option is xsalsa20-poly1305 currently.

      • The ciphertext is the output of symmectric_alg , i.e. the output of libsodiums crypto_secretbox_easy, which is MAC + CIPHER with an upper-limit of 512 bytes.

      • cipher_params params used for successful decryption of the ciphertext

      • kdf specifies the methods used for key derivation.

      • kdf_params are the params used by the kdf

      • id is a Version 4 UUID

      • version currently 1. Defines the version of secret storage format.

    • Each JSON Object can also have an optional name field, which can be a human-readable name for the secret.

    Secret types

    Specifying an appropriate secret_type helps consumers to decide the proper way of handling the decrypted data without having to store additional metadata.

    The following secret_type values have been proposed:

    • ed25519-bip39-mnemonic

    • ed25519-slip0010-masterkey

    This list should be expanded with adoption.

    It is not advised to use this format as a store for arbitrary binary data.

    Example

    Reference

    • https://github.com/ethereum/wiki/wiki/Web3-Secret-Storage-Definition

    Quick Start with Docker Compose

    Step 1: Clone the Repository

    Step 2: Database Snapshot (Optional)

    1. Download a full backup from Aeternity Downloads.

    2. Create a data directory under the root repository directory and extract the backup using the following command:

      This will extract the mnesia and mdw.db folders to the data directory.

    Step 3: Start the Application

    Run the following command to start the application on the mainnet:

    To check if the application is running properly, visit the /status endpoint and ensure that node_height is higher than 600000.

    Running with Docker (Without Compose)

    Step 1: Create Directories and Set Permissions

    Create the necessary directories for data storage and logs:

    Ensure the directories have the correct permissions to allow the middleware to write to them:

    Step 2: Use a Database Snapshot (Optional)

    If you want to use a database snapshot:

    1. Download a full backup from Aeternity Downloads.

    2. Extract the backup to the data directory:

      This will place the mnesia and mdw.db folders under the data directory.

    Step 3: Run the Container

    Start the container with the following command:

    This command starts the middleware in a docker container. The middleware will be available at http://localhost:4000. Note that you can pass the -d flag to run the container in detached mode.

    Step 4: Check the Status

    To check if the middleware is running properly, visit the /status endpoint and ensure that node_height is higher than 0.

    Step 5: Managing the Container

    To check the logs, run the following command:

    To check the status of the container, run the following command:

    To stop the container, run the following command:

    To restart the container, run the following command:

    Customizing Configuration

    Edit the configuration file docker/aeternity.yaml to specify network settings:

    • ae_mainnet for mainnet

    • ae_uat for testnet

    • A custom network name if running your own network or a hyperchain

    You can also pass environment variables to configure the node, similar to standard Aeternity Node configuration.

    Refer to Aeternity Configuration Docs for more details.

    Additional Resources

    • Aeternity Node Configuration

    • Aeternity Hyperchain Configuration

    æternity blockchain

    to install Ledger Live;

  • to install [email protected] or above app from Ledger Live to HW;

  • to have Ledger HW connected to computer, unlocked, with aeternity app opened.

  • Usage

    To work with accounts on Ledger HW firstly you need to choose a transport implementation. Ledger HW can be connected through USB or Bluetooth using a specific NPM package.

    After creating a transport instance you need to create a factory of Ledger accounts

    Using the factory, you can create instances of specific accounts by providing an index

    The private key for the account would be derived on the Ledger device using the provided index and the mnemonic phrase it was initialized with. The private key won't leave the device.

    The complete examples of how to use it in nodejs and browser can be found here.

    Account verification

    To protect from MITM attacks is it recommended to ensure that the accessed account is the account actually available on Ledger. To do so, the app should show to user the address it have access to, the same as Ledger HW should show the address on its screen, and user should ensure that addresses the same. To trigger verification process you need to use getAddress method

    Account persistence

    Account can be persisted and restored by saving values of index, address properties

    It can be used to remember accounts between app restarts.

    Account discovery

    In addition to the above, it is possible to get access to a sequence of accounts that already have been used on chain. It is needed, for example, to restore the previously used accounts in case the user connects Ledger HW to an app that doesn't aware of them.

    Error handling

    If the user rejects a transaction/message signing or address confirmation you will get an exception inherited from TransportStatusError (exposed in '@ledgerhq/hw-transport' package). With the message "Ledger device: Condition of use not satisfied (denied by the user?) (0x6985)". Also, statusCode equals 0x6985, and statusText equals CONDITIONS_OF_USE_NOT_SATISFIED.

    Implement unit tests

    In the test/exampleTest.js file you can find an example for unit testing using AEproject.

    1. Dependencies

    Javascript testing framework used with mocha for assertions, documented at https://www.chaijs.com/api/assert/

    Helper and utilities for AEproject use, e.g. prefunded wallets, network definition and utility functions for SDK initialization and snapshotting.

    Read AEproject Library for a more detailed explanation about the usage of these imports.

    2. SDK and Snapshotting Setup

    Provide your initializations in mocha which need to be done once before all tests:

    Initialize the default SDK instance with provided utils:

    Get the filesystem definition for (custom) includes of the given contract:

    Read the contract source from the filesystem:

    Initialize the contract instance:

    Deploy the contract:

    Create a snapshot of the chain state once before all tests. This allows you to rollback to a clean state after each test if needed:

    Rollback to the previously created snapshot after each test for a clean state in the following tests:

    3. Example Test

    Use mocha for test setup and chai for assert. Then implement contract usage using the aeternity sdk as explained in the guide at https://github.com/aeternity/aepp-sdk-js/blob/develop/docs/guides/contracts.md#5-call-contract-entrypoints

    2. Create a new Vue.js project

    3. Switch to the folder of your Vue.js project

    4. Install the SDK

    5. Modify the HelloWorld component

    6. Run the application

    npm install -g @vue/cli
    const sender = AccountMemory.generate();
    console.log('Sender address:', sender.address);
    console.log('Sender secret key:', sender.secretKey);
    const NODE_URL = 'https://testnet.aeternity.io';
    // replace <SENDER_SECRET_KEY> with the generated secretKey from step 2
    const sender = new AccountMemory('<SENDER_SECRET_KEY>');
    
    (async function () {
      const node = new Node(NODE_URL);
      const aeSdk = new AeSdk({
        nodes: [{ name: 'testnet', instance: node }],
        accounts: [sender],
      });
    
      // spend one AE
      await aeSdk.spend(1e18, '<RECIPIENT_ADDRESS>');
      // replace <RECIPIENT_ADDRESS>, Ideally you use address from Superhero Wallet you have created before
    })();
    Universal({
      url,
      internalUrl,
    });
    const nodeInstance = await Node({ url, internalUrl });
    Universal({
      nodes: [{ name: 'testnet', instance: nodeInstance }],
    });
    Universal({ keypair });
    Universal({
      accounts: [MemoryAccount({ keypair })],
    });
    const client = Universal({ ... })
    
    await client.aensUpdate('cm_ad1wdsa...', ...)
    await client.aensTransfer('cm_ad1wdsa...', ...)
    await client.aensRevoke('cm_ad1wdsa...', ...)
    const client = Universal({ ... })
    
    await client.aensUpdate('testname.chain', ...)
    await client.aensTransfer('testname.chain', ...)
    await client.aensRevoke('testname.chain', ...)
    52 ak_XsSLpN161dHo77k82CZHDnUCDpVG1JSujZjbGYhNKTgMy5exZ
    52 ak_13P6GKgb4VcxJHrb5Vnhb66RNBGgdnFLVJS8RaLcrAeseZmuc
    52 ak_115z6Ns8nevqahWHQfYU3QNJbK7PsX2rWxoPQRcpvWzB4U77s
    51 ak_111dqrd5iRqVHQe2T2JdZe79bqNBVCkWPqSc1JAXMW6F2vvT
    50 ak_1111PM8Acd6qZCjioCqPt6PcTuWVxxS22gt2ytCdH82FY4C
    51 ak_111113q5w8zgNNjAgLbxrMmA8qBNCv8aVHBM7eLm7JbfcgVe
    50 ak_111111UGVF8HYKFC7hLzwffE8JR5vQKQ9z4BiYJYCVcEGna
    49 ak_1111111wnTfJ9TWagQmzk42ADoUqVg1VvNMG7t8Fo8SQGf
    50 ak_11111111389cwfh57Mw1d4uYXps2orpWxc9Zoov7PdW6G7S
    49 ak_111111111G6iURaQ8ycLUNERoocnfJPQ8J7bopyndikHFM
    49 ak_11111111116b9WMyCB85kS4YkDfP9D3LhqUu5eG7AEfrLg
    48 ak_11111111111urvTGsQm76A4yTbApC8DJ1rLggAFKXiZXp
    48 ak_1111111111119eSHeN26TTHqgKpcEVTmbCHEbQgAHJkjd
    48 ak_11111111111115QmcWAusFcLUq2MfYLXdxnFEhPkRrQu5
    47 ak_11111111111111c7Y1hucPEYuPH6ZY5sFdKo6dhb86gk
    47 ak_1111111111111116qaT3Ac44qzDFevr9Czj1S9p9Y46r
    47 ak_11111111111111114KqRXnNJJwVDnphudyDt4XDmjLn7
    46 ak_11111111111111111XGs41KwLTa74AMCwx3gYYAHv81
    46 ak_1111111111111111114sffTSqJvTbsAjsQykvVsDcV8
    45 ak_1111111111111111111wVeBwZE5g63oPLdnrQC7TuP
    45 ak_11111111111111111111Y4FSQ8pV3J8f96h3SS68Df
    45 ak_1111111111111111111114ZmkEyJVpPoE6bFrxSt3n
    44 ak_1111111111111111111111hEHXkLzkWadzEyFn6pw
    44 ak_11111111111111111111111A6y5vKi2SUtEiqyw1H
    44 ak_1111111111111111111111112PszJecmUrBA1wHbx
    43 ak_1111111111111111111111111yqJmD1ujq7rtGX6
    43 ak_111111111111111111111111113hoVWLS2aptDtG
    42 ak_111111111111111111111111111PhgEh1GA292t
    42 ak_1111111111111111111111111111Z6ci7mUpU7i
    42 ak_111111111111111111111111111119gETXQQAsT
    42 ak_11111111111111111111111111111136u6WXDf6
    41 ak_1111111111111111111111111111111PqPZYur
    41 ak_11111111111111111111111111111111273Yts
    npm install -g @aeternity/aeproject
    BaseError
    ├── ArgumentError
    ├── IllegalArgumentError
    ├── ArgumentCountMismatchError
    ├── InsufficientBalanceError
    ├── MissingParamError
    ├── NoSerializerFoundError
    ├── RequestTimedOutError
    ├── TxTimedOutError
    ├── TypeError
    ├── UnsupportedPlatformError
    ├── UnsupportedProtocolError
    ├── NotImplementedError
    ├── UnsupportedVersionError
    ├── LogicError
    │
    ├── InternalError
    │   └── UnexpectedTsError
    │
    ├── AccountError
    │   └── UnavailableAccountError
    │
    ├── AensError
    │   ├── AensPointerContextError
    │   ├── InsufficientNameFeeError
    │   └── InvalidAensNameError
    │
    ├── AeppError
    │   ├── InvalidRpcMessageError
    │   ├── MissingCallbackError
    │   ├── UnAuthorizedAccountError
    │   ├── UnknownRpcClientError
    │   └── UnsubscribedAccountError
    │
    ├── ChannelError
    │   ├── ChannelCallError
    │   ├── ChannelConnectionError
    │   ├── ChannelPingTimedOutError
    │   ├── UnexpectedChannelMessageError
    │   ├── ChannelIncomingMessageError
    │   └── UnknownChannelStateError
    │
    ├── CompilerError
    │   └── InvalidAuthDataError
    │
    ├── ContractError
    │   ├── BytecodeMismatchError
    │   ├── DuplicateContractError
    │   ├── InactiveContractError
    │   ├── InvalidMethodInvocationError
    │   ├── MissingContractAddressError
    │   ├── MissingContractDefError
    │   ├── MissingFunctionNameError
    │   ├── NodeInvocationError
    │   ├── NoSuchContractFunctionError
    │   ├── NotPayableFunctionError
    │   ├── MissingEventDefinitionError
    │   └── AmbiguousEventDefinitionError
    │
    ├── CryptographyError
    │   ├── InvalidChecksumError
    │   ├── MerkleTreeHashMismatchError
    │   ├── MissingNodeInTreeError
    │   ├── UnknownNodeLengthError
    │   └── UnknownPathNibbleError
    │
    ├── NodeError
    │   ├── DuplicateNodeError
    │   └── NodeNotFoundError
    │
    ├── TransactionError
    │   ├── DecodeError
    │   ├── PayloadLengthError
    │   ├── DryRunError
    │   ├── IllegalBidFeeError
    │   ├── InvalidSignatureError
    │   ├── InvalidTxError
    │   ├── PrefixNotFoundError
    │   ├── SchemaNotFoundError
    │   ├── TagNotFoundError
    │   └── TxNotInChainError
    │
    ├── WalletError
    │   ├── AlreadyConnectedError
    │   ├── NoWalletConnectedError
    │   └── RpcConnectionError
    │
    ├── RpcError
    │   ├── RpcInvalidTransactionError
    │   ├── RpcRejectedByUserError
    │   ├── RpcUnsupportedProtocolError
    │   ├── RpcConnectionDenyError
    │   ├── RpcNotAuthorizeError
    │   ├── RpcPermissionDenyError
    │   └── RpcInternalError
    // events emitted by contract calls are automatically decoded
    const tx = await contract.emitEvents(1337, 'this message is not indexed');
    console.log(tx.decodedEvents);
    
    /*
    [
      {
        name: 'AnotherEvent',
        args: [
          'fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk',
          'this message is not indexed'
        ],
        contract: {
          name: 'EventEmitter',
          address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh'
        }
      },
      {
        name: 'FirstEvent',
        args: [1337n],
        contract: {
          name: 'EventEmitter',
          address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh'
        }
      }
    ]
    */
    const txHash = 'th_2YV3AmAz2kXdTnQxXtR2uxQi3KuLS9wfvXyqKkQQ2Y6dE6RnET';
    // aeSdk is an instance of the AeSdk class
    const txInfo = await aeSdk.api.getTransactionInfoByHash(txHash);
    
    // decode events using contract instance
    const decodedUsingContract = contract.$decodeEvents(txInfo.callInfo.log);
    console.log(decodedUsingContract);
    
    /*
    [
      {
        name: 'AnotherEvent',
        args: [
          'fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk',
          'this message is not indexed'
        ],
        contract: {
          name: 'EventEmitter',
          address: 'ct_fKhQBiNQkDfoZcVF1ZzPzY7Lig6FnHDCLyFYBY33ZjfzGYPps'
        }
      },
      {
        name: 'FirstEvent',
        args: [1337n],
        contract: {
          name: 'EventEmitter',
          address: 'ct_fKhQBiNQkDfoZcVF1ZzPzY7Lig6FnHDCLyFYBY33ZjfzGYPps'
        }
      }
    ]
    */
    AEX: 3
    Title: Secret storage format
    Author: Sascha Hanse <[email protected]>, Shubhendu Shekhar (@shekhar-shubhendu)
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aex-3-secure-storage-format/3220
    Status: Active
    Type: Informational
    Created: 2019-04-03
    {
      "crypto": {
        "secret_type": "ed25519-slip0010-masterkey",
        "symmetric_alg": "xsalsa20-poly1305",
        "ciphertext":"66891af8a59e83f0c600435a0681413644588f296240ab922ee357fa5ffa857f2709f8753b2b70d35625203adc6bf6e8",
        "cipher_params": {
          "nonce": "b085597ac8351330b469e9845fc9fb8cefa07e51cb7736a"
        },
        "kdf": "argon2id",
        "kdf_params": {
          "memlimit_kib": 65536,
          "opslimit": 3,
          "salt": "somesaltyness",
          "parallelism": 1,
        }
      },
      "id": "b1ff1e48-4e3e-4caf-818e-c8a7c3559d97",
      "name": "main",
      "version": 1
    }
    tar -xvzf path-to-backup.tar.gz -C data
    tar -xvzf path-to-backup.tar.gz -C data
    git clone https://github.com/aeternity/ae_mdw && cd ae_mdw
    docker compose up
    mkdir -p data/mnesia data/mdw.db log
    chown -R 1000 data log
    docker run -it --name ae_mdw \
      -p 4000:4000 \
      -p 4001:4001 \
      -p 3113:3113 \
      -p 3013:3013 \
      -p 3014:3014 \
      -v ${PWD}/data/mnesia:/home/aeternity/node/data/mnesia \
      -v ${PWD}/data/mdw.db:/home/aeternity/node/data/mdw.db \
      -v ${PWD}/log:/home/aeternity/ae_mdw/log \
      -v ${PWD}/docker/aeternity.yaml:/home/aeternity/.aeternity/aeternity/aeternity.yaml \
      aeternity/ae_mdw:latest
    docker logs ae_mdw
    docker ps -a
    docker stop ae_mdw
    docker start ae_mdw
    import { AccountLedgerFactory } from '@aeternity/aepp-sdk';
    
    const accountFactory = new AccountLedgerFactory(transport);
    const account = await accountFactory.initialize(0);
    console.log(account.address); // 'ak_2dA...'
    console.log(await account.signTransaction('tx_...')); // 'tx_...' (with signature added)
    await accountFactory.getAddress(<account index>, true)
    import { AccountLedger } from '@aeternity/aepp-sdk';
    
    const accountIndex = accountToPersist.index;
    const accountAddress = accountToPersist.address;
    
    const restoredAccount = new AccountLedger(transport, accountIndex, accountAddress);
    import { Node } from '@aeternity/aepp-sdk';
    
    const node = new Node('https://testnet.aeternity.io');
    const accounts = await accountFactory.discover(node);
    console.log(accounts[0].address); // 'ak_2dA...'
    aeproject test
    import { assert } from "chai";
    import { before, describe, afterEach, it } from "mocha";
    import { utils } from "@aeternity/aeproject";
    import * as AeppSdk from "@aeternity/aepp-sdk";
    import { Contract, getFileSystem } from "@aeternity/aepp-sdk";
    before(async () => ...)
    aeSdk = utils.getSdk(AeppSdk, {});
    const fileSystem = await getFileSystem(EXAMPLE_CONTRACT_SOURCE);
    const sourceCode = utils.getContractContent(EXAMPLE_CONTRACT_SOURCE);
    contract = await Contract.initialize({ ...aeSdk.getContext(), sourceCode, fileSystem });
    await contract.init();
    await utils.createSnapshot(aeSdk);
    afterEach(async () => {
      await utils.rollbackSnapshot(aeSdk);
    });
    it("ExampleContract: set and get", async () => {
      const set = await contract.set(42, {
        onAccount: utils.getDefaultAccounts()[1],
      });
      assert.equal(set.decodedEvents[0].name, "SetXEvent");
      assert.equal(
        set.decodedEvents[0].args[0],
        utils.getDefaultAccounts()[1].address,
      );
      assert.equal(set.decodedEvents[0].args[1], 42);
    
      const { decodedResult } = await contract.get();
      assert.equal(decodedResult, 42);
    });
    vue create my-project
    cd my-project
    npm install @aeternity/aepp-sdk
    <!-- src/components/HelloWorld.vue -->
    
    <script>
    import { AeSdk, Node } from '@aeternity/aepp-sdk'
    
    export default {
      name: 'HelloWorld',
      data () {
        return {
          msg: 'Loading latest block ...'
        }
      },
      async mounted () {
        // Init required Node class
        const node = new Node('https://testnet.aeternity.io')
    
        // Init SDK instance with AeSdk class
        const aeSdk = new AeSdk({
           nodes: [{ name: 'test-net', instance: node }],
        })
        // Start using the SDK
        const height = await aeSdk.getHeight()
        this.msg = 'Current Block: ' + height
      }
    }
    </script>
    npm run serve
    Removed commands

    Following commands have been removed and cannot be used anymore. Most of them didn't work properly or aren't used by anyone:

    • aeproject compatibility (discontinued)

    • aeproject compile

      • manual compilation isn't needed for use of aeproject, alternatively use the CLI or the SDK programmatically

    • aeproject deploy

      • deployment isn't supported in aeproject anymore, alternatively use the or the programmatically

    • aeproject export (discontinued)

    • aeproject tx-inspector

      • manual tx inspection is moved to the

    Updated commands

    • aeproject init

      • added the folder argument to create a new folder for the project initialization

    Project structure

    The latest available node and compiler will always be used with starting the testing environment.

    Testing is now handled locally in the project using mocha and chai as direct dev dependencies.

    @aeternity/aeproject is added itself as dependency and includes some library-functions that can be used in testing.

    • networks includes network definitions for local development, testnet and mainnet

    • wallets includes example wallets that are prefunded in local development

    • utils includes helper functions for testing

      • getFilesystem(source) to get the filesystem definition for a given contract for deployment

      • getSdk() get an instance of the SDK for local development

        • initialized with all prefunded wallets for onAccount to be used calling from different accounts

      • awaitKeyBlocks(aeSdk, number) await a certain number of key-blocks

      • createSnapshot(aeSdk) create a snapshot for local testing

      • rollbackSnapshot(aeSdk) rollback to previously created snapshot in local testing

    Instructions

    1. Upgrade your project

      • adds new files needed

        • including new example contract and tests

      • prompts for files to replaced

        • docker setup for the node, compiler dev-mode setup should be accepted

        • example contract and example tests should not be accepted if used in your project for testing

      • automatically installs needed dependencies and removes unnecessary ones

    2. Adapt Testing Setup (compare your tests with test/exampleTest.js) to

      • include const { assert } = require('chai'); for assertions

      • replace NETWORKS import with const { networks } = require('@aeternity/aeproject'); for networks definition

    v6.4.0
  • If you want to see a more advanced implementation you can take a look into the repository of the Superhero Wallet

  • 1. Create bridge between extension and page

    First you need to create a bridge between your extension and the page. This can be done as follows:

    2. Initialize AeSdkWallet class

    Then you need to initialize AeSdkWallet class in your extension and subscribe for new runtime connections. After the connection is established you can share the wallet details with the application.

    iFrame-based Wallet

    The iFrame-based approach works similar to the WebExtension approach except that the connectionProxy in between isn't needed.

    You can take a look into the implementation of the following example to see how it works:

    • iFrame-based Wallet Example

    WebExtension Wallet Example
    1. Specify imports and constants

    2. Initialize the AeSdkAepp class

    3. Scan for wallets and connect to a wallet

    Alternatively, aepp can request wallet to share node url it connected to. If agreed, then aepp can connect to the wallet's node.

    It can be used to

    • improve responsiveness by connecting to the exact node that wallet uses;

    • allow to connect aepps to private/development networks without changing their configuration;

    • simplify configuration on aepp side.

    Note:

    • The steps above are snippets taken from the full implementation of the Simple æpp

    Superhero Wallet extension
    a REST API
    OpenAPI document
    Node class
    protocol
    buildTx
    buildTxAsync
    unpackTx
    buildTxAsync
    buildTx

    Batch Transactions

    Introduction

    In some cases, aepp developer may need to send a set of transactions at once. The SDK provides optimizations for this scenario but it also requires additional effort by the developer. This guide covers specific cases with suggestions on how to proceed with them to produce a sequence of requests in an efficient way.

    Multiple spend transactions

    Obviously, multiple spends may be done like:

    But this isn't the fastest approach, because on each iteration SDK would:

    • request the sender data (its type and nonce)

    • verify the transaction (including additional requests)

    • wait until the transaction is mined

    It can be avoided by making spends as:

    This way, SDK would make a single request to get info about the sender account and a transaction post request per each item in the spends array.

    Additionally, you may want to set gasPrice and fee to have predictable expenses. By default, SDK sets them based on the current network demand.

    Multiple spends via contract call

    If you need to transfer a fixed AE amount from the same account to more than 24 accounts, it is more efficient to do it via a smart contract.

    Let's define and deploy a contract

    after deployment this contract, it can be called as follows

    Pros of this approach:

    • less fees if more than 24 recipients;

    • faster to execute because it needs to mine fewer transactions.

    Cons:

    • the amount of recipients in one transaction limited by the maximum gas in a block (about 800 recipients);

    • harder to implement.

    Fees difference

    One spend tx takes approximately 0.0000167ae. The above contract deployment is 0.0000815ae. The base contract call price is 0.000182ae. Adding an address to the list costs about 0.0000058ae. So, it is more efficient to use a contract if you have more than 24 recipients. And more than 17 recipients if you use a pre-deployed contract.

    Recipients
    Fee savings for batch spending via contract

    Multiple contract static calls

    Basically, the dry-run endpoint of the node is used to run them. Doing requests one by one, like

    will make SDK create a new dry-run request for each static call. It may be not efficient because dry-run supports executing multiple transactions at a single request. It can be done by making all calls at once:

    With combine flag SDK would put all of them into a single dry-run request. Also, it is necessary to generate increasing nonces on the aepp side to avoid nonce-already-used errors.

    This approach has another limitation: by default, dry-run is limited by 6000000 gas. This is enough to execute only 32 plain contract calls. it can be avoided by:

    • increasing the default gas limit of restricted dry-run endpoint in node configuration

    • decreasing the gas limit of each static call

    • using a debug dry-run endpoint instead of the restricted one

    Hyperchain Bridge

    The Hyperchain Bridge enables seamless token transfers between the Aeternity blockchain and its Hyperchains. It ensures secure and efficient scalability and interoperability across these networks. By monitoring Aeternity networks, it indexes and stores bridge transactions, facilitating fast data retrieval for the user interface. Additionally, the application empowers users to integrate new Hyperchain networks, extending bridge capabilities to emerging networks.

    ⚠ Warning: The Hyperchain Bridge is a work in progress and is not production-ready. Use it with caution and be aware of the risk of losing funds.

    Getting Started

    Prerequisites

    1. Install Bun.js: The bridge application uses Bun.js as its JavaScript runtime. Install Bun.js on the machine that will run the application: .

    2. Setup Supabase: The bridge application relies on a PostgreSQL database hosted on the Supabase platform. The database should include the following tables: actions and networks. Use the SQL definitions below to create the tables:

      After setting up the database:

    Application Checklist

    Before running the application, ensure the following steps are completed:

    1. Add the required environment variables to a .env file:

    2. Update the network constants in src/constants/networks.ts with the deployed bridge contract addresses using the bridge operator account.

    3. Ensure the Hyperchain networks are added to the constants with valid attributes. By default, only Mainnet and Testnet networks are included. Additional chains can be specified in this file or added through the network identification flow.

    Running the Application

    1. Install Dependencies:

    2. Run the Development Build: Start the development build with hot module replacement:

    3. Run the Production Build: Start the production build:

    Debugging

    The application can be debugged using Visual Studio Code with the Bun for Visual Studio Code extension. After installing the extension, use the debug configurations in launch.json to debug the application.

    Architecture and Workflow

    Tech Stack

    The Hyperchain Bridge leverages the following technologies:

    • TypeScript: Ensures type safety and improves developer productivity.

    • Bun.js: A JavaScript runtime powering backend services for efficient handling of bridge transactions, data processing, and routing.

    • React: Provides a responsive and user-friendly interface.

    • Sophia: A functional smart contract language for secure and efficient contracts on the Aeternity blockchain.

    Components

    The project consists of the following key components:

    • Smart Contracts: Includes HyperchainBridge and AEX9 FungibleToken Sophia contracts for secure transactions, along with unit tests for critical functionality.

    • Deployment Scripts: Utility scripts for streamlined deployment of smart contracts.

    • Backend: Listens for new bridge transactions and stores them in a PostgreSQL database.

    • Frontend: Enables users to interact with the bridge contracts, perform bridge actions, view transaction history, and monitor ongoing transactions.

    Bridge Workflow

    The bridge workflow involves transferring tokens between Aeternity blockchains using the HyperchainBridge contract:

    1. A user initiates a bridge action by calling the enter_bridge function on the HyperchainBridge contract with the destination network, token, amount, and other parameters.

    2. After the entry transaction is confirmed, the user connects to the destination network specified in the call.

    3. The user retrieves the necessary parameters (e.g., signature, timestamp) from the bridge API backend.

    4. On the destination network, the user calls the

    Network Identification Workflow

    The application allows users to add new networks by providing details such as nodeURL and mdwURL. The workflow is as follows:

    1. Connect to a network not specified in the networks constants.

    2. Fill out the form with the required network details and submit.

    3. The application verifies the network's connectivity and provides feedback.

    4. Fund the bridge operator's account for contract deployment.

    AEX 8

    Simple Summary

    This document defines a standard how arbitrary messages or payload can be signed using an aeternity keypair.

    Motivation

    Message signing can be used in a wide variety of scenarios. Common use cases include:

    • Authentication / Login (Proving you are the owner of an address/pubkey)

    • Authorization (Giving a user priviliges based on the coins / tokens he owns)

    • Prove Data Integrity

    • Voting

    This technique has been around for a long time, but with the rise in crypto adoption it becomes more accessible to the average user.

    Specification

    Flow

    1. DApp / Website / Wallet prepares a signing request containing a message (challenge) and other parameters (see below)

    2. Signing request is sent to the Wallet / Signer containing the Private Key

    3. User can select an identity (= keypair)

    4. Message will be signed

    Encoding

    The signature should be encoded in hex: Buffer.from(signature).toString("hex");

    Message Signing Request

    Message Signing Response

    The response can contain an array of signatures and publicKeys, which allows a single message to be signed by multiple identities at once.

    Signing the message

    Verifying the signature

    Example

    Serialization and Transport Layer

    Serialization and Transport Layer are not part of this propaosal.

    The Serialization is being discussed as part of AEX-7 Data Serialization

    Security

    In order to prevent malicious DApps from sending a seeminly random message to be signed that actually contains data like a valid transaction, we should add a prefix to the message so this can't be exploited.

    https://github.com/ethereum/wiki/wiki/JSON-RPC#eth_sign

    Releases

    This document describes the requirements and the process of creating releases of aepp-sdk to npmjs.com.

    Prerequisites

    A user wanting to release a new version needs to be a member of the @aeternity organization on npmjs.com. An existing member with write access needs to invite them in order to achieve this. In addition, the user needs to activate any means of 2-factor authentication because the aepp-sdk package is set up to only accept new versions if a second factor for authentication is in use.

    As new releases should only happen from release branch merges to the master branch of the repository on GitHub followed by a signed tag push, the user also needs direct write access to on GitHub. Normally, this can be achieved by first adding them to the and then to the, which gives automatic write access.

    Branching Out

    As aepp-sdk follows the for development, the release process is modelled after that strategy accordingly, with a few additions.

    Branch out from develop to a dedicated release branch denoting the target version number, e.g. release/v2.3.4.

    Preparing a Pre-Release

    If Testnet is not yet targeting the latest Node version, but you're "ready to release", you can do a pre-release for the latest version, tagging the release as @next on npmjs.

    To do this, You can follow the steps listed below, while keeping the next portion in both CHANGELOG.md and package.json files.

    Preparing a Release

    On the release branch, remove the next portion of the version string in package.json.

    Execute npm run release to automatically

    • bump version number in package.json and package-lock.json (according to)

    • output changes to

    • commit package-lock.json and package.json and CHANGELOG.md

    Next, git diff the release, branch a release/vX.X.X (where vX.X.X is your latest release) against master and validate that all changes are covered in the changelog. You can find more instructions on how to maintain a CHANGELOG here:

    PR against master

    Create a pull request against master and have it peer reviewed thoroughly. As all changes should've been reviewed before when they were merged to develop, emphasize on security-related changes and small changes pushed to develop separately.

    Merging

    Once the integration build has successfully completed (with or without additional fixes), merge (without squash) the branch into master. This allows master to be comprised of release commits exclusively, so every commit on master corresponds to exactly one released (or at least, tagged) version of aepp-sdk, respectively.

    Build, Release and Tag

    Update the local working copy to a local tracking branch of master and update. Optionally, wait for the CI build to finish and execute a lastnpm run test locally.

    Important: Because npm publish will use the local files on disk for releasing, perform a full clean and build in order to release to npmjs.com!

    1. Cleanup - run git clean -ffdx to completely wipe out your workspace of files not in the repository. This might wipe out files you still need, so consider a separate clone of the project!

    2. Execute npm run prepublishOnly to generate Documentation for the API and the SDK codebase, optionally followed by npm pack and investigate the resulting tarball's contents. This tarball resembles what users will actually download from npmjs.com once the release is completed!

    3. Execute npm publish

    Important: If you are releasing a Pre-Release (AKA next), make sure to tag the release as next using the command npm publish --tag next.

    At this point, the release should already be in npmjs.com. The final step is to also tag the release on GitHub and push the tag, which requires direct write access.

    1. git tag vX.X.X

    2. git push tag vX.X.X

    Recommendation: Use signed tags using the -s option to increase community's trust in the project!

    Merging Back into develop

    At this point, it is important to synchronize develop with any changes that have happened after branching out to the release branch. Create a new branch called realign/vX.X.X from master (where vX.X.X is your latest release) and open a Pull Request towards develop and resolve conflicts, if needed.

    This concludes the release process and the development cycle.

    æternity's JavaScript SDK

    JavaScript SDK for the revolutionary æternity blockchain, targeting theæternity node implementation. The aepp-sdk is hosted on GitHub.

    Guides & Examples

    Introduction

    Usage guides:

    • (æternity naming system)

    There are also that you can directly use and play with.

    CLI - Command Line Interface

    To quickly test all of æternity's blockchain features from your terminal, you can install and use the by running:

    1. npm i -g @aeternity/aepp-cli to globally install the CLI

    2. aecli --help to get a list of possible commands

    Contributing

    For advanced use, to get a deeper understanding of the SDK or to contribute to its development, it is advised to read the section.

    Changelog

    We keep our up to date.

    Quick Start

    Requirements

    In order to have AEproject working you must have installed the following:

    Note: on windows WSL 2 must be used

    Install

    Init a project

    This will create the project scaffold with an example contract including tests as well as a sample deployment script inside the specified folder. If no folder is specified the artifacts will be initialized in the current directory.

    Further explained in .

    Running a local environment

    This will run a local æternity network in dev-mode (node, compiler and nginx-proxy).

    To stop an already spawned local environment use aeproject env --stop

    Further explained in .

    Testing

    This will run the tests located in ./test folder. Further explained in .

    Help

    Run this command to give you all possible commands of aeproject with help and info

    Version

    Running this command will give you the current installed aeproject version

    AEproject Library

    Installed automatically with each project initialized with aeproject init, otherwise can be installed using npm i @aeternity/aeproject.

    Available imports include helper definitions and utils using:

    const { utils, wallets, networks } = require("@aeternity/aeproject");

    Utils

    Read the contract source from given path, just a wrapper for fs.readFileSync using utf-8 encoding.

    Initialize the æternity SDK, pre-configured for optimal use in an AEproject project using æternity node devmode.

    Create and wait for n number of key-blocks with the æternity node devmode, checked using the passed aeSdk.

    Create a snapshot of the current chain state using the æternity node devmode, using the passed aeSdk.

    Rollback to the latest snapshot using the æternity node devmode, using the passed aeSdk.

    Rollback to the specified height using the æternity node devmode, using the passed aeSdk.

    Get the pre-funded default accounts as MemoryAccount, so they can be used natively using the aeSdk.

    Wallets

    List of configured keypairs that are pre-funded using the æternity node devmode as provided in AEproject.

    Networks

    Exposed URLs for commonly used nodeUrl and compilerUrl, per default local devmode and optionally hosted URLs for mainnet and testnet.

    AeMdw Hyperhain Setup Documentation

    Overview

    AeMdw is a middleware that acts as a caching and reporting layer for the . It responds to queries more efficiently than the node and supports additional queries.

    The middleware runs an Aeternity Node alongside it in the same Docker container and BEAM VM instance, so you don't need to run a standalone one. This node can be configured using the aeternity.yaml file or by passing environment variables, just like configuring the node directly.

    AEproject

    AEproject is an æternity framework which helps with setting up a project to develop and test . It provides commands to spin up a local environment as well as utilities for compiling and testing Sophia Smart Contracts. The initial scaffold provides an example contract & corresponding tests.

    Install

    JWT usage

    Generating JWT

    Use signJwt to generate a JWT signed by an account provided in arguments.

    Provide sub_jwk: undefined in payload to omit signer public key added by default. Do it to make JWT shorter.

    Or if you using a different way to encode a signer address.

    aeproject init --update
    npm install -g @aeternity/aeproject
    const { networks, utils, wallets } = require("@aeternity/aeproject");
    await this.aeSdk.connectToWallet(wallet.getConnection(), {
      connectNode: true,
      name: 'wallet-node',
      select: true,
    });
    AEX: 8
    Title: Message Signing
    Author: Andreas Gassmann (@AndreasGassmann), Alessandro De Carli (@dcale)
    License: BSD-3-Clause
    Discussions-To: TBD
    Status: Draft
    Type: Standards Track
    Created: 2019-05-13
    nodejs >= 18
    docker
    npm install -g @aeternity/aeproject
    utils.getContractContent(contractPath);
    import * as AeppSdk from "@aeternity/aepp-sdk";
    utils.getSdk(AeppSdk, {});
  • local testing network is now devmode instead of local

  • replace defaultWallets import with const { wallets } = require('@aeternity/aeproject'); for prefunded wallets

  • replace contractUtils import with const { utils } = require('@aeternity/aeproject'); for utils

    • consider using the new helpers for initializing an instance of the SDK and creating snapshots similar to test/exampleTest.js

  • CLI
    SDK
    CLI
    and follow the on-screen instructions
    the repository
    æternity organization
    sdk team
    git-flow strategy
    Semantic Versioning
    CHANGELOG.md
    https://keepachangelog.com

    1 000

    0.0107ae

    100 000

    1.07ae

    10 000 000

    107ae

    Obtain SUPABASE_URL and SUPABASE_ANON_KEY from the Supabase dashboard and add them to the .env file.
  • Disable Row Level Security (RLS) for these tables.

  • Add Bridge Operator Private Key: Add a trusted account's private key to the .env file under the BRIDGE_OWNER_PK variable. Note: Private keys must be in the old format (128 characters long, base64 string).

  • Add Networks: Add your Hyperchain networks to src/constants/networks.ts with the appropriate settings (leave bridge contract addresses empty and fill them once deploy step is done)

  • Deploy Bridge Contracts: Deploy the HyperchainBridge contracts for each network using deploy scripts:

    Note: Before running the deploy command, make sure corresponding network has been added to src/constants/networks.ts and BRIDGE_OWNER_PK environment variable is set.

  • Supabase: An open-source Firebase alternative for managing PostgreSQL databases.

  • Docker: Simplifies deployment and management by containerizing components for consistency across environments.

  • aepp-js-sdk: A JavaScript SDK for interacting with the Aeternity blockchain.

  • Aeternity Middleware: Indexes and provides access to blockchain data for efficient querying and retrieval.

  • exit_bridge
    function with the retrieved parameters.
  • The bridge contract verifies the request and completes the bridge action.

  • Complete the process by clicking the "Finish" button after funding the account.

    Bun.js Installation Guide

    User is either being redirected to the provided callback URL, or the signed message is displayed (eg. QR code)

    Initialization Documentation
    Environment Documentation
    Testing Documentation
    utils.awaitKeyBlocks(aeSdk, n);
    Step 1: Generating Configuration Files

    To properly configure your middleware for Aeternity Hyperchains, start by generating the necessary configuration files from init.hyperchains.ae.

    1. Access the Hyperchains Initialization Tool:

      • Visit init.hyperchains.ae in your web browser.

    2. Input Node Information and Generate the Configuration Files:

      • Click on the 'Get Started' button.

      • Follow the on-screen instructions to enter details about your Hyperchain node and select a pinning chain.

      • Download the init.yaml file.

      • Follow the 'Next Steps' to generate additional configuration files:

        • aeternity.yaml

        • ${NAME}_accounts.json

        • ${NAME}_contracts.json


    Step 2: Running the Docker Container

    Once you have the necessary configuration files, you can run the middleware using Docker:

    • Make sure you have enough account balance on the pinning chain for all of the accounts

    • The command assumes the configuration files are in the ${NAME}/nodeConfig directory in your current working directory, where ${NAME} is the name of your Hyperchain.

    • This command uses the middleware image, which differs from the node image.

    • You can pass the -d flag to run the container in detached mode.


    Step 3: Persisting Node and Middleware Databases (Optional but Recommended)

    To ensure data persistence across container restarts:

    1. Create the Data Directory (if it doesn’t already exist):

      • In your working directory, create a data folder to store the node and middleware databases:

    2. Run the Docker Container with Volumes:

    • -v ${PWD}/data/mnesia:/home/aeternity/node/data/mnesia: Persists the node database.

    • -v ${PWD}/data/mdw.db:/home/aeternity/node/data/mdw.db: Persists the middleware database.

    With this setup, the middleware will retain its state even after the container is stopped or restarted.

    You can also pass the -d flag to run the container in detached mode.

    Step 4: Accessing the Middleware

    Once the container is running, you can access the middleware at http://localhost:4000 and the node at http://localhost:3013.

    Managing the Container

    To check the logs, run the following command:

    To check the status of the container, run the following command:

    To stop the container, run the following command:

    To restart the container, run the following command:


    Node Configuration Options

    You can use the same configuration options available for the Aeternity node to further customize your setup. For more information on available options and how to modify the aeternity.yaml file, refer to the Aeternity node documentation.

    æternity blockchain
    Verifying JWT

    Let's assume we got a JWT as string. Firstly we need to ensure that it has the right format.

    After that we can pass JWT to other SDK's methods, for example to get JWT payload and signer address in case JWT has the signer public key included in "sub_jwk".

    unpackJwt will also check the JWT signature in this case.

    Alternatively, if "sub_jwk" is not included then we can provide signer address to unpackJwt.

    If we need to a get signer address based on JWT payload then we need to unpack it without checking the signature. Don't forget to check signature after that using verifyJwt.

    import { AccountMemory, signJwt } from '@aeternity/aepp-sdk';
    
    const account = AccountMemory.generate();
    const payload = { test: 'data' };
    const jwt = await signJwt(payload, account);
    const jwt = await signJwt({ test: 'data', sub_jwk: undefined }, account);
    for (const { address, amount } of spends) {
      await aeSdk.spend(amount, address);
    }
    const base = (await aeSdk.api.getAccountNextNonce(aeSdk.address)).nextNonce;
    await Promise.all(
      spends.map(({ amount, address }, idx) =>
        aeSdk.spend(amount, address, { nonce: base + idx, verify: false, waitMined: false }),
      ),
    );
    include "List.aes"
    
    contract MultipleSpends =
      payable stateful entrypoint spend(addresses : list(address), amount: int) =
        List.foreach(addresses, (address) => Chain.spend(address, amount))
    await contract.spend(addresses, amount, { amount: amount * addresses.length });
    const results = [];
    for (const d of data) {
      results.push(await contract.foo(d));
    }
    const base = (await aeSdk.api.getAccountNextNonce(aeSdk.address)).nextNonce;
    const results = await Promise.all(
      data.map((d, idx) => contract.foo(d, { nonce: base + idx, combine: true })),
    );
    bun deploy-bridge --network $NETWORK_ID
    # Bridge operator account's private key
    BRIDGE_OWNER_PK=
    
    # Bridge user account's private key (for testing purposes)
    BRIDGE_USER_PK=
    
    # Supabase URL and Anonymous key from the Supabase dashboard
    SUPABASE_URL=
    SUPABASE_ANON_KEY=
    bun install
    bun dev
    bun start
    
    const signingRequest = {
    	message: string // Message to be signed
    	publicKey?: string // OPTIONAL: allows wallet to pre-select signing identity
    	ttl?: string // OPTIONAL: Blockheight or timestamp to prevent replay attacks
    	origin?: string // OPTIONAL: eg. aeternity.com
    	callbackURL?: string // OPTIONAL: eg. https://aeternity.com/?signedMessage=
    }
    
    const signingResponse = {
    	message: string // Message to be signed
    	signature: string[] // Signature of the message
    	publicKey: string[] // allows wallet to pre-select signing identity
    	ttl?: string // Blockheight or timestamp to prevent replay attacks
    	origin?: string // OPTIONAL: eg. aeternity.com
    }
    // TODO: How do we fit TTL and hostname into the message?
    
    import * as sodium from "libsodium-wrappers";
    
    const signMessage = async (
      message: string,
      privateKey: Buffer
    ): Promise<string> => {
      await sodium.ready;
      const signature = sodium.crypto_sign_detached(
        sodium.from_string(message),
        privateKey
      );
      const hexSignature = Buffer.from(signature).toString("hex");
    
      return hexSignature;
    };
    import * as sodium from "libsodium-wrappers";
    
    const verifyMessage = async (
      message: string,
      hexSignature: string,
      publicKey: Buffer
    ): Promise<boolean> => {
      await sodium.ready;
      const signature = new Uint8Array(Buffer.from(hexSignature, "hex"));
      const isValidSignature = sodium.crypto_sign_verify_detached(
        signature,
        message,
        publicKey
      );
    
      return isValidSignature;
    };
    // risk monitor path sick coconut cube ecology brief table adapt evil oven
    
    const privateKey = Buffer.from(
      "7f192bc4b5d6e828b6aeed3958f791f2d4d0f69e9b34a164df41f0f325c48ceb7d29631b2cc36eb4931a2ebe8b0a1bd95a29825ec21430b9e472146c851d2cfd",
      "hex"
    );
    const publicKey = Buffer.from(
      "7d29631b2cc36eb4931a2ebe8b0a1bd95a29825ec21430b9e472146c851d2cfd",
      "hex"
    );
    const message = "This message will be signed.";
    
    const signature = await signMessage(message, publicKey);
    // e650110d48b42cf07f577b886f852b36945da4b175cb1629528b705799d1565799802c7fbb7d07685f8b22185db7ce5bd03f7e0e754b904b80b4fe4fda4f1802
    
    const isValidSignature = await verifyMessage(message, signature, publicKey);
    // true
    aeproject init [folder]
    aeproject env
    aeproject test
    aeproject help
    aeproject --version
    utils.createSnapshot(aeSdk);
    utils.rollbackSnapshot(aeSdk);
    utils.rollbackHeight(aeSdk, height);
    utils.getDefaultAccounts();
    mkdir -p ${PWD}/data
    docker run -it --name ae_mdw_${NAME} \
      -p 4000:4000 \
      -p 4001:4001 \
      -p 3113:3113 \
      -p 3013:3013 \
      -p 3014:3014 \
      -v ${PWD}/${NAME}/nodeConfig/aeternity.yaml:/home/aeternity/.aeternity/aeternity/aeternity.yaml \
      -v ${PWD}/${NAME}/nodeConfig/${NAME}_accounts.json:/home/aeternity/node/data/aecore/${NAME}_accounts.json \
      -v ${PWD}/${NAME}/nodeConfig/${NAME}_contracts.json:/home/aeternity/node/data/aecore/${NAME}_contracts.json \
      aeternity/ae_mdw
    docker run -it --name ae_mdw_${NAME} \
      -p 4000:4000 \
      -p 4001:4001 \
      -p 3113:3113 \
      -p 3013:3013 \
      -p 3014:3014 \
      -v ${PWD}/${NAME}/nodeConfig/aeternity.yaml:/home/aeternity/.aeternity/aeternity/aeternity.yaml \
      -v ${PWD}/${NAME}/nodeConfig/${NAME}_accounts.json:/home/aeternity/node/data/mnesia/${NAME}_accounts.json \
      -v ${PWD}/${NAME}/nodeConfig/${NAME}_contracts.json:/home/aeternity/node/data/mnesia/${NAME}_contracts.json \
      -v ${PWD}/data/mnesia:/home/aeternity/node/data/mnesia \
      -v ${PWD}/data/mdw.db:/home/aeternity/node/data/mdw.db \
      aeternity/ae_mdw
    docker logs ae_mdw_${NAME}
    docker ps -a
    docker stop ae_mdw_${NAME}
    docker start ae_mdw_${NAME}
    const payload = {
      test: 'data',
      sub_jwk: undefined,
      address: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E',
    };
    const jwt = await signJwt(payload, account);
    import { isJwt, ensureJwt } from '@aeternity/aepp-sdk';
    
    if (!isJwt(jwt)) throw new Error('Invalid JWT');
    // alternatively,
    ensureJwt(jwt);
    import { unpackJwt } from '@aeternity/aepp-sdk';
    
    const { payload, signer } = unpackJwt(jwt);
    console.log(payload); // { test: 'data', sub_jwk: { ... } }
    console.log(signer); // 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E'
    const knownSigner = 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E';
    const { payload, signer } = unpackJwt(jwt, knownSigner);
    console.log(payload); // { test: 'data' }
    console.log(signer); // 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E'
    import { verifyJwt } from '@aeternity/aepp-sdk';
    
    const { payload, signer } = unpackJwt(jwt);
    console.log(payload); // { address: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E' }
    console.log(signer); // undefined
    if (!verifyJwt(jwt, payload.address)) throw new Error('JWT signature is invalid');

    PayingForTx (Meta-Transactions)

  • Batch Transactions

  • Error Handling

  • Low vs High level API

  • Typed data hashing and signing

  • Usage with TypeScript

  • JWT usage

  • Transaction options

  • Range of possible address length

  • Wallet Interaction

    • Connect an æpp to a wallet

    • How to build a wallet

    • Ledger Hardware Wallet

  • Installation
    Quick Start
    AENS
    Contracts
    Contract Events
    Oracles
    examples
    API Reference
    CLI
    Contributing Guidelines
    Changelog
    Documentation
    • Quick Start

    • Project Initialization

    • Local Environment

    • Unit Testing

    Release Process

    1. merge the release please PR

      • as @aeternity/aeproject has a dependency on itself as library, the CI run before publishing to npm after merging might fail

    2. build locally and publish

      • checkout latest origin/main including the merged release please PR, ensure no local changes

      • publish to npm using npm publish (does automatically clean-build, may require login if not already)

    Sophia Smart Contracts

    AEX 11 Fungible Token Standard

    Abstract

    A short (~200 word) description of the technical issue being addressed.

    Motivation

    The following describes standard functions a token contract and contract working with specified token can implement to prevent accidentally sends of tokens to contracts and make token transactions behave like ether transactions. Moreover, where designing the tokens we looked carfully at compliance work and wanted to make it easier for integrating compliance workflow. With this respect token transactions contains data field to be used freely to pass additional information (eg: reference) from a holder or an operator.

    The goal is to make this specification useful with Native Tokens.

    Specification

    Interface

    The token contract MUST implement the above interface. The implementation MUST follow the specifications described below.

    Operators

    An operator is an address which is allowed to send and burn tokens on behalf of some holder.

    NOTE: A holder MAY have multiple operators at the same time.

    A default operator is an implicitly authorized operator for all holders. The rules below apply to default operators:

    • The token contract MUST define default operators at creation time. The default operators set MAY be empty.

    • The token contract MUST NOT add or remove default operators after contract instantiation.

    • AuthorizedOperator events MUST NOT be emitted when defining default operators.

    • A holder MUST be allowed to revoke a default operator (unless the holder is the default operator).

    The following rules apply to any operator:

    • An address MUST always be an operator for itself. Hence an address MUST NOT ever be revoked as its own operator.

    NOTE: A holder MAY authorize an already authorized operator. An AuthorizedOperator MUST be emitted each time.

    NOTE: A holder MAY revoke an already revoked operator. A RevokedOperator MUST be emitted each time.

    Functional Specification

    General Notes

    meta() : meta_inf

    Returns information about token as a meta_inf record.

    total_supply() : int

    Returns: Total supply of tokens currently in circulation.

    • NOTE: MUST be equal to the sum of the balances of all addresses—as returned by the balance_of function.

    • NOTE: MUST be equal to the sum of all the minted tokens as defined in all the Minted events minus the sum of all the burned tokens as defined in all the Burned events.

    balance_of(holder: address) : option(int)

    Get the balance of the holder account. If the account is not registered (didn't use any token) then it MUST return None. Oherwise it MUST return non negative integer.

    default_operators() : list(address)

    List of addresses of all the default operators.

    is_operator_for(operator: address, holder: address) : bool

    MUST return true if the operator address is an operator for the holder. Otherwise MUST return false.

    authorize_operator(operator: address)

    Set a third party operator address as an operator of Call.caller to transfer and burn tokens on its behalf.

    NOTE: The holder (Call.caller) is always an operator for itself. This right SHALL NOT be revoked.

    revoke_operator(operator: address)

    Remove the right of the operator address to be an operator for Call.caller and to send and burn tokens on its behalf.

    NOTE: The holder (Call.caller) is always an operator for itself. This right SHALL NOT be revoked.

    transfer(to: address, amount: int, data: string)

    Send the amount of tokens from the Call.caller (holder) to the to address. data an information provided by the holder.

    In the Transfer event, the operator and the holder MUST both be Call.caller.

    op_transfer(from: address, to: address, amount: int, data: string, op_data: string)

    Send the amount of tokens on behalf of the from address to the to address.

    Reminder: If the operator address (Call.caller) is not an authorized operator of the from address, then the send process MUST abort.

    burn(amount: int, data: string)

    Burn the amount of tokens from the Call.caller address.

    In the Burned event, the operator and the holder MUST both be Call.caller.

    op_burn(from: address, amount: int, data: string, op_data: string)

    Burn the amount of tokens on behalf of the from address.

    Reminder: If the operator address (Call.caller) is not an authorized operator of the from address, then the burn process MUST abort.

    AuthorizedOperator event

    Indicates the authorization of operator as an _operator for holder. The token contract MUST emit an AuthorizedOperator event with the correct values when a holder authorizes an address as its operator (even if it's already authorized or it's defined as a default oprator).

    RevokeOperator event

    Indicates the revokation of operator as an _operator for holder. The token contract MUST emit an RevokeOperator event with the correct values when a holder revokes an address as its operator (even if it's already revoked or it's defined as a default oprator).

    Hooks

    tokensToTransfer hook

    The tokensToSend hook notifies of any request to decrement the balance (transfer and burn) for a given holder. Any address (regular or contract) wishing to be notified of token debits from their address MAY register for receiving this hooks

    Interface:

    Notify a request to transfer or burn (if to is 0x0) an amount tokens from the from address to the to address by the operator address. The holder MAY block a send or burn process by aborting. (I.e., reject the withdrawal of tokens from its account.)

    • to MUST be 0x0 for a burn.

    • amount MUST be the number of tokens the holder sent or burned. MUST be non negative integer (0 is possible).

    • data MUST contain the extra information (if any) provided to the send or the burn process.

    NOTE: A regular address MAY register a different address—the address of a contract—implementing the interface on its behalf. A contract MAY register either its address or the address of another contract but said address MUST implement the interface on its behalf.

    TODO

    tokensReceived hook

    The tokensToSend hook notifies of any request to increment the balance (transfer and mint) for a given holder. Any address (regular or contract) wishing to be notified of token credits from their address MAY register for receiving this hooks

    Interface:

    Notify a send or mint (if from is 0x0) of amount tokens from the from address to the to address by the operator address.

    TOOD

    Backwards Compatibility

    This token provides a foundation for compliance tokens. Because of the need for refence field (data), and introduction of operators (often required in the industry and interoperability with other smart contracts), the interface is not backward compatible with proposed AEX-9 simple token standard.

    Implementation

    TODO

    Further consideration

    • register token interfaces Probably we don't need it because Sophia is strong static typed language.

    Transaction options

    For every transaction it is possible to provide an options object with one or multiple of the following attributes to the respective function that builds and broadcasts the transaction. Some of these are common and can be provided for each transaction type. Others are transaction specific and only relevant for a specific tx-type.

    The options object can be optionally passed to the respective function behind the last parameter, example:

    Note:

    • Without the options object the sender would be some other account selected in the instance of AeSdk and the recipient would receive 1 aetto instead of 1 AE.

    Common options

    These options are common and can be provided to every tx-type:

    • onAccount (default: the first account defined in the account array of the SDK instance)

      • You can specify the account that should be used to sign a transaction.

      • Note:

    Tx-type specific options

    The following options are sepcific for each tx-type.

    ContractCreateTx & ContractCallTx

    • amount (default: 0)

      • To be used for providing aettos (or AE with respective denomination) to a contract related transaction.

    • denomination

    NameClaimTx

    • nameFee (default: calculated based on the length of the name)

      • The fee in aettos that will be payed to claim the name.

      • For bids in an auction you need to explicitely calculate the required nameFee based on the last bid

    NameUpdateTx

    • clientTtl (default: 3600, one hour)

      • This option is an indicator for indexing tools to know how long (in seconds) they could or should cache the name information.

    • nameTtl (default: 180000)

    OracleRegisterTx

    • queryFee (default: 0)

      • The fee in aettos that the oracle requests in order to provide a response.

    • oracleTtlValue (default: 500

    OracleQueryTx

    • queryFee (default: 0)

      • The fee in aettos that will be payed to the oracle.

    • queryTtlValue (default: 10

    SpendTx

    • denomination (default: aettos)

      • You can specify the denomination of the amount that will be provided to the contract related transaction.

    How to estimate gas?

    • As æpp developer, it is reasonable to estimate the gas consumption for a contract call using the dry-run feature of the node once and provide a specific offset (e.g. multiplied by 1.5 or 2) as default in the æpp to ensure that contract calls are mined. Depending on the logic of the contract the gas consumption of a specific contract call can vary and therefore you should monitor the gas consumption and increase the default for the respective contract call accordingly over time.

    • By default, SDK estimates gasLimit using dry-run endpoint. This means an extra request that makes contract iterations slower, but it is more developer friendly (support of heavy requests without adjustments, and verbose error messages).

    AEX 7

    WITHDRAWN

    This proposal has been withdrawn because of overlap with AEX-2. A new AEX will be created at a later stage that is compatible with AEX-2 and focuses on the transport layer only.

    Simple Summary

    This document defines a serialization standard to facilitate data transfer between DApps, Wallets and devices.

    Motivation

    Data needs to be transferred between different apps and devices. Those apps may or may not be located on the same device. The transport layer used by those apps is unknown and will not be part of this AEX. However, since many of the transport layers can only transfer a limited amount of data (eg. QR codes, Bluetooth, NFC, URLs), the data should always be encoded in a standardized and space efficient way.

    The data serialization protocol in this AEX aims to provide a solution with the following goals in mind:

    • Easy understand and implement

    • Space efficient

    • Make sure to not transmit redundant information, send only what is necessary

    • Allow airgapped Apps such as AirGap Vault to properly display all necessary information when signing a transaction

    Specification

    Serialization - RLP

    Basic description of .

    We use RLP for the following reasons:

    • RLP is being used throughout the crypto space, with Aeternity adapting RLP as well after Ethereum

    • It is able to serialize and deserialize data in a predictable way

    • Easy to understand and implement

    • Encoded Data as Binary, size-efficient

    Encoding

    The resulting string will be encoded with base58 because it is URL-safe, which is important for some transport layers.

    Transport Layers

    The different transport layers are not part of this AEX, but we should keep the following transport layers in mind:

    • QR Codes

    • Deeplinking / URLs

    • Clipboard copy/paste

    • Push Notifications

    Example

    This example would result in the following, base58 encoded, string:

    The payload can be another RLP array, depending on the MessageType.

    Paging / Chunks

    While the transport layer is not part of this AEX, we have to think about how we can split up a request if it doesn't fit into one "packet", depending on the transport layer.

    The protocol should offer a "chunking" functionality where the user can pass a maximum size per chunk.

    Message Types

    This standard allows for new message types to be added by every application. But ideally, we should provide a set of commonly used types so they can be re-used between different apps. Some of the default types could be:

    • MetadataRequest (Information about the app, like name, version, url)

    • MetadataResponse

    • AccountShareRequest

    • AccountShareResponse

    The numbers 0 to 999 of the message type are reserved for official/default messages, other numbers can be used for user defined types (for which they have to provide their own serialization / deserialization methods.)

    Versioning

    There are 2 different kinds of versions:

    • Protocol Version: Defines the version of the sync protocol. If this does not match, then the request most likely cannot be processed.

    • Message Version: This version is specific to a currency and message type. This allows us to add additional functionality (new message types), without breaking existing (unchanged) message types.

    Looking at the MessageVersion, MessageType and ProtcolIdentifier together, we can determine if we can handle that specific request or not.

    Rationale

    We use RLP over more commonly used standards like JSON or XML because it's more space efficient.

    We encode the resulting string with base58 so it will be compatible with URLs.

    Adding context to a request

    In some situations it makes sense to include context to a request, which is then also sent back with the response.

    This could for example be used to attach IDs to requests to track their state.

    The context should be used with caution because:

    1. It will increase the size of both the request and response QR.

    2. You cannot be sure that the response is received on the same device that created the original request. (eg. prepare in chrome extension > signing on offline device > broadcasting with mobile phone)

    This context will be added as an optional parameter to all the default message types.

    Implementation

    There is currently one working implementation inside the , which uses this scheme to facilitate communication between online and offline devices.

    Oracles

    Introduction

    This guide shows you how to perform all the operations that you need within the lifecycle of oracles 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.

    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 .

    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.

    Note:

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

    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.

    Poll for response (alternative)

    Now you have query ID that can be used to poll for the 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:

    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:

    Respond to query (alternative)

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

    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:

    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

    • 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

    Development

    Principles

    The Javascript SDK wraps the æternity API exposed byNode's Swagger file. It aims to abstract the API, while still providing low-level access to it's endpoints, when necessary.

    It uses the following Javascript technologies and principles:

    • JavaScript the Good Parts (because Crockford is always right)

    • , using export and import

    • using ES7 syntax, where applicable

    • Statelessness wherever possible

    • and the

    • Loose coupling of modules to enable

    • Convention over configuration

    • "Easy things should be easy, and hard things should be possible." --

    • Support for

      • module access, enabling tree-shaking

      • direct use in node scripts through bundling

      • direct use in browser <script> tags through bundling

    Requirements

    aepp-sdk is transpiled to EcmaScript 5 through , using and is expected to work in any sufficiently new version of or modern web browser.

    Contributing

    1. Clone the application

    2. Make sure your editor/IDE can read and use the .editorconfig file

    3. Start hacking (and don't forget to add for whatever you'll be building).

    Documenting

    Apart from documenting features and code, there is also documentation automatically generated using for documenting TS files and for documenting examples and code partials.

    Building

    aepp-sdk is built using npm. In order to build a production version, launch the build command.

    Note: If you experience errors during the building, you might need to install build tools for your OS.

    Windows: Windows Build Tools

    Ubuntu / Debian: Build Essential

    Mac

    Download from AppStore, then run

    Generate bundle report

    Testing

    To test, launch the test command. This will run 's tests locally.

    This repository also includes a docker-compose file, to allow you to run your own æternity node locally. If you want to do so, from the root of the project:

    1. Run docker-compose up node

    2. Congrats! you're now running your own æternity node locally.

    The WebPack compilation provides two different build artifacts in dist/, one for Node.js and one for browsers. When referencing aepp-sdk through any modern build tooling, it should pick the right one automatically through the entry points defined in package.json.

    Installation / Linking

    In order to add a local development version of aepp-sdk to a project, npm link can be used.

    Releasing

    Installation

    Direct <script> include via CDN

    In case you're not using any JS bundling/compilation technique, the SDK can also be loaded with the traditional <script> tag, as follows:

    Latest SDK version

    Specific SDK version

    ...where VERSION is the version number of the SDK you want to use (eg. 14.1.0).

    Browser <script> tag

    The bundle will assign the SDK to a global variable called Aeternity that makes all functionalities of the SDK accessible.

    Usage:

    NPM

    Latest Release

    Pre Release

    To install a Pre-Release (latest beta or alpha version) you have to install the package appending the @next tag reference.

    Specific Github Branch

    You can also install a version coming from a specific branch. In this case you would install the SDK version of the develop branch.

    TypeScript projects

    To work properly, sdk requires to enable allowSyntheticDefaultImports flag and register folder that contains type definitions for third-party packages sdk depends on. This may be done in tsconfig.json:

    Ensure that you have strictFunctionTypes option not enabled (as it is in VS code and ts-node by default), otherwise some of SDK types won't work correctly (see ).

    In some environments, TypeScript fails to check types of sdk's dependencies (@metamask/json-rpc-engine, @ledgerhq/hw-transport), if so you may find useful.

    Vue CLI@4

    SDK checks are not working correctly because CLI picks both ESM and CJS versions of autorest dependencies. To fix this, you need to specify aliases in vue.config.js.

    Vue@3

    Reactivity in Vue@3 Proxy class. Proxy is with private fields of ES classes. AeSdk, Contract and AccountMemory classes uses private fields, so if you make an instance of these classes reactive then the app may fail with

    TypeError: attempted to get private field on non-instance

    AeSdk and Contract classes doesn’t have a state intended to be tracked using reactivity. Therefore to solve this issue we suggest to avoid making their instances reactive using Vue's integrated utility: . The idea is to make reactive only the instance value, to don't make it reactive in deep.

    Alternatively, can unwrap the proxy object, returning an unmodified instance and allowing access to its private properties by its methods. It can be useful if you need a reactive array of AccountMemory.

    You can find both approaches used in the .

    Command Line Interface (CLI)

    If you don't need to include specific functionality into your application and just want to use or play around with features the SDK provides you can make use of the and follow the instructions mentioned there.

    AEX 5

    Simple Summary

    This document describes the process and messages required for inter wallet communication between aeternity supported wallets.

    Motivation

    The purpose of AEXs is to provide specification and JSON-RPC compatible messages required for an inter-wallet communication channel.

    npm install -g @aeternity/aeproject
    AEX: 11
    Title: Fungible Token Standard
    Author: Robert Zaremba (@robert-zaremba)
    License: BSD-3-Clause
    Discussions-To: <URL>
    Status: Draft
    Type: Interface
    Created: 2019-09-19
    const sender = 'ak_...';
    const recipient = 'ak_...';
    const options = { onAccount: sender, denomination: 'ae' }; // optional options object
    // aeSdk is an instance of the AeSdk class
    await aeSdk.spend(1, recipient, options); // amount, recipient and (optional) options
    AEX: 7
    Title: Data Serialization
    Author: Andreas Gassmann (@AndreasGassmann), Alessandro De Carli (@dcale)
    License: BSD-3-Clause
    Discussions-To: TBD
    Status: Withdrawn
    Type: Standards Track
    Created: 2019-05-13
    The account needs to be provided to the SDK instance in order to be used for signing.
  • nonce (default: obtain nonce of the account via node API)

    • The default behavior might cause problems if you perform many transactions in a short period of time.

    • You might want to implement your own nonce management and provide the nonce "manually".

    • 2 different strategies to use in order to determine the next nonce, See option strategy to learn more.

  • strategy (default: max)

    • The strategy to obtain next nonce for an account via node API

    • If set to max, then the greatest nonce seen in the account or currently in the transaction pool is incremented with 1 and returned. If the strategy is set to continuity, then transactions in the mempool are checked if there are gaps - missing nonces that prevent transactions with greater nonces to get included

  • ttl (default: 0 if buildTx used, current height + 3 otherwise)

    • Should be set if you want the transaction to be only valid until a certain block height is reached.

  • fee (default: calculated for each tx-type, based on network demand)

    • The minimum fee is dependent on the tx-type.

    • You can provide a higher fee to additionally reward the miners.

  • innerTx (default: false)

    • Should be used for signing an inner transaction that will be wrapped in a PayingForTx.

  • verify (default: false)

    • If set to true the transaction will be verified prior to broadcasting it.

  • waitMined (default: true)

    • Wait for transactions to be mined.

    • You can get the tx object that contains the tx-hash immediately by setting to false and should implement your own logic to watch for mined transactions.

  • (default:
    aettos
    )
    • You can specify the denomination of the amount that will be provided to the contract related transaction.

  • gasLimit

    • Maximum amount of gas to be consumed by the transaction. Learn more on How to estimate gas?

  • gasPrice (default: based on network demand, minimum: 1e9)

    • To increase chances to get your transaction included quickly you can use a higher gasPrice.

  • This option tells the protocol the relative TTL based on the current block height.

  • 180000 is the maximum possible value

  • )
    • The TTL of the oracle that defines its expiration.

  • oracleTtlType (default: ORACLE_TTL_TYPES.delta)

    • ORACLE_TTL_TYPES.delta: TTL value treated relative to a current block height

    • ORACLE_TTL_TYPES.block: TTL value treated as absolute block height

  • )
    • The TTL of the query that defines its expiration. The oracle needs to respond before the queryTtl expires.

  • queryTtlType (default: ORACLE_TTL_TYPES.delta)

    • ORACLE_TTL_TYPES.delta: TTL value treated relative to a current block height

    • ORACLE_TTL_TYPES.block: TTL value treated as absolute block height

  • responseTtlValue (default 10)

    • The TTL of the response that defines its expiration. The response of the oracle will be garbage collected after its expiration.

  • responseTtlType (default ORACLE_TTL_TYPES.delta)

    • ORACLE_TTL_TYPES.delta: TTL value treated relative to a current block height

    • ORACLE_TTL_TYPES.block: TTL value treated as absolute block height

  • Aeternity snap for MetaMask
    main action
    codecov
    docs
    npm
    npm
    AEproject Library
    Migration from 3.x.x to 4.x.x
    Migration from 4.x.x to 5.x.x
    Upcoming Version Support
    npm version
  • A holder MUST be allowed to re-authorize a previously revoked default operator.

  • op_data MUST contain the extra information provided by the address which triggered the decrease of the balance (if any).

    WebSockets
  • Webhooks

  • Bluetooth

  • NFC

  • TransactionSignRequest
  • TransactionSignResponse

  • MessageSignRequest

  • MessageSignResponse

  • RLP
    airgap-coin-lib
    transaction options
    transaction options
    ae-oracle-pricefeed
    tipping-oracle-service

    bundling through webpack

    ES6 modules
    Promises
    async/await
    webpack
    Babel
    loader
    tree-shaking
    source
    Larry Wall
    WebPack
    Babel
    Node.js
    test
    TypeDoc
    a script
    Xcode
    mocha
    1
    How to release a new version
    #1793
    skipLibCheck
    based on
    not compatible
    shallowRef
    toRaw
    æpp example
    💻 CLI
    contract AEX11Token {
        record meta_info = { name : string
                             symbol : string
                             decimals : int}
        entrypoint meta(): meta_info
        entrypoint total_supply() external : int
        entrypoint balance_of(holder: address) : option(int)
    
        external default_operators() : list(address)
        external is_operator_for(operator: address, holder: address) : bool
        stateful external authorize_operator(operator: address)
        stateful external revoke_operator(operator: address)
    
        entrypoint stateful transfer(to: address, amount: int, data: string)
        entrypoint stateful op_transfer(from: address, to: address, amount: int, data: string, op_data: string)
    
        entrypoint stateful burn(amount: int, data: string)
        entrypoint stateful op_burn(from: address, amount: int, data: string, op_data: string)
    
        datetype event =
            // operator, from, to, amount ,data, op_data
            Transfer(indexed address,  // operator
                     indexed address,  // from
                     address,          // to
                     int,              // amount
                     string,           // data
                     string)           // op_data
          | Mint(indexed address,  // operator
                 indexed address,  // to
                 int,              // amount
                 string,           // data
                 string)           // op_data
          | Burned(indexed address,  // operator
                   indexed address,  // from
                   int,              // amount
                   string,           // data
                   string)           // op_data
          | AuthorizedOperator(indexed address,  // operator
                               indexed address)  // holder
          | RevokedOperator(indexed address,  // oprator
                            indexed address)  // holder
    }
    stateful entrypoint tokensToTransfer(
        operator: address,
        from: address,
        to: address,
        amount: int,
        data: string,
        op_data: string
    )
    function tokensReceived(
        operator: address,
        from: address,
        to: address,
        amount: int,
        data: string,
        op_data: string
    )
    [
      1, // ProtocolVersion
      1, // SerializationType: Full or Chunked
      [
        // Array of Messages
        [
          1, // MessageVersion
          2, // MessageType
          "ae", // Protocol
          "payload" // Payload depending on the MessageType
        ],
        [
          1, // MessageVersion
          3, // MessageType
          "ae", // Protocol
          "payload" // Payload depending on the MessageType
        ]
      ]
    ];
    2hDLW1FiwvQs5ofPUgi5CgAJKDWiNncCoETXf7DGdkkDmrhN3z
    function serialize(rlp, maxChunkSizeInByte): string[] {}
    function deserialize(chunks): any[] {}
    
    const chunks = serialize(rlp, 1024);
    const deserializedRlp = deserialize(chunks);
    [
      1, // Protocol Version
      1, // SerializationType: Full or Chunked
      [
        1, // Current Page
        4, // Number of pages
        "payload of current chunk as string"
      ]
    ];
    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())
    // 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);
    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);
    const { queryId } = await oracleClient.postQuery('{"city": "Berlin"}'); // oq_...
    
    console.log('Oracle query ID', queryId);
    const response = await oracleClient.pollForResponse(queryId);
    
    console.log('Decoded oracle response', response);
    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();
    const stopPolling = await oracle.pollQueries(
      (query) => {
        console.log(query); // log a new query
      },
      { interval: 1000 }, // polling interval in milliseconds
    );
    
    stopPolling();
    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);
    // 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);
    #generate examples and api documentation
    npm run docs:examples && npm run docs:api
    npm install
    npm run build
    npm install -g windows-build-tools
    sudo apt-get update
    sudo apt-get install build-essential
    xcode-select --install
    npx webpack --env REPORT
    npm test
    <script src="https://unpkg.com/@aeternity/aepp-sdk/dist/aepp-sdk.browser-script.cjs"></script>
    <script src="https://unpkg.com/@aeternity/aepp-sdk@VERSION/dist/aepp-sdk.browser-script.cjs"></script>
    <!doctype html>
    <html lang="en">
      <head>
        <meta charset="utf-8" />
      </head>
      <body>
        <!-- include latest SDK version -->
        <script src="https://unpkg.com/@aeternity/aepp-sdk/dist/aepp-sdk.browser-script.cjs"></script>
        <script type="text/javascript">
          const { AeSdk, Node } = Aeternity;
    
          const node = new Node('https://testnet.aeternity.io');
          const aeSdk = new AeSdk({
            nodes: [{ name: 'testnet', instance: node }],
          });
          aeSdk.getHeight().then((height) => {
            console.log('Current Block Height:' + height);
          });
        </script>
      </body>
    </html>
    npm i @aeternity/aepp-sdk
    npm i @aeternity/aepp-sdk@next
    npm i github:aeternity/aepp-sdk-js#develop
    {
      "compilerOptions": {
        ...
    +   "typeRoots": [
    +     "node_modules/@types",
    +     "node_modules/@aeternity/aepp-sdk/src/typings"
    +   ],
    +   "allowSyntheticDefaultImports": true
      }
    }
    module.exports = {
      configureWebpack: {
        resolve: {
          alias: {
    +       '@azure/core-client': '@azure/core-client/dist-esm/src/index.js',
    +       '@azure/core-rest-pipeline': '@azure/core-rest-pipeline/dist-esm/src/index.js',
          },
        },
      },
    };

    Currently, if a wallet wants to talk to another wallet then each wallet has to implement its own set of messages that the wallet on the other end will understand and this gets limited to communication between the wallets of a single vendor. Although, this single vendor implementation eases the transaction and message signing part when having multiple devices but it binds users to a single wallet and single experience.

    By standardization of the set of messages that should be used for inter-wallet communication this AEX will to open the communication between different types of wallet (mobile, web, extensions) from different vendors.

    Current Process (with regards to AEX-2)

    1. SDK connects with a wallet

    2. Wallet shares the account address with the SDK

    3. When the SDK needs the wallet to sign the transaction it asks the wallet

    4. Wallet signs and returns the signed transaction.

    Proposed process with inter-wallet communication

    1. SDK connects with a wallet

    2. Wallet returns its current address and other account addresses it may help the SDK in getting signature for.

    3. When the SDK needs the wallet to sign the transaction it asks the wallet

    4. Wallet performs steps in the below order

      1. checks if it can sign the transaction.

      2. else it checks if it holds a direct link to the wallet that can sign the transaction and forwards the request to it.

      3. and at last it checks if there is an indirect link to the signing address i.e. via another connected wallet and forwards the request to it.

    5. Once the transaction is signed, it is returned back to the requesting SDK for further processing.

    Specification

    JSON-RPC 2.0 Methods

    General

    • error: Used to communicate any error occurred. Error code 1 to 9 are reserved and reused here from AEX-2.

    • ping/pong: general ping/pong messages to check liveness. Implementation of this method is not mandatory for wallets communicating over a transport layer that have native support for liveness check.

      Parameters

      Object

      • id - A unique identifier, must conform to the

      Returns

      Object

      • id - same id as in the corresponding request

      • data - Value will always be equal to pong

    Start and Close

    • wallet.channel.initiate: Initiate request to open a communication channel. The request contains an identifier that will be used by either party to recognize and process incoming messages. The id should match the subsequent incoming or outgoing messages between the two wallets. The generated identifier must be unique and must conform to the UUID v4 standards.

      Parameters

      Object

      • id - A unique identifier, must conform to the

      • name - human readable wallet name

      • version - protocol version. Currently defaults to 1.

      Returns

      Object

      • id - same id as in the corresponding request

      • name - human readable wallet name

    • wallet.channel.close: Close the channel

      Parameters

      Object

      • id - A unique identifier, must conform to the

      Returns

      Object

    • wallet.channel.close_incoming: Close channel only for signing requests i.e. closing wallet can still ask the wallet on another end to sign or forward the transactions.

      Parameters

      Object

      • id - A unique identifier, must conform to the

      Returns

    Address Update

    • wallet.get.address: Ask the connected wallet for its address

      Parameters

      Object

      • id - A unique identifier, must conform to the UUID v4 standards

    • wallet.update.address: Issued by connected wallets for returning addresses incl. from the connected wallets. The connected field is optional and contains the list of address of the wallets it is further connected to.

      Parameters

      Object

      • id - A unique identifier, must conform to the

      • address - Object containing two objects named current and connected.

        • current

    Sign and Broadcast Transaction

    • wallet.sign.tx: Ask the connected wallet to sign the transaction.

      Parameters

      Object

      • id - A unique identifier, must conform to the UUID v4 standards

      • tx - raw unsigned transaction

      Returns

      Object

      • id - same id as in the corresponding request

      • tx - signed tx returned by the wallet

    • wallet.request.broadcast: Ask connected wallet to broadcast the transaction. The connected wallet can try to broadcast the transaction itself or forward it to the SDK. If the wallet is unable to broadcast it returns the error with code 3.

      Parameters

      Object

      • id - A unique identifier, must conform to the

    Example Flow

    [WIP]

    user-guide

    User guide

    This guide assumes that you have aecli installed and you checked the Quick start.

    Table of Contents

    Account commands

    The account (wallet) are those which create and report on key pairs, and sign transactions, messages. To within aeternity, you need to have at least two wallets with some coins on their accounts.

    Use to create a new wallet. You can specify a password for accessing your wallet or just press Enter if you do not want to set a password. The wallet is created at the specified path.

    Alternatively, you can pass the secret key in [secretKey] argument to generate a corresponding wallet.

    View the address (public key) of your wallet using command. Also, it can be used to reveal your secret key.

    The name group

    With the aeternity naming system (AENS), you can assign and register a name to your account or oracle. This way, instead of a complex hash, you can use a name you choose. These names have an expiration period, after which the name will no longer belong to anyone, so it can be claimed again. For more information, see docs.

    The name group consists of the .

    Use to create and register a name for your account.

    After that, you can use command to set a name pointer. You can assign the name to another account via pointers, you will still have the right to do other operations with this name.

    Don't forget to run from time to time to don't lose access to your name. By default name TTL gets extended to one year, it can't be extended for a longer period.

    You can a name to another account or contract, just indicate another account's address. You will pass all rights regarding the name to another account.

    At last, you can revoke your name using . The revoked name can be claimed again after a fixed timeout of 2016 blocks (~ 4 days).

    The contracts group

    A smart contract is a computer protocol intended to digitally facilitate, verify, or enforce the negotiation or performance of a contract. Smart contracts allow the performance of credible transactions without third parties. These transactions are trackable and irreversible. Smart contracts aim to provide security that is superior to traditional contract law and to reduce other transaction costs associated with contracting.

    The contracts group consists of the .

    deploy

    Here is an example contract that we will deploy

    To deploy a contract, run adding a file that should be compiled.

    call

    To execute a function of the contract, run command. sum is a function which is executed by this contract, [1, 2] are arguments of this function:

    In the above, the "Return value (decoded)" is a result of contract execution — it is a sum of values 1 and 2.

    The chain group

    display basic information about the blockchain and require little explanation. moves backward through the blockchain displaying blocks and transactions.

    Inspect command examples

    The command allows you to see inside various æternity types. Because each æternity type starts with two letters identifying what sort of thing it is, you can throw anything you like at inspect, and it will bravely try to do the right thing.

    inspect account by address

    inspect transaction

    inspect block

    Offline signing

    One of aecli use cases is offline signing. It requires the below steps.

    1. prepare a transaction using on any device;

    2. optionally run to verify the generated transaction before signing on offline device;

    3. sign the transaction by on offline device;

    4. broadcast signed transaction using on a device connected to the internet.

    Migration to 14.0.0

    This guide describes all breaking changes introduced with v14.0.0.

    Updated sdk requirements

    Minimum supported versions:

    • [email protected]

    • [email protected]

    • aeternity node 7.1.0

    • [email protected]

    • aesophia@8

    Iris is not supported

    Stick to a previous sdk version if it is required.

    CommonJS bundles have cjs extension instead js

    If you are importing files explicitly from dist folder then you need to update the extension

    recover, dump removed (AEX-3 keystore implementation)

    Copy the removed implementation to your project or add a previous sdk as a separate dependency

    $host is readonly in generated APIs

    It is made to don't break caching. If you need to change a server URL, create a new server instance instead.

    Aepp

    RpcBroadcastError not exported anymore

    Because it is not thrown by wallet as well.

    Contract delegations used in Iris removed from aepp-wallet connection

    Use signDelegation api instead.

    Wallet

    AeSdkWallet requires onAskToSelectNetwork constructor option

    Provide a function throwing RpcMethodNotFoundError if you don't want to support network change by aepp.

    Transaction builder

    ChannelClientReconnectTx removed

    You couldn't use it because it is not supported on the node side.

    ORACLE_TTL, QUERY_TTL, RESPONSE_TTL not exported anymore

    These values provided by default in buildTx, if necessary define them as

    buildTx/unpackTx works only with transactions

    If you need to work with node's entry use packEntry/unpackEntry.

    Tag include only transactions

    Node entries tags moved to EntryTag.

    buildTx doesn't accept prefix anymore

    Use decode/encode to convert payload to desired format.

    NAME_*TTL, CLIENT_TTL not exported anymore

    These values provided by default in buildTx, if necessary define them as

    Node

    Node returns time in KeyBlock and MicroBlockHeader as Date

    Apply a change

    Account

    Save HD wallets methods removed

    Namely: deriveChild, derivePathFromKey, getMasterKeyFromSeed,derivePathFromSeed, getKeyPair, generateSaveHDWalletFromSeed,getSaveHDWalletAccounts, getHdWalletAccountFromSeed. Use AccountMnemonicFactory instead.

    sign, signMessage removed

    Use MemoryAccount:sign, MemoryAccount:signMessage instead.

    isValidKeypair removed

    Create a MemoryAccount by a secret key and compare it's address with an address in the key pair instead.

    getAddressFromPriv removed

    Use MemoryAccount instead.

    Use SDK page to convert secret keys.

    generateKeyPair removed

    Use MemoryAccount::generate instead. Optionally add decode if you need raw keys. Obtain the secret key via MemoryAccount:secretKey.

    generateKeyPairFromSecret removed

    Use MemoryAccount instead.

    MemoryAccount accepts secret key as sk_-prefixed string

    Convert secret key as hex to new format as

    Use SDK page to convert secret keys.

    AccountBase inheritors required to implement signTypedData, signDelegation

    You can throw an exception if the account operation is not doable.

    Aens

    aens* methods removed

    Use Name class instead.

    Accordingly for other methods:

    NAME_BID_MAX_LENGTH not exported anymore

    Use isAuctionName function instead.

    Oracle

    oracle methods removed

    Use Oracle, OracleClient classes instead.

    Accordingly for other methods:

    pollQueries don't return responded queries by default

    Use includeResponded option to restore the previous behavior.

    Compiler

    CompilerCli uses aesophia@8 by default

    CompilerCli8 removed

    Use CompilerCli instead.

    Contract

    encodeFateValue, decodeFateValue not exported anymore

    Use ContractByteArrayEncoder:encodeWithType, decodeWithType from @aeternity/aepp-calldata.

    AeSdk:initializeContract removed

    Use Contract.initialize instead:

    createDelegationSignature removed

    Use packDelegation and AccountBase::signDelegation instead.

    Methods to sign specific delegations removed

    Namely:

    • signDelegationToContract,

    • signNameDelegationToContract,

    • signAllNamesDelegationToContract,

    Use signDelegation instead.

    Changelog

    All notable changes to this project will be documented in this file.

    The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

    Unreleased

    - 2024.05.29

    Fixed

    • The issue of large build size by setting include_src to false for prod build, and removing unnecessary dependencies.

    - 2024.04.12

    Fixed

    • Compilation error due to a bug in enacl library.

    - 2024.02.03

    Added

    • format generic server call for formatting outputs as renderables

    • version generic server call

    • set_account generic server call for setting balance of arbitrary account

    Changed

    • Generic server now returns structured data and errors which have to be formatted manually using format call

    • location display has been improved

    • display_gas is renamed to print_gas for consistency

    Removed

    • In-repl Sophia functions

    - 2023.12.19

    Added

    • Option to return rendered results

    • Option to return raw erlang values for successful calls to the gen server

    • Several options to configure printing format

    Changed

    • Themed rendering now returns bytestrings

    • print is renamed to lookup

    • aere_repl more often returns a tuple {Result, repl_state()}

    Removed

    • In-repl functions

    - 2023.12.10

    Added

    • Command print_vars to list all values of all variables at a breakpoint

    - 2023.08.29

    Added

    • File system cache

    - 2023.07.17

    Added

    • Debugger integration

    • REPL meta-states: normal, break, abort

    Changed

    • Rendering of colored messages

    - 2023.09.12

    Changed

    • Reworked file loading and including to resemble GHCi's behaviour

    - 2022.09.04

    Added

    • Disassembling features

    Changed

    • Fixed parsing errors

    • Fixed bugs in printing outputs

    - 2022.08.29

    Added

    • Dockerfile

    • help instruction

    • print instruction

    Changed

    • Refactored the project structure

    • Fixed command parsing

    - 2022.08.05

    Changed

    • Massively refactored and cleaned code

    • The REPL operates directly on the FATE engine

    Removed

    • Most of inline definitions such as types, functions, variables

    - 2020.04.02

    Added

    • Added

    Changed

    • Updated to

    Contributor guide

    Install aecli from git repository

    1. Clone the git repository into any place you like

    AEX: 5
    Title: Inter-Wallet Communication
    Author: Shubhendu Shekhar <@shekhar-shubhendu>
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aex-5-inter-wallet-communication/3371
    Status: Withdrawn
    Type: Standards Track
    Created: 2019-04-29
    stop command to quit debugging state and revert the call
  • Option call_gas_price to set result of Call.gas_price

  • Option call_origin to set the account to execute the repl query (affectsCall.origin and Call.caller)

  • Option call_contract_creator to set result of Contract.creator

  • Option call_fee to set result of Call.fee

  • Option call_height to set result of Chain.block_height

  • Startup parameter accounts to specify initial account balances

  • CLI arguments to set the newly added accounts parameter

  • Fixed numerous bugs and crashes

  • Adjusted output of :location

  • CLI uses REPL supervisor directly

    3.3.2
    3.3.1
    3.3.0
    3.2.0
    3.1.1
    3.1.0
    3.0.0
    2.3.0
    2.2.0
    2.1.0
    2.0.0
    1.2.0
    CHANGELOG.md
    Sophia 4.3.0
    With your terminal: enter in folder when the repo has been cloned
  • Run npm link for linking aecli executable to src/aecli.js

  • Start a new terminal session and try aecli command to see if everything is okay.

  • If you have any issue, open an issue in github

  • If you have problems linking, try also npm install and then npm link. Instead of using npm link you can also execute ./src/aecli.js directly.

    aepp-cli-js
    • id - same id as in the corresponding request

    • status - Value will always be equal to ack

    Object
    • id - same id as in the corresponding request

    • status - Value will always be equal to ack

    - Object containing only a single account currently in use by the wallet.
  • connected(optional) - Object containing multiple connected accounts.

    Example Account Format

  • tx - signed transaction to be broadcasted

  • verify - Boolean. Perform verification before broadcasting or not.

  • Returns

    Object

    • id - same id as in the corresponding request

    • tx_id - transaction id of the broadcasted transaction

    UUID v4 standards
    UUID v4 standards
    UUID v4 standards
    UUID v4 standards
    UUID v4 standards
    UUID v4 standards
    Inspect command examples
  • Offline signing

  • Account commands
    The name group
    The contracts group
    The chain group
    commands
    perform transactions
    aecli account create
    aecli account address
    Aeternity Naming System
    following commands
    aecli name full-claim
    aecli name update
    aecli name extend
    transfer
    aecli name revoke
    following commands
    aecli contract deploy
    aecli contract call
    These commands
    play
    inspect
    transaction builder
    aecli inspect
    aecli account sign
    aecli chain broadcast
    signOracleQueryDelegationToContract.
    tools
    tools
    {
      "current": {
          "ak_2iBPH7HUz3cSDVEUWiHg76MZJ6tZooVNBmmxcgVK6VV8KAE688": {
              "name": "this property is optional"
            }
        }
    }
    contract Example =
      entrypoint sum(a: int, b: int) = a + b
    $ aecli contract deploy --contractSource ./contract.aes ./wallet.json
    Contract was successfully deployed
    Contract address   ct_5MbRKEb77pJVZrjVrQYHu2nzr2EKojuthotio1vZ2Q23dkYkV
    Transaction hash   th_5M77avjrPKezyBrUfkn19C79MnVh9SSoX4Euz4nY75kn9Fxto
    Deploy descriptor  /path/to/contract.aes.deploy.5MbRKEb77pJVZrjVrQYHu2nzr2EKojuthotio1vZ2Q23dkYkV.json
    $ aecli contract call --descrPath contract.aes.deploy.5MbRKEb77pJVZrjVrQYHu2nzr2EKojuthotio1vZ2Q23dkYkV.json sum '[1, 2]' ./wallet.json
    Transaction hash  th_urgozuZRooNXrZxuvNDdT4BiApcGKsf6ZRpffargXcoZNHQ4C
    Block hash        mh_dnoULQWpiRtcrntd5yJPUxcu7YrTu18xZ1e9EC2b8prKdShME
    Block height      4 (about now)
    Signatures        ["sg_Vn2cCsMk8RvBKyNTKTbq8V4vm6beuHxfYA7vLBNLnRF3x9hoydWWAtNkaiix8KhyEFSLmsmTy6jz9Lps2TQqVdmH6qmCG"]
    Transaction type  ContractCallTx (ver. 1)
    Caller address    ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    Contract address  ct_5MbRKEb77pJVZrjVrQYHu2nzr2EKojuthotio1vZ2Q23dkYkV
    Gas               31 (0.000000031ae)
    Gas price         0.000000001ae
    Call data         cb_KxHrtMsKKwIE32Kmfg==
    ABI version       3 (Fate)
    Amount            0ae
    Fee               0.00018198ae
    Nonce             3
    TTL               7 (in 6 minutes)
    ----------------------Call info-----------------------
    Gas used                25 (0.000000025ae)
    Return value (encoded)  cb_BvMDXHk=
    Return value (decoded)  3
    $ aecli inspect ak_22xzfNRfgYWJmsB1nFAGF3kmabuaGFTzWRobNdpturBgHF83Cx
    Account ID       ak_22xzfNRfgYWJmsB1nFAGF3kmabuaGFTzWRobNdpturBgHF83Cx
    Account balance  52.1342501ae
    Account nonce    3
    No pending transactions
    $ aecli inspect th_iirV7mw49NfFY8NbBhbXGBLv9PPT3h1ou11oKtPsJVHGVpWVC
    Transaction hash  th_iirV7mw49NfFY8NbBhbXGBLv9PPT3h1ou11oKtPsJVHGVpWVC
    Block hash        mh_2RojH44UtAjf8pRQekPp7o78CmCqMQJkRdxmfXvVmWg9M6ymcr
    Block height      99005 (5 years ago)
    Signatures        ["sg_MjwB8zrhqGTqYWY2c5jLrikuCcwppnhNhjXg9TcdFbCkSvGhPL6Hf4iu81eoxWWJFSgRSFQ3h3qMv6vVNqYfo5NNBNDFK"]
    Transaction type  NameClaimTx (ver. 2)
    Account address   ak_2i74vkHbdciAdr7Bw3ogdTHsLykPf4ii1DQEGLh6RpySyhtA9H
    Name              yanislav.test
    Name salt         6632125367082877
    Fee               0.00001638ae
    Nonce             2
    $ aecli inspect mh_2DhgyD4np6n3JMsNWVXdtWZE2rAx74sgxL6nb2GsCKB1VnbLxN
    <<--------------- MicroBlock --------------->>
    Block hash               mh_2DhgyD4np6n3JMsNWVXdtWZE2rAx74sgxL6nb2GsCKB1VnbLxN
    Block height             762850
    State hash               bs_9vEQ2hkjJLFoqbmUq2YB3PyZN4TGV6Viv686wgX3i4t21PUK3
    Nonce                    N/A
    Miner                    N/A
    Time                     17/04/2023, 05:54:40
    Previous block hash      mh_2VaToyVbe8joVts9SjzdGJZqK7nk6w4MfvGC32Nfwp9KnTa7Z6
    Previous key block hash  kh_2gVG4vzZwWJfzMe5Ug2jwwDcgcpmjEd1umsWqKA9CkSPidCYuw
    Version                  5
    Target                   N/A
    Transactions             1
        <<--------------- Transaction --------------->>
        Transaction hash   th_2uc2RDDQnDV2BsyVLHA36GP3UZJNn16utV6uivWjLAQoTVBA3u
        Block hash         mh_2DhgyD4np6n3JMsNWVXdtWZE2rAx74sgxL6nb2GsCKB1VnbLxN
        Block height       762850
        Signatures         ["sg_4UUxNZhGLXWjGsfAMEddccjQ1wpZfwUkZ9qMczjRUNFGAWAS3fahHWqgwxLf79RQ3J3ZRnEaazz259dPzUjj5J3EHcNYj"]
        Transaction type   SpendTx (ver. 1)
        Sender address     ak_2swhLkgBPeeADxVTAVCJnZLY5NZtCFiM93JxsEaMuC59euuFRQ
        Recipient address  ak_22xzfNRfgYWJmsB1nFAGF3kmabuaGFTzWRobNdpturBgHF83Cx
        Amount             50ae
        Payload            ba_Xfbg4g==
        Fee                0.00001688ae
        Nonce              1513
    - https://unpkg.com/@aeternity/aepp-sdk/dist/aepp-sdk.browser-script.js
    + https://unpkg.com/@aeternity/aepp-sdk/dist/aepp-sdk.browser-script.cjs
      "dependencies": {
        "@aeternity/aepp-sdk": "^14.0.0",
        "@aeternity/aepp-sdk-13": "npm:@aeternity/aepp-sdk@^13.3.3"
      }
    - node.$host = 'http://example.com';
    + node = new Node('http://example.com');
    const ORACLE_TTL = { type: ORACLE_TTL_TYPES.delta, value: 500 };
    const QUERY_TTL = { type: ORACLE_TTL_TYPES.delta, value: 10 };
    const RESPONSE_TTL = { type: ORACLE_TTL_TYPES.delta, value: 10 };
    const NAME_TTL = 180000;
    const NAME_MAX_TTL = 36000;
    const NAME_MAX_CLIENT_TTL = 86400;
    const CLIENT_TTL = 86400;
    -const time = new Date(
    -  (await node.getTopHeader()).time,
    -);
    +const time = (await node.getTopHeader()).time;
    - address = getAddressFromPriv(secretKeyOldFormat)
    + address = new MemoryAccount(secretKeyNewFormat).address
    - const keyPair = generateKeyPairFromSecret(rawSecretKey)
    + const secretKey = encode(rawSecretKey.subarray(0, 32), Encoding.AccountSecretKey)
    + const account = new MemoryAccount(secretKey)
    + const keyPair = {
    +   publicKey: decode(account.address),
    +   secretKey: rawSecretKey,
    + }
    const oldSk =
      '9ebd7beda0c79af72a42ece3821a56eff16359b6df376cf049aee995565f022f840c974b97164776454ba119d84edc4d6058a8dec92b6edc578ab2d30b4c4200';
    const newSk = encode(Buffer.from(oldSk, 'hex').subarray(0, 32), Encoding.AccountSecretKey);
    // 'sk_2CuofqWZHrABCrM7GY95YSQn8PyFvKQadnvFnpwhjUnDCFAWmf'
    -await aeSdk.aensPreclaim('example.chain')
    +const name = new Name('example.chain', aeSdk.getContext())
    +await name.preclaim()
    aensRevoke => Name:revoke
    aensUpdate => Name:update
    aensTransfer => Name:transfer
    aensQuery => Name:getState
    aensClaim => Name:claim
    aensBid => Name:bid
    -aeSdk.pollForQueries(queryHandler)
    +const oracle = new Oracle(account, aeSdk.getContext());
    +oracle.pollQueries(queryHandler)
    extendOracleTtl => Oracle:extendTtl
    respondToQuery => Oracle:respondToQuery
    getOracleObject => Oracle:getState
    registerOracle => Oracle:register
    getQueryObject => Oracle:getQuery, OracleClient:getQuery
    postQueryToOracle => OracleClient:postQuery
    pollForQueryResponse => OracleClient:pollForResponse
    - aeSdk.initializeContract(options)
    + Contract.initialize({ ...aeSdk.getContext(), ...options })
    -const dlg = await aeSdk.createDelegationSignature(contractAddress, [name]);
    +const dlg = await aeSdk.signDelegation(
    +  packDelegation({
    +    tag: DelegationTag.AensName,
    +    accountAddress: aeSdk.address,
    +    contractAddress,
    +    nameId: name,
    +  }),
    +);

    aepp-cli-js

    Command Line Interface for the æternity blockchain.

    Installation

    You can install aecli using your preferred tool (yarn or npm). Here's an npm example

    Quick start

    Let's ensure that CLI installed correctly by running $ aecli. It will show the available commands as below.

    To read documentation of other commands and sub-commands, you can append --help. For example, type aecli account --help to get a list of commands available in account module.

    The next step is to create a wallet to use in other commands:

    You need to send some coins to the created wallet.

    On testnet you can do that using . Switch to testnet using $ aecli select-node.

    Run $ aecli inspect <wallet address> to ensure that it got coins.

    At the last step, we will send our coins to another account:

    Find out more in the .

    Resources

    Commands reference

    • account

      • — sign a transaction using wallet

      • — sign a personal message using wallet

      • — check if message was signed by address

    Migration to 11.0.0

    This guide describes all breaking changes introduced with v11.0.0.

    Changes to decodeEvents method

    • Removed decodeEvents from contract ACI methods ().

    rewrite

    to

    • Removed raw fields from the decodeEvents response () use processed fields for the same.

    • Renamed decoded events response field decoded to args

    old response

    new response

    Removed allowUnsynced option of poll method ()

    Transaction poll method now checks if Tx is in the node pool ()

    The default polling interval of 5000 is replaced by a method which calculates the default interval using expected mine rate and micro block cycle ()

    Following contract instance methods are dropped()

    • topBlock

      • use aeSdk.api.getTopHeader() instead

    • contractCall

    rewrite

    to

    The default gas of 25000 limit has been dropped. Instead, SDK attempts to estimate the gas using dry-run feature ()

    See documentation on for detailed explanation.

    Removed Wrappers around CompilerApi ()

    • Removed getBytecodeCompilerVersion method.

    • Removed encodeCall method from contractCompile response.

    • Removed getCompilerVersion method, use aeSdk. sdk.compilerVersion instead.

    rewrite

    to

    • Removed contractEncodeCallDataAPI:

    rewrite

    to

    • Removed contractGetACI:

    rewrite

    to

    • Removed validateByteCodeAPI:

    rewrite

    to

    Native build of claim tx now accepts unencoded name instead of encoded name ()

    rewrite

    to

    Removed forceValidation flag from aepp-rpc and wallet-rpc stamps. ()

    Renamed hd-wallet methods ()

    • Renamed generateSaveHDWallet to generateSaveHDWalletFromSeed

    • Renamed getHdWalletAccountFromMnemonic to getHdWalletAccountFromSeed

    Usage with TypeScript

    This guide explains handling the edge cases that can occur while using aeternity SDK in a TypeScript project.

    Firstly, ensure you've set up TypeScript according to the installation guide.

    Extract types of methods exposed by SDK

    SDK doesn't expose types separately to reduce the number of exports and simplify tracking of breaking changes. But you may need these types to prepare parameters or to hold the return value. In such cases, it is advised to use TypeScript-provided generics Parameters and ReturnType. For example,

    The same for ReturnType:

    Initialize parameters with specific types

    You may need to define an object with parameters to call an sdk method. Obvious to try it as

    The problem in this case, is that TypeScript will generalize the type of unpackedEntry.txHash to string instead of th_${string} making it incompatible with arguments of . To fix this you may define gaAuthData's type explicitly, like:

    Or to define gaAuthData as immutable:

    In the last case, txHash's type will be exactly "th_2CKnN6EorvNiwwqRjSzXLrPLiHmcwo4Ny22dwCrSYRoD6MVGK1", making it compatible with .

    Narrow the union type returned by , , and

    Some sdk methods return a of multiple types. For example, returns a union of fields. To work correctly you need to narrow this type to a specific transaction before accessing its fields. For example,

    Without checking the tx.tag TypeScript will fail with

    Property 'amount' does not exist on type 'TxUnpackedSignedTx1 & { tag: Tag; }'.

    The above check is also implemented in itself, instead of checking the tx.tag you can provide Tag in the second argument:

    But if you need to get SpendTx properties inside a SignedTx you still need to use the above tag check.

    You may find that is a generic function so that it can be executed as

    The problem is that JavaScript won't check if the transaction is a SpendTx, so provide Tag.SpendTx as the second argument instead (as the above).

    Functions to assert types of user-provided data

    Let's assume we need to receive an address from the user to send some coins to it. The user enters an address in a text box, we can get it as a string. method accepts the address as , it won't accept a general string. We can overcome this restriction by adding a type assertion, like:

    The problem is that TypeScript won't check if address is an ak_-encoded string, and the method will fail in this case. A more accurate solution would be to check the address in advance, providing user feedback if it is incorrect. For example:

    Please note that this method doesn't require explicit casting string to because implicitly marks address as ak_${string} in case it returns true.

    Additionally, you can use to validate data against other address types:

    Or encoding types in general:

    AENS name validation

    The similar way can be used

    If you don't need to handle invalid names specially then you can use :

    Doing this way, will throw an exception if nameAsString is not a proper AENS name. TypeScript will handle nameAsString as ${string}.chain in lines below invocation.

    Check types of contract methods

    By default, it is allowed to call any method of the instance. You can enable type-checking by providing a contract interface in a generic parameter of . For example:

    If you need to define the contract interface separately then extend :

    It is theoretically possible to generate a contract interface by ACI. But unfortunately, it is currently.

    AEX-130: æpps Metadata Format Specification

    Simple Summary

    The goal of this document is to specify a format for metadata which æpps provide to æpp listing services, decentralized æpp stores, æpp browsers, and wallets.

    Abstract

    $ npm install --global @aeternity/aepp-cli
    import { walletDetector } from '@aeternity/aepp-sdk';
    
    type WDCallback = Parameters<typeof walletDetector>[1];
    type Wallet = Parameters<WDCallback>[0]['newWallet'];
    let wallet: Wallet | null = null;
    
    const stop = walletDetector(connection, ({ newWallet }) => {
      wallet = newWallet;
      stop();
    });
    import { unpackDelegation } from '@aeternity/aepp-sdk';
    
    type DlgUnpacked = ReturnType<typeof unpackDelegation>;
    let delegation: DlgUnpacked | null = null;
    
    delegation = unpackDelegation(
      'ba_+EYDAaEBXXFtZp9YqbY4KdW8Nolf9Hjp0VZcNWnQOKjgCb8Br9mhBV1xbWafWKm2OCnVvDaJX/R46dFWXDVp0Dio4Am/Aa/Z2vgCEQ==',
    );

    replace await aeSdk.contractCall(identityContract, contractId, 'getArg', [42])

  • with (await aeSdk.getContractInstance({ source, contractAddress: contractId })).methods.getArg(42)

  • contractCompile

    • replace await aeSdk.contractCompile(CONTRACT_SOURCE)

    • with (await aeSdk.getContractInstance({ source: CONTRACT_SOURCE })).compile()

  • contractDeploy

    • replace await aeSdk.contractDeploy(bytecode, identityContract)

    • with (await aeSdk.getContractInstance({ bytecode, source: identityContract })).deploy()

  • contractCallStatic

    • replace await aeSdk.contractCallStatic(identityContract, null, 'init', [], { bytecode })

    • with await contract.deploy([], { callStatic: true })

  • Removed property createdAt from contract.deploy method response

  • call/callStatic

    • removed call and callStatic methods from deploy response

  • Removed contractDecodeCallDataByCodeAPI method.

  • Removed contractDecodeCallResultAPI method.

  • Removed getFateAssembler method.

  • Removed compileContractAPI method.

  • a84d781
    45bae5f
    6baa15d
    690db5b
    d9c6cf9
    #1368
    #1367
    transaction-options.md
    #1363
    eea92be
    9f958c3
    f6243ad
    packEntry
    packEntry
    unpackTx
    unpackDelegation
    unpackEntry
    union
    unpackTx
    all supported transaction
    unpackTx
    unpackTx
    spend
    Encoded.AccountAddress
    spend
    Encoded.AccountAddress
    isEncoded
    isEncoded
    isName
    ensureName
    ensureName
    ensureName
    Contract
    Contract
    ContractMethodsBase
    not supported
    cInstance.methods.emitEvents.decodeEvents(log);
    cInstance.decodeEvents(log);
    // events emitted by contract calls are automatically decoded
    const tx = await contractInstance.methods.emitEvents(1337, 'this message is not indexed');
    console.log(tx.decodedEvents);
    
    /*
    [
      {
        address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh',
        data: 'cb_dGhpcyBtZXNzYWdlIGlzIG5vdCBpbmRleGVkdWmUpw==',
        topics: [
          '101640830366340000167918459210098337687948756568954742276612796897811614700269',
          '39519965516565108473327470053407124751867067078530473195651550649472681599133'
        ],
        name: 'AnotherEvent',
        decoded: [
          'fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk',
          'this message is not indexed'
        ]
      },
      {
        address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh',
        data: 'cb_Xfbg4g==',
        topics: [
          '59505622142252318624300825714684802559980671551955787864303522023309554554980',
          1337
        ],
        name: 'FirstEvent',
        decoded: [ '1337' ]
      }
    ]
    */
    // events emitted by contract calls are automatically decoded
    const tx = await contractInstance.methods.emitEvents(1337, 'this message is not indexed');
    console.log(tx.decodedEvents);
    
    /*
    [
      {
        name: 'AnotherEvent',
        args: [
          'fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk',
          'this message is not indexed'
        ],
        contract: {
          name: 'EventEmitter',
          address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh'
        }
      },
      {
        name: 'FirstEvent',
        args: [1337n],
        contract: {
          name: 'EventEmitter',
          address: 'ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh'
        }
      }
    ]
    */
    deployed = await contract.deploy([], { onAccount });
    await deployed.call('getArg', [42]);
    await deployed.callStatic('getArg', [42]);
    await contract.deploy();
    await contract.methods.getArg(42, { callStatic: false });
    await contract.methods.getArg(42, { callStatic: true });
    const code = await aeSdk.compileContractAPI(identityContract);
    const callData = await aeSdk.contractEncodeCallDataAPI(identityContract, 'init', []);
    const result = await initiatorCh.createContract({
      code,
      callData,
      deposit: 1000,
      vmVersion: 5,
      abiVersion: 3,
      amount,
      gas,
      gasPrice,
    });
    contract = await aeSdk.getContractInstance({ source: contractSource });
    await contract.compile();
    const result = await aeSdk.createContract({
      code: contract.bytecode,
      callData: contract.calldata.encode('Identity', 'init', []),
      deposit: 1000,
      vmVersion: 5,
      abiVersion: 3,
      amount,
      gas,
      gasPrice,
    });
    
    //or
    bytecode = (await aeSdk.compilerApi.compileContract({ code: contractSource })).bytecode;
    await aeSdk.contractEncodeCallDataAPI(contractSource, 'getArg', ['42']);
    contract = await aeSdkInitiator.getContractInstance({ source: contractSource });
    await contract.compile();
    contract.calldata.encode('Identity', 'getArg', [42]);
    const aci = await aeSdk.contractGetACI(contractSource);
    const aci = await aeSdk.compilerApi.generateACI({ code: contractSource });
    aeSdk.validateByteCodeAPI(bytecode, identityContract);
    await aeSdk.compilerApi.validateByteCode({ bytecode, source: identityContract });
    const name = 'test123test.chain';
    const nameHash = `nm_${encodeBase58Check(Buffer.from(name))}`;
    const params = { accountId: senderId, nonce, name: nameHash, nameSalt: _salt, nameFee };
    const txFromAPI = await aeSdk.nameClaimTx(params);
    const name = 'test123test.chain';
    const params = { accountId: senderId, nonce, name, nameSalt: _salt, nameFee };
    const txFromAPI = await aeSdk.nameClaimTx(params);
    import { packEntry, EntryTag } from '@aeternity/aepp-sdk';
    
    const gaAuthData = {
      tag: EntryTag.GaMetaTxAuthData,
      fee: 766e11,
      txHash: 'th_2CKnN6EorvNiwwqRjSzXLrPLiHmcwo4Ny22dwCrSYRoD6MVGK1',
    };
    
    const gaAuthDataPacked = packEntry(gaAuthData);
    import { Tag, Encoded } from '@aeternity/aepp-sdk';
    
    interface GaAuthData {
      tag: Tag;
      fee: number;
      txHash: Encoded.TxHash;
    }
    
    const gaAuthData: GaAuthData = {
      tag: EntryTag.GaMetaTxAuthData,
      fee: 766e11,
      txHash: 'th_2CKnN6EorvNiwwqRjSzXLrPLiHmcwo4Ny22dwCrSYRoD6MVGK1',
    };
    const gaAuthData = {
      tag: EntryTag.GaMetaTxAuthData,
      fee: 766e11,
      txHash: 'th_2CKnN6EorvNiwwqRjSzXLrPLiHmcwo4Ny22dwCrSYRoD6MVGK1',
    } as const;
    import { unpackTx, Tag } from '@aeternity/aepp-sdk';
    
    const encodedTx =
      'tx_+F0MAaEB4TK48d23oE5jt/qWR5pUu8UlpTGn8bwM5JISGQMGf7ChAeEyuPHdt6BOY7f6lkeaVLvFJaUxp/G8DOSSEhkDBn+wiBvBbWdOyAAAhg9e1n8oAAABhHRlc3QLK3OW';
    
    const tx = unpackTx(encodedTx);
    
    if (tx.tag !== Tag.SpendTx) {
      throw new Error(`Unknown transaction type: ${Tag[tx.tag]}`);
    }
    
    console.log(tx.amount);
    const tx = unpackTx(encodedTx, Tag.SpendTx);
    const tx = unpackTx<Tag.SpendTx>(encodedTx);
    await aeSdk.spend(100, address as Encoded.AccountAddress);
    import { isEncoded, Encoding } from '@aeternity/aepp-sdk';
    
    if (!isEncoded(address, Encoding.AccountAddress)) {
      alert('The address is not valid');
      return;
    }
    
    await aeSdk.spend(100, address);
    import { Encoding } from '@aeternity/aepp-sdk';
    
    isEncoded(address, Encoding.ContractAddress, Encoding.OracleAddress);
    isEncoded(address, Encoding.Transaction);
    import { isName } from '@aeternity/aepp-sdk';
    
    console.log(isName('name.chain')); // true
    console.log(isName('мир.chain')); // true
    console.log(isName('🙂.chain')); // false
    import { ensureName, Name } from '@aeternity/aepp-sdk';
    
    const nameAsString: string = readName();
    ensureName(nameAsString);
    const name = new Name(nameAsString, options);
    import { Contract } from '@aeternity/aepp-sdk';
    
    const sourceCode = `
    include "String.aes"
    
    contract Test =
      entrypoint foo(x: int) = x
    
      entrypoint bar(x: map(string, int)) = x
    
      datatype name = FirstName(string) | LastName(string)
      entrypoint baz(n: name) =
        switch(n)
          FirstName(first) => String.length(first)
          LastName(_) => abort("Last name not supported yet")
    `;
    
    const contract = await Contract.initialize<{
      foo: (v: bigint) => bigint;
      bar: (x: Map<string, bigint>) => Map<string, bigint>;
      baz: (v: { FirstName: [string] } | { LastName: [string] }) => number;
    }>({
      ...aeSdk.getContext(),
      sourceCode,
    });
    
    await contract.$deploy([]);
    
    console.log((await contract.foo(21n)).decodedResult); // 42
    console.log((await contract.bar(new Map([['test', 10n]]))).decodedResult); // Map(1) { 'test' => 10n }
    console.log((await contract.baz({ FirstName: ['Nikita'] })).decodedResult); // 6
    import { ContractMethodsBase } from '@aeternity/aepp-sdk';
    
    interface FooContract extends ContractMethodsBase {
      foo: (v: bigint) => bigint;
      bar: (x: Map<string, bigint>) => Map<string, bigint>;
      baz: (v: { FirstName: [string] } | { LastName: [string] }) => number;
    }
    
    const contract = await Contract.initialize<FooContract>({
      ...aeSdk.getContext(),
      sourceCode,
    });
  • address — get wallet address and optionally secret key

  • create — create a wallet by a secret key or generate a new one

  • spend — send coins to another account or contract

  • name

    • full-claim — claim an AENS name in a single command

    • pre-claim — pre-claim an AENS name

    • claim — claim an AENS name (requires pre-claim)

    • — bid on name in auction

    • — update a name pointer

    • — extend name TTL

    • — revoke an AENS name

    • — transfer a name to another account

  • contract

    • compile — compile a contract to get bytecode

    • encode-calldata — encode calldata for contract call

    • decode-call-result — decode contract call result

    • — execute a function of the contract

    • — deploy a contract on the chain

  • oracle

    • create — register current account as oracle

    • extend — extend oracle's time to leave

    • create-query — create an oracle query

    • — respond to an oracle query

  • chain

    • top — query the top key/micro block of the chain

    • status — query node version, network id, and related details of the selected node

    • ttl — get relative TTL by absolute TTL

    • — prints blocks from top until condition

    • — send signed transaction to the chain

  • inspect — get details of a node entity

  • tx

    • spend — build spend transaction

    • name-preclaim — build name preclaim transaction

    • name-claim — build name claim transaction

    • — build name update transaction

    • — build name transfer transaction

    • — build name revoke transaction

    • — build contract deploy transaction

    • — build contract call transaction

    • — build oracle register transaction

    • — build oracle extend transaction

    • — build oracle post query transaction

    • — build oracle respond transaction

    • — verify transaction using node

  • config — print the current sdk configuration

  • select-node — specify node to use in other commands

  • select-compiler — specify compiler to use in other commands

  • faucet
    user guide
    User guide
    Changelog
    Contributor guide
    sign
    sign-message
    verify-message
    A format which is consistenly used by developers is needed to facilitate the uniform and useful user experience of browsing aepps inside æpps browsers, wallets, and listing services.

    Motivation

    The motivation behind this aexpansion is to improve the user experience of browsing æpps inside æpps browsers, wallets, and listing services. Our goal is to make it easy for users to recognize the purpose of an æpp/what the æpp allows its users to do and whether users would like to open the æpp and give it access to the account data it requests.

    Specification

    Format

    Required members

    • Name of aepp

    • aepp icons

    • Networks the aepp is available on [mainnet, testnet]

    Recommended members

    • aepp description

    • Category (select from predermined list)

    • Author

    • Author URL

    • Related applications

    • Age restrictions/rating

    References

    Reference visuals for the result of implementing such metadata format are included below.

    A service listing aepps
    Detail view of a aepp metadata rendered inside a aepp browser

    Rationale

    We are leveraging the webmanifest format and augmenting it to fit the needs of the blockchain context. The premise is that this format can be universal (used by multiple protocols, with only one field difference).

    Other considerations

    • Consider if aeppsmanifest format applies to both web and non-web contexts.

    • This proposal does not address whether metadata provided by an aepp is accurate/truthful.

    Future Considerations

    • This proposal does not articulate a stance on storage concerns (as aepp metadata can be rendered dynamically or stored locally).

    • This proposal does not address the concern of aepps sharing aepps data between themselves.

    Implementation

    Required members

    name member

    Documentation: https://www.w3.org/TR/appmanifest/#name-member

    icons member

    Documentation: https://www.w3.org/TR/appmanifest/#icons-member

    aeternity_network_ids member

    An array of AeternityNetworkIdType items, each item represents id of the network that aepp is compatible with. The persistence of this member means that aepp supports aeternity protocol.

    AeternityNetworkIdType is a string, allowed values: ae_mainnet, ae_uat (testnet).

    Recommended members

    description member

    Documentation: https://www.w3.org/TR/appmanifest/#description-member

    category member

    Documentation: https://www.w3.org/TR/appmanifest/#categories-member List of known values: https://github.com/w3c/manifest/wiki/Categories

    author member

    The author member is a string that represents the name of author.

    author_url member

    The author_url member is a string that represents the URL of the author's website.

    Additional members

    iarc_rating_id member

    Could be used to set age restrictions/ratings. Documentation: https://www.w3.org/TR/appmanifest/#iarc_rating_id-member

    Reference implementation

    http://aeternity.com/aepp-base-example/webmanifest.json


    References

    Web App Manifest standard: https://www.w3.org/TR/appmanifest/ Extensions Registry: https://github.com/w3c/manifest/wiki/Extensions-Registry


    Comments

    MDN documentation says

    PWA manifests include its name, author, icon(s), version, description, and list of all the necessary resources (among other things).

    DD: I can't find a specific way to add author info except for adding it as a part of another member (for example, at the end of description member). Because of this, I am defining the author member in this document.

    Copyright

    Contracts

    Introduction

    The smart contract language of the æternity blockchain is Sophia. It is a functional language in the ML family, strongly typed and has restricted mutable state.

    Before interacting with contracts using the SDK you should get familiar with Sophia itself first. Have a look into aepp-sophia-examples and start rapid prototyping using AEstudio.

    1. Specify imports

    2. Setup compiler

    Compiler primarily used to generate bytecode to deploy a contract. Skip this step if you have a contract bytecode or need to interact with an already deployed contract. Out-of-the-box SDK supports and implemented in and respectively.

    CompilerCli is available only in Node.js and requires Erlang installed (escript available in $PATH), Windows is supported.

    CompilerHttp requires a hosted compiler service. Preferable to host your own compiler service since is planned to be decommissioned. An example of how to run it using .

    Both compiler classes implement the that can be used to generate bytecode and ACI without a Contract instance.

    3. Create an instance of the SDK

    When creating an instance of the SDK you need to provide an account which will be used to sign transactions like ContractCreateTx and ContractCallTx that will be broadcasted to the network.

    Note:

    • You can provide multiple accounts to the SDK.

    • For each transaction you can choose a specific account to use for signing (by default the first account will be used), see .

      • This is specifically important and useful for writing tests.

    4. Initialize the contract instance

    To do so, we need to prepare an options object, which can be done in multiple ways.

    By source code

    Note:

    • If your contract includes external dependencies which are not part of the you should initialize the contract using:

    By path to source code (available only in Node.js)

    It can be used with both CompilerCli and CompilerHttp. This way contract imports would be handled automatically, with no need to provide fileSystem option.

    By ACI and bytecode

    If you pre-compiled the contracts you can also initialize a contract instance by providing ACI and bytecode:

    By ACI and contract address

    In many cases an application doesn't need to deploy a contract or verify its bytecode. In this case you'd want to initialize the instance by just providing the ACI and the contract address. This is also possible:

    Create contract instance

    Do it by Contract::initialize.

    AeSdk:getContext is used to get base options to instantiate contracts. These options include the current account, node, and compiler. They are referenced using Proxy class, pointing to the latest values specified in AeSdk. So, if you change the selected node in the AeSdk instance, it will be also changed in bound contract instances.

    Options

    • Following attributes can be provided via options to Contract::initialize:

      • aci (default: obtained via onCompiler)

    Keep bytecode and ACI for future use

    After the contract is initialized you can persist values of contract._aci and contract.$options.bytecode. They can be provided for subsequent contract initializations to don't depend on a compiler.

    5. Deploy the contract

    If you have a Sophia contract source code that looks like this:

    The contract can be deployed using the contract in two different ways:

    Note:

    • Deployment is only possible if the contract instance was initialized by providing source code or bytecode.

    • The init entrypoint is a special function which is only called once for deployment, initializes the contract's state and doesn't require the stateful declaration.

    • In Sophia all public functions are called entrypoints and need to be declared as stateful

    6. Call contract entrypoints

    a) Stateful entrypoints

    According to the example above you can call the stateful entrypoint increment by using one of the following lines:

    Note:

    • The callStatic: false option provide an explicit way to tell the SDK to sign and broadcast the transaction.

    • When using the increment function directly the SDK will automatically determine if it's a stateful entrypoint.

    b) Regular entrypoints

    The æternity node can expose an API endpoint that allows to execute a dry-run for a transaction. You can make use of that functionality to get the result of entrypoints that don't execute state changes. Following lines show how you can do that using the SDK for the get_count entrypoint of the example above:

    Note:

    • The callStatic option provide an explicit way to tell the SDK to perform a dry-run and to NOT broadcast the transaction.

    • When using the get_count function directly the SDK will automatically determine that the function is not declared stateful and thus perform a dry-run, too.

    c) Payable entrypoints

    You will probably also write functions that require an amount of aettos to be provided. These functions must be declared with payable and (most likely) stateful. Let's assume you have declared following Sophia entrypoint which checks if a required amount of aettos has been provided before it continues execution:

    In order to successfully call the fund_project entrypoint you need to provide at least 50 aettos. You can do this by providing the desired amount of aettos using one of the following lines:

    Transaction options

    As already stated various times in the guide it is possible to provide as object to a function of the SDK that builds and potentially broadcasts a transaction. This object can be passed as additional param to each of these functions and overrides the default settings.

    Sophia datatype cheatsheet

    Sometimes you might wonder how to pass params to the JavaScript method that calls an entrypoint of your Sophia smart contract. The conversion between JS and Sophia values is handled by aepp-calldata library. Refer to to find the right type to use.

    Generate file system object in Node.js

    To do so you can use function. In most cases, you don't need to do it explicitly. Prefer to use sourceCodePath instead sourceCode in, and instead in CompilerBase.

    AEX 1

    Simple Summary

    This document describes the process a proposal has to go through in order to be accepted into the AEX repository.

    Motivation

    The purpose of AEXs is to provide high quality and accessible specifications to be used when developing applications on top of Aeternity. We intend AEXs to be the primary mechanisms for proposing new standards, for collecting community technical input on an issue, and for documenting the design decisions. Because the AEXs are maintained as text files in a versioned repository, their revision history is the historical record of the feature proposal.

    Migration to 12.0.0

    This guide describes all breaking changes introduced with v12.0.0.

    General

    Universal

    Migration to 10.0.0

    This guide describes all breaking changes introduced with v10.0.0.

    pollForQueryResponse returns response as string ()

    • replace oldResult.decode

    $ aecli
    Usage: aecli [options] [command]
    
    Options:
      -V, --version                                 output the version number
      -h, --help                                    display help for command
    
    Commands:
      account                                       handle wallet operations
      spend [options] <wallet> <receiver> <amount>  send coins to another account or contract
      name                                          manage AENS names
      contract                                      contract interactions
      oracle                                        interact with oracles
      chain                                         make a request to the node
      inspect [options] <identifier>                get details of a node entity
      tx                                            generate transactions to sign and submit manually
      config [options]                              print the current sdk configuration
      select-node [nodeUrl]                         specify node to use in other commands
      select-compiler [compilerUrl]                 specify compiler to use in other commands
      help [command]                                display help for command
    $ aecli account create ./wallet.json
    Address  ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    Path     /path/to/wallet.json
    $ aecli inspect ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    Account ID       ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    Account balance  10000ae
    Account nonce    0
    No pending transactions
    $ aecli spend ./wallet.json ak_AgV756Vfo99juwzNVgnjP1gXX1op1QN3NXTxvkPnHJPUDE8NT 42ae
    Transaction mined
    Transaction hash   th_2muLsbZeFaVJ3tePTnLqobPhxBzwFsm1zUv8sjgMX4LKuevX2T
    Block hash         mh_dnoULQWpiRtcrntd5yJPUxcu7YrTu18xZ1e9EC2b8prKdShME
    Block height       2 (about now)
    Signatures         ["sg_SG5uW5KEGiy5iG1cCkKq4VEdpyvewcW4NjVf4vj2ZoCiap5iB7UQoknWpyWsD4FkziBuGPE88zwXemq3ZvPrdzNtXtKuD"]
    Transaction type   SpendTx (ver. 1)
    Sender address     ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    Recipient address  ak_AgV756Vfo99juwzNVgnjP1gXX1op1QN3NXTxvkPnHJPUDE8NT
    Amount             42ae
    Payload            ba_Xfbg4g==
    Fee                0.00001684ae
    Nonce              1
    TTL                4 (about now)
    AEX: 130
    Title: æpps Meta Information Format
    Author: Stoyan Vasilev (@j28), Denis Davidyuk (@davidyuk)
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aexpansion-proposal-aepps-metadata-format-specification/3987/9
    Status: Draft
    Type: Meta
    Created: 2019-07-09

    aeternity Developer Tools

    aeternity User Tools

    bid
    update
    extend
    revoke
    transfer
    call
    deploy
    respond-query
    play
    broadcast
    name-update
    name-transfer
    name-revoke
    contract-deploy
    contract-call
    oracle-register
    oracle-extend
    oracle-post-query
    oracle-respond
    verify
    The Contract ACI.
  • address

    • The address where the contract is located at.

    • To be used if a contract is already deployed.

  • fileSystem (default: {})

    • Key-value map with name of the include as key and source code of the include as value.

  • validateBytecode (default: false)

    • Compare source code with on-chain version.

  • other transaction options which will be provided to every transaction that is initiated using the contract instance. You should be aware that:

    • For most of these additional options it doesn't make sense to define them at contract instance level.

    • You wouldn't want to provide an amount to each transaction or use the same nonce which would result in invalid transactions.

    • For options like ttl or gasPrice it does absolutely make sense to set this on contract instance level.

  • if they should produce changes to the state of the smart contract, see
    increment(value: int)
    .
    aesophia_cli
    aesophia_http
    CompilerCli
    CompilerHttp
    compiler.aepps.com
    docker-compose
    same interface
    transaction options
    standard library
    transaction options
    its documentation
    getFileSystem
    Contract::initialize
    compile
    compileBySourceCode
    ,
    RpcAepp
    ,
    RpcWallet
    ,
    Ae
    stamps are removed

    Use AeSdk, AeSdkAepp, AeSdkWallet, AeSdbBase accordingly. For example:

    Node, RpcClient, BrowserWindowMessage classes are using private fields

    Accessing private fields through Proxy will lead to "TypeError: attempted to set private field on non-instance" (tc39). This may be an issue if you are using aepp-sdk with Vue@3, because Vue@3 introduced reactivity based on Proxy class (Vue docs). Avoid the above error by not making instances of these classes reactive.

    all combined exports are inlined (require('@aeternity/aepp-sdk').generateKeyPair())

    Import the needed utils directly instead of importing a wrapper object firstly. For example:

    AccountBase and inheritors are classes now

    Use new to create an instance.

    ChainNode, Contract, Oracle, Aens, GeneralizedAccount stamps not exported

    Their methods exported instead. Outside of AeSdkBase context, they may accept onAccount,onNode, onCompiler options.

    Node and Compiler

    Node, Compiler (previously ContractCompilerHttp) are classes instead of a stamps

    For example:

    Node, Compiler doesn't check version on the first request instead of init

    Don't handle new Node(...) and new Compiler(...) as a Promise.

    getNetworkId returns a promise

    getNetworkId ignores force option

    So, it would throw exception in case networkId is not provided. Use try/catch instead.

    api is removed in Node

    Use node.getBalance instead of node.api.getBalance.

    static properties are removed in Node

    Use node.getStatus() or node.getNodeInfo() to get values of version, revision,genesisHash, nodeNetworkId, consensusProtocolVersion.

    Node returns BigInts for coin amount fields instead of string or number

    Node not accepts internalUrl

    Node doesn't accepts and stores internalUrl, also internal endpoints are not available anymore. If necessary, create a wrapper of internal API separately (swagger-client package).

    removed mempool method in Node

    Create a wrapper of internal API by genSwaggerClient and use getPendingTransactions method instead.

    compilerVersion is removed in Compiler

    Use compilerApi.aPIVersion() method instead.

    setCompilerUrl changes compiler URL in sync

    Don't handle aeSdk.setCompilerUrl(...) as a Promise.

    methods of Compiler requires options object according to their specification

    methods of Compiler returns and accepts keys named in camelCase instead of snake_case

    Transaction builder

    removed methods to generate a transaction of specific type

    Use aeSdk.buildTx(txType, params) instead.

    removed ability to generate transaction on the node side

    Use aeSdk.buildTx(txType, params) instead.

    nonce, ttl, gas decoded and accepted as numbers instead of strings

    gas renamed to gasLimit

    Use gasLimit instead of gas everywhere except for transaction details returned by node.

    unpackTx not accepting transaction as Buffer, only as tx-encoded string

    Use unpackTx(encode(tx, 'tx')) instead.

    unpackTx doesn't have binary field in result

    Use require('rlp').decode(unpackTx(tx).rlpEncoded) instead.

    encode: since the prefix is evaluated by the type itself the required prefix parameter

    is no more accepted For example:

    calculateMinFee returns BigNumber instead of string

    Fee helpers not exported anymore (BASE_GAS, GAS_PER_BYTE, KEY_BLOCK_INTERVAL,

    TX_FEE_BASE_GAS, TX_FEE_OTHER_GAS, calculateFee, DEFAULT_FEE) Use a general calculateMinFee instead.

    buildRawTx, calculateTtl not exported anymore

    Use a general buildTx method instead.

    TX_TYPE mapped to tag (number) instead of string

    Always use TX_TYPE. To get type name by tag use TX_TYPE[tag].

    OBJECT_ID_TX_TYPE not exported anymore

    Use TX_TYPE[tag] instead.

    TX_SERIALIZATION_SCHEMA combined with TX_DESERIALIZATION_SCHEMA

    Use TX_SCHEMA[TX_TYPE.*] instead.

    Transaction schemas doesn't contain tag anymore

    Use OBJECT_ID_TX_TYPE to find tag by transaction type.

    AENS

    computeBidFee accepts startFee, increment as options

    NAME_BID_TIMEOUTS not exposed anymore

    Use computeAuctionEndBlock function instead.

    computeAuctionEndBlock accepts and returns height as number

    removed ensureNameValid

    Use a TypeScript check instead.

    name.update, name.revoke doesn't accept address in onAccount

    Pass an instance of AccountBase to onAccount option instead.

    Oracle

    extendOracleTtl accepts oracle ttl in oracleTtlType and oracleTtlValue fields

    Use oracleTtlType field instead of type, and oracleTtlValue field instead of value.

    decode method of getQueryObject removed

    Use decode function instead.

    Contract

    createAensDelegationSignature first argument not an object

    contractId accepted as the first argument, name should be passed as option to the second one.

    createOracleDelegationSignature first argument not an object

    contractId accepted as the first argument, queryId should be passed as option to the second one.

    call arguments in createGeneralizedAccount is required

    Pass an empty array if you need no arguments.

    filesystem option renamed to fileSystem

    Contract instance doesn't accept address in onAccount

    It should be an instance of AccountBase instead.

    Chain

    removed balance method

    Use getBalance instead.

    removed tx method

    Use node.getTransactionByHash/getTransactionInfoByHash instead.

    removed getTxInfo method

    Use node.getTransactionInfoByHash instead.

    Other

    getAccountNonce removed

    Use node.getAccountNextNonce instead.

    AeSdk doesn't accept array of accounts

    Use aeSdk.addAccount method instead.

    destroyInstance method removed

    It wasn't doing anything, just remove it's usages.

    NodePool is removed

    Use AeSdkBase or AeSdk instead.

    AccountMultiple is removed

    Use AeSdk instead.

    DENOMINATION_MAGNITUDE not exposed anymore

    It is intended for internal use only.

    The result of unpackTx returned instead of TxObject

    In txObject option of onSign handler on wallet side. In tx field of contract call result.

    validateKeyObj removed

    Rely on TypeScript checks instead.

    deriveKeyUsingArgon2id removed

    Use argon2-browser package instead.

    removed extra implementation of getAddressFromPriv in keystore

    Use Crypto.getAddressFromPriv instead.

    genSwaggerClient removed

    Use swagger-client package instead.

    Aepp Wallet communication

    BrowserRuntimeConnection, BrowserWindowMessageConnection are classes

    Create instances using new.

    ContentScriptBridge, WalletDetector rewrited to plain functions

    Use connectionProxy, walletDetector accordingly.

    RpcClient: removed origin property

    Use connection property instead.

    RpcClient: sendMessage is a private method

    Use request or notify instead.

    RpcClient: handlers parameter is removed

    Provide a methods parameter instead of handlers[0]. Provide an onDisconnect parameter instead of handlers[1].

    RpcClient: doesn't contain aepp info anymore

    Get aepp info in onConnection callback, and store somehow to use later.

    RpcClient: doesn't contain networkId anymore

    On wallet side: assume that all aepps uses the same network as the wallet connected to. On aepp side: use networkId that wallet provided. In case networkId is not compatible ask user to switch wallet to a compatible network.

    RPC helpers are not exposed anymore (isInIframe, sendMessage, getHandler, message,

    responseMessage, sendResponseMessage, isValidAccounts) Use own implementation if needed.

    Aepp

    connectToWallet accepts wallet connection as the first argument

    See connect-aepp-to-wallet.md for details.

    disconnectWallet runs in sync and sendDisconnect arg removed

    So, aepp would always send closeConnection notification.

    sendConnectRequest removed

    Use connectToWallet instead.

    doesn't accept connection anymore

    Use connectToWallet method instead.

    removed isConnected, isSubscribedAccount methods

    Detect is aepp connected by persistence of rpcClient property.

    signMessage returns Buffer by default

    Use returnHex option to get the previous behaviour.

    Wallet

    BrowserRuntimeConnection requires port parameter

    Pass require('webextension-polyfill').runtime.connect() to it.

    requires id, type in params

    id should be a unique string;type should be one of WALLET_TYPE.window, WALLET_TYPE.extension.

    getBrowserAPI helper removed

    Use webextension-polyfill package instead.

    shareWalletInfo accepts rpc client id instead of callback

    For example:

    shareNode argument in accept callback of onConnection removed

    Just deny the connection if you don't want to share the node url.

    can't handle specific set of accounts for an app

    If you need this feature, create a custom wallet implementation or fill us an issue.

    txObject parameter of onSign callback is removed

    Use unpackTx(tx) on wallet side instead.

    rpcClients in wallet is not exposed anymore

    This expected to be used only internally.

    onDisconnect callback on wallet side accepts client id instead of RpcClient

    Use sdk.rpcClient[clientId] to get the corresponding instance of RpcClient.

    wallet can't selectively notify aepps about selecting/adding account

    If you need this feature, create a custom wallet implementation or fill us an issue.

    wallet can't provide metadata for accounts

    If you need this feature, create a custom wallet implementation or fill us an issue.

    removed action.accept in permission callbacks

    Return the value you passed to accept instead.

    removed action.deny in permission callbacks

    Throw instances of RpcRejectedByUserError instead.

    callbacks accept client id, params, and origin

    with
    new Buffer(newResult)
    .
  • replace oldResult.response with TxBuilderHelper.encode(new Buffer(newResult), 'or').

  • removed skipArgsConvert option of contract call and deployment (6d4a599)

    Convert arguments in intermediate Sophia representation to JavaScript types. For example:

    rewrite to

    removed skipTransformDecoded option of contract call and deployment (bb49239)

    Decoding to JavaScript types is enforced, please use it instead.

    ak_ addresses are not accepted as hashes, bytes, and signatures anymore (cbaac62)

    Encode addresses as an ak_-prefixed string instead.

    removed contractEncodeCall (a4b303f)

    Use contractEncodeCallDataAPI instead.

    removed contractDecodeData (5df2285)

    Use contractDecodeCallResultAPI instead.

    removed setOptions on contract instance (b88e767)

    Pass them through getContractInstance options instead.

    contractCallStatic, contractCall, contractDeploy are deprecated now (c4ec019)

    Use getContractInstance instead. Also, these methods will accept JavaScript-type variables instead of Sophia-encoded. For example:

    should be replaced with

    dropped compatibility with [email protected] (f9cef12)

    Use compiler 6.0.0 and above.

    invert and rename forceCodeCheck option to validateBytecode in getContractInstance (72122fa)

    Use validateBytecode when you need to ensure that the source code/bytecode provided togetContractInstance corresponds to the on-chain bytecode.

    removed getConsensusProtocolVersion method (75f0447)

    Use node.consensusProtocolVersion instead.

    switched to @aeternity/aepp-calldata package (#1313)

    Numbers in Sophia are not limited in size. Before they were returned from contract methods as usual JavaScript numbers that have limited accuracy. To fix this, we make it return instances of BigInt.

    Variant types are now supported by sdk, so replace "RelativeTTL(50)" with { RelativeTTL: [50] }. As an exception Some(value) is converted to the exact value in JavaScript and None is converted to undefined (Sophia's option type).

    Contract methods will accept/return instances of JavaScript's Map as variables of Sophia's map type. Objects are not accepted as maps any longer.

    Sophia's hash, signature, bytes types return values as Uint8Array instead of a hex-encoded string.

    Check the documentation of calldata package for additional info.

    Use .decodedResult instead of .decode() to get the result of method call.

    Most of the errors thrown by contract iterations will be different due to doing validation using calldata package instead of joi.

    pass source in options of sdk.getContractInstance (5c690d2)

    For example:

    rewrite to

    Contract instance can be generated by ACI and bytecode:

    SDK won't use hosted compiler in this case.

    Also, contract.compiled was renamed to contract.bytecode.

    additional options of getContractInstance accepted as usual ones (10fb7ba)

    For example, replace

    with

    drop compatibility with es5 (#1331)

    To support old environments, you need to set up transpilation of SDK package while building your app. In Webpack it can be done by excludingnode_modules folder except for this package in babe-loader rule. In @vue/cli you can usetranspileDependencies option.

    removed primitives for encryption/decryption by keypairs (#1183)

    Use third-party cryptographic packages instead of Crypto.encryptData, Crypto.decryptData methods.

    aensUpdate accepts pointers as object (f6b8999)

    For example, replace

    with

    Additionally, getDefaultPointerKey (was named classify before) helper function can be used

    #1285
    // node.js import
    const { AeSdk, AccountMemory, Node } = require('@aeternity/aepp-sdk');
    // ES import
    import { AeSdk, AccountMemory, Node } from '@aeternity/aepp-sdk';
    // additionally you may need to import CompilerCli or CompilerHttp
    const compiler = new CompilerCli();
    const compiler = new CompilerHttp('https://v8.compiler.aepps.com'); // host your own compiler
    const node = new Node('https://testnet.aeternity.io'); // ideally host your own node
    const account = new AccountMemory(SECRET_KEY);
    
    const aeSdk = new AeSdk({
      nodes: [{ name: 'testnet', instance: node }],
      accounts: [account],
      onCompiler: compiler, // remove if step #2 skipped
    });
    const sourceCode = ... // source code of the contract
    const options = { sourceCode }
    const fileSystem = ... // key-value map with name of the include as key and source code of the include as value
    const options = { sourceCode, fileSystem }
    const sourceCodePath = './example.aes';
    const options = { sourceCodePath };
    const aci = ... // ACI of the contract
    const bytecode = ... // bytecode of the contract
    const options = { aci, bytecode }
    const aci = ... // ACI of the contract
    const address = ... // the address of the contract
    const options = { aci, address }
    const contract = await Contract.initialize({ ...aeSdk.getContext(), ...options });
    contract Increment =
    
        record state =
            { count: int }
    
        entrypoint init(start: int) =
            { count = start }
    
        stateful entrypoint increment(value: int) =
            put(state{ count = state.count + value })
    
        entrypoint get_count() =
            state.count
    const tx = await contract.$deploy([1]);
    // or
    const tx = await contract.init(1);
    
    // after successful deployment you can look up the transaction and the deploy information
    console.log(tx); // { owner, transaction, address, result, rawTx }
    const tx = await contract.increment(3); // recommended
    // or
    const tx = await contract.increment(3, { callStatic: false });
    // or
    const tx = await contract.$call('increment', [3]);
    const tx = await contract.get_count(); // recommended
    // or
    const tx = await contract.get_count({ callStatic: true });
    
    // access the decoded result returned by the execution of the entrypoint
    console.log(tx.decodedResult);
    payable stateful entrypoint fund_project(project_id: int) =
            require(Call.value >= 50, 'at least 50 aettos need to be provided')
            // further logic ...
    const tx = await contract.fund_project(1, { amount: 50 }); // recommended
    // or
    const tx = await contract.$call('fund_project', [1], { amount: 50 });
    -import { Universal } from '@aeternity/aepp-sdk'
    +import { AeSdk } from '@aeternity/aepp-sdk'
    
    -const aeSdk = await Universal(options)
    +const aeSdk = new AeSdk(options)
    -import { Crypto } from '@aeternity/aepp-sdk'
    +import { generateKeyPair } from '@aeternity/aepp-sdk'
    
    -console.log(Crypto.generateKeyPair())
    +console.log(generateKeyPair())
    import { Node } from '@aeternity/aepp-sdk'
    
    -const node = await Node({ url, ignoreVersion: false })
    +const node = new Node(url, { ignoreVersion: false })
    -decode('cb_DA6sWJo=', 'cb')
    +decode('cb_DA6sWJo=')
    const connection = new BrowserRuntimeConnection({ port })
    -aeSdk.addRpcClient(connection)
    -aeSdk.shareWalletInfo(port.postMessage.bind(port))
    +const rpcClientId = aeSdk.addRpcClient(connection)
    +aeSdk.shareWalletInfo(rpcClientId)
    contract.methods.listFn('[1, 2]', { skipArgsConvert: false });
    contract.methods.listFn([1, 2]);
    sdk.contractCallStatic(source, address, methodName, ['42']);
    sdk.contractCallStatic(source, address, methodName, [42]);
    sdk.getContractInstance(contractSource, { contractAddress: '...' });
    sdk.getContractInstance({ source: contractSource, contractAddress: '...' });
    sdk.getContractInstance({ aci, bytecode });
    sdk.getContractInstance({ source, opt: { ttl: 1 } });
    sdk.getContractInstance({ source, ttl: 1 });
    sdk.aensUpdate('test.chain', ['ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk']);
    sdk.aensUpdate('test.chain', {
      account_pubkey: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
    });
    import { getDefaultPointerKey } from '@aeternity/aepp-sdk';
    
    const address = 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk';
    sdk.aensUpdate('test.chain', { [getDefaultPointerKey(address)]: address });

    Specification

    AEX Types

    There are three types of AEXs:

    • A Standards Track AEX describes any change or addition that affects the interoperability of applications using Aeternity. Standards Track AEXs consist of two parts: a design document and a reference implementation.

    • An Informational AEX describes a design issue, or provides general guidelines or information to the Aeternity community, but does not propose a new feature. Informational AEXs do not necessarily represent an Aeternity community consensus or recommendation, so users and implementors are free to ignore Informational AEXs or follow their advice.

    • A Meta AEX describes a process surrounding AEXs or proposes a change to (or an event in) a process. They often require community consensus; unlike Informational AEXs, they are more than recommendations, and users are typically not free to ignore them. Examples include procedures, guidelines, changes to the decision-making process, and changes to the tools or environment used in Aeternity development.

    Workflow

    Parties involved in the process are you, the champion or AEX author and the AEX editors.

    ⚠️ Before you begin, vet your idea, this will save you time. Ask the Aeternity community first if an idea is original to avoid wasting time on something that will be be rejected based on prior research (searching the Internet does not always do the trick). It also helps to make sure the idea is applicable to the entire community and not just the author. Just because an idea sounds good to the author does not mean it will work for most people in most areas where Aeternity is used. Examples of appropriate public forums to gauge interest around your AEX include the Aeternity forums and the issues section of this repository. In particular, the issues section of this repository is an excellent place to discuss your proposal with the community and start creating more formalised language around your AEX.

    Your role as the champion is to write the AEX using the style and format described below, shepherd the discussions in the appropriate forums, and build community consensus around the idea.

    Stages

    Stage
    Purpose
    Entrance Criteria
    Changes Expected

    Draft

    rapid iteration in small/focused working group

    none

    major

    Review

    review and feedback from editor and other interested parties

    initial specification, editor assigned, template filled, authors and editor consider document to be in a state where the general public can give constructive feedback

    no major TODOs left

    Last call (yyyy-mm-dd to yyyy-mm-dd)

    indicate that authors and editors consider document to be complete; solicit last round of feedback

    at least one working implementation (if applicable), authors and editors deem the proposal complete

    Each status change is requested by the AEX author and reviewed by the AEX editors. Use a pull request to update the status.

    AEXs should be changed from Draft or Review status, to Rejected status, upon request by any person, if they have not made progress in three years. Such a AEX may be changed to Draft status if the champion provides revisions that meaningfully address public criticism of the proposal, or to Review status if it meets the criteria required as described in the previous paragraph.

    The transition from Last Call to either Final or Active happens automatically if during the last call period, typically 14 days, no substantiated objections are voiced or left unaddressed.

    A Last Call which results in material changes or substantial unaddressed technical complaints will cause the AEX to revert to Review.

    Transferring AEX Ownership

    It occasionally becomes necessary to transfer ownership of AEXs to a new champion. In general, we'd like to retain the original author as a co-author of the transferred AEX, but that's really up to the original author. A good reason to transfer ownership is because the original author no longer has the time or interest in updating it or following through with the AEX process, or has fallen off the face of the 'net (i.e. is unreachable or isn't responding to email). A bad reason to transfer ownership is because you don't agree with the direction of the AEX. We try to build consensus around an AEX, but if that's not possible, you can always submit a competing AEX.

    If you are interested in assuming ownership of an AEX, send a message asking to take over, addressed to both the original author and the AEX editor. If the original author doesn't respond to email in a timely manner, the AEX editor will make a unilateral decision (it's not like such decisions can't be reversed :).

    Editors

    For each new AEX that comes in, an editor does the following:

    • Read the AEX to check if it is ready: sound and complete. The ideas must make technical sense, even if they don't seem likely to get to final status.

    • The title should accurately describe the content.

    • Check the AEX for language (spelling, grammar, sentence structure, etc.), markup (Github flavoured Markdown), code style

    If the AEX isn't ready, the editor will send it back to the author for revision, with specific instructions.

    Once the AEX is ready for the repository, the editor will:

    • Assign an AEX number (generally the PR number or, if preferred by the author, the issue # if there was discussion in the issues section of this repository about this AEX)

    • Merge the corresponding pull request

    • Send a message back to the AEX author with the next step.

    In general, the editors:

    • Don't pass judgment on AEXs.

    • Are intended to fulfil administrative and editorial responsibilities.

    • Monitor AEX changes, and update AEX headers as appropriate.

    List of editors

    • Sascha Hanse (@knarz)

    • Philipp Piwowarsky (@thepiwo)

    Format

    Successful AEXs should contain most of the following sections:

    • Preamble: RFC 822 style headers containing metadata about the AEX

    • Simple Summary: a simplified and layman-accessible explanation of the AEX

    • Abstract: a short (~200 word) description of the (technical) issue being addressed

    • Motivation: clearly explaining why the existing standards are inadequate to address the problem that the AEX solves

    • Specification: should describe the syntax and semantics of any new feature and should be detailed enough to allow competing, interoperable implementations

    • Rationale: fleshes out the specification by describing what motivated the design and why particular design decisions were made. It should describe alternate designs that were considered and related work, e.g. how the feature is supported in other languages. The rationale may also provide evidence of consensus within the community, and should discuss important objections or concerns raised during discussion.

    • Backwards Compatibility: if a proposal is supposed to supersede another proposal without providing backwards compatibility then it should contain a section describing these incompatibilities and their severity. Further, it should explain how the author proposes to deal with these incompatibilities.

    • Test Cases: links to test cases if applicable

    • Implementations: implementation or link to implementations, if applicable

    A AEX template can be found under AEX-X.

    Preamble

    Each AEX must begin with an RFC 822 style header preamble. The headers must appear in the following order. Headers marked with "*" are optional and are described below. All other headers are required.

    Header fields permitting lists must separate elements with commas.

    The Discussions-To field should point to a discussion of the proposed standard. Most of the initial work should happen in small, focused working groups and only posted once it is in a reasonably stable state. Please try to refrain from having WIP documents or very early drafts in this repository as they tend orphan.

    Each proposal must start in the Draft state and will move through the phases in accordance to the criteria defined in this document.

    If a proposal depends on another AEX, the Requires field should indicate so.

    Superseded-By, Replaces, Updates and Updated-By fields are required since standards are in constant flux. Editors and authors should make sure that old AEXs are update where appropriate.

    Copyright

    The following recommended licenses should be used both for code and the specification:

    • BSD-2-Clause

    • BSD-3-Clause

    • CC0-1.0

    • GNU-All-Permissive

    Each submitted proposal needs to list at least one license. If code is included, a separate license for it can be specified. The licenses should be included in the header via the License and License-Code fields. If those fields do not cover the requirements, include a copyright section in your proposal.

    Or with multiple licenses:

    Other acceptable licenses:

    • ISC: Internet Systems Consortium License

    • Apache-2.0: Apache License, version 2.0

    • MIT: Expat/MIT/X11 license

    • AGPL-3.0+: GNU Affero General Public License (AGPL), version 3 or newer

    • FDL-1.3:

    • GPL-2.0+:

    • LGPL-2.1+:

    References

    Many parts of this document are inspired by or adapted with only minor modifications from many of the already existing standardisation processes.

    • EIP-1

    • BIP-2

    • TC39

    • The Internet Standards Process

    https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/StoreAeSdkPlugin.js#L34-L49
    https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/Connect.vue#L66-L85

    aex-9

    AEX 9

    Simple Summary

    This document aims to outline a standard and define how fungible tokens should be created and used on aeternity blockchain.

    https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/node/_api-high-level.js#L1-L18
    AEX: 1
    Title: AEX process
    Author: Sascha Hanse <[email protected]>
    License: CC0-1.0
    Discussions-To: https://forum.aeternity.com/t/aeternity-best-current-practices-aexpansions/2461
    Status: Active
    Type: Meta
    Created: 2019-02-01
    +---------------+             +---------------+             +---------------+
    |     Draft     |------------>|     Review    |<----------->|   Last call   |
    +---------------+             +---------------+             +---------------+
           ^      |                 |     ^                       |   |   |   |
           |      v                 |     |                       |   |   |   |
           |  +---------------+     |     |                       |   |   |   |
           |  |   Withdrawn   |<----+-----|-----------------------+   |   |   |
           |  +---------------+           |                           |   |   |
           v                              |                           |   |   |
    +---------------+                     |                           |   |   |
    |    Rejected   |<--------------------+---------------------------+   |   |
    +---------------+                                    -----------------+   |
                                                         |                    |
                                                         v                    v
              +---------------+             +---------------+    +---------------+
              |    Updated    |<----------->|     Final     |    |     Active    |
              +---------------+             +---------------+    +---------------+
                      |                             |
                      +----------+       +----------+
                                 |       |
                                 v       v
                             +---------------+
                             |   Superseded  |
                             +---------------+
    AEX: <to be assigned by editors>
    Title: <AEX title>
    Author: <a list of the author's or authors' name(s) and/or username(s), or name(s) and email(s), e.g. (use with the parentheses or triangular brackets): FirstName LastName (@GitHubUsername), FirstName LastName <[email protected]>, FirstName (@GitHubUsername) and GitHubUsername (@GitHubUsername)>
    License: <license names, abbreviated>
    License-Code (*optional): <license names, abbreviated>
    Discussions-To: <URL>
    Status: <Draft | Active Review | Last Call (yyyy-mm-dd to yyyy-mm-dd) | Final | Updated | Superseded | Rejected | Withdrawn>
    Type: <Standards Track | Informational | Meta>
    Created: <date created on, in ISO 8601 (yyyy-mm-dd) format>
    Requires (*optional): <AEX number(s)>
    Replaces (*optional): <AEX number(s)>
    Superseded-By (*optional): <AEX number(s)>
    Updates (*optional): <AEX number(s)>
    Updated-By (*optional): <AEX number(s)>
    License: CC0-1.0
    License-Code: Apache-2.0
    License: CC0-1.0
             BSD-3-Clause
    License-Code: Apache-2.0
            aeSdk = new AeSdkAepp({
              name: 'Simple æpp',
              nodes: [
                { name: 'testnet', instance: new Node(TESTNET_NODE_URL) },
                { name: 'mainnet', instance: new Node(MAINNET_NODE_URL) },
              ],
              compilerUrl: COMPILER_URL,
              onNetworkChange: async ({ networkId }) => {
                const [{ name }] = (await aeSdk.getNodesInPool())
                  .filter((node) => node.nodeNetworkId === networkId);
                aeSdk.selectNode(name);
                commit('setNetworkId', networkId);
              },
              onAddressChange: ({ current }) => commit('setAddress', Object.keys(current)[0]),
              onDisconnect: () => alert('Aepp is disconnected'),
            });

    minor

    Final

    proposal is considered to be completed

    no unaddressed substantiated objections are left

    crucial or cosmetic updates only

    Active

    proposal can be in constant flux

    no unaddressed substantiated objections are left

    crucial or cosmetic updates only

    Updated

    signalling that an updating standard might have to be considered

    an updating proposal entered the Final state

    crucial or cosmetic updates only

    Superseded

    standard should no longer be used

    community consensus around a superseding proposal

    none

    Rejected

    editors deemed this proposal to be unworkable

    proposal was rejected before, authors were unwilling to respond to feedback, too unfocused, too broad, duplication of effort, being technically unsound, not providing proper motivation or addressing backwards compatibility

    none

    Withdrawn

    signalling that the proposal is no longer relevant

    withdrawn by original authors

    none

    GNU Free Documentation License, version 1.3
    GNU General Public License (GPL), version 2 or newer
    GNU Lesser General Public License (LGPL), version 2.1 or newer
    Abstract

    The following standard allows for the implementation of a standard API for tokens within smart contracts. This standard provides basic functionality to transfer tokens, as well as allow tokens to be approved so they can be spent by another on-chain third party.

    Motivation

    This standard will allow decentralized applications and wallets to handle fungible tokens in a standardized way. A standard interface allows any tokens to be re-used by other applications, e.g. from wallets to decentralized exchanges.

    The provided specification is following the ERC20 standard introduced in Ethereum for fungible tokens. This standard is proven to be working, it will help with interoperability and easier developer onboarding as the main differences will be Sophia syntax related. Another goal with following the ERC20 standard, is to learn from its mistakes and not repeat them.

    The newly proposed standard should be easy to use but extendable with more functionality, both first and third party as shown by splitting allowance, minting, burning and swapping into optional extensions.

    Specification

    Basic Token

    Interface

    Methods

    aex9_extensions()

    This function returns a hardcoded list of all implemented extensions on the deployed contract.

    meta_info()

    This function returns meta information associated with the token contract.

    return
    type

    meta_info

    meta_info

    total_supply()

    This function returns the total token supply.

    return
    type

    total_supply

    int

    balances()

    This function returns the full balance state for static calls, e.g. by a blockchain explorer.

    return
    type

    balances

    map(address, int)

    balance()

    This function returns the account balance of another account with address owner, if the account exists. If the owner address is unknown to the contract None will be returned. Using option type as a return value allows us to determine if the account has balance of 0, more than 0, or the account has never had balance and is still unknown to the contract.

    parameter
    type

    owner

    address

    return
    type

    balance

    option(int)

    transfer()

    This function allows transfer of value amount of tokens to to_account address and MUST fire the Transfer event. The function SHOULD abort if the Call.caller's account balance does not have enough tokens to spend.

    Note: Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event.

    parameter
    type

    to_account

    address

    value

    int

    Events

    Transfer

    This event MUST be triggered and emitted when tokens are transferred, including zero value transfers.

    The transfer event arguments should be as follows: (from_account, to_account, value)

    parameter
    type

    from_account

    address

    to_account

    address

    value

    int

    Mint (optional if token creation happens) - MUST trigger when tokens are minted and thus are newly available in the given token contract, this also applies to tokens created using the init method on contract creation.

    The mint event arguments should be as follows: (account, value)

    parameter
    type

    account

    address

    value

    int

    Extensions

    This section covers the extendability of the basic token - e.g. mintable, burnable and allowances.

    When a token contract implements an extension its name should be included in the aex9_extensions array, in order for third party software or contracts to know the interface. Any extensions should be implementable without permission. Developers of extensions MUST choose a name for aex9_extensions that is not yet used. Developers CAN make a pull request to the reference implementation for general purpose extensions and maintainers choose to eventually include them.

    Extension Mintable ("mintable")

    mint()

    This function mints value new tokens to account. The function SHOULD abort if Call.caller is not the owner of the contract state.owner.

    parameter
    type

    account

    address

    value

    int

    Events

    Mint - MUST trigger when tokens are minted and thus are newly available in the given token contract, this also applies to tokens created using the init method on contract creation.

    The mint event arguments should be as follows: (account, value)

    parameter
    type

    account

    address

    value

    int

    Extension Burnable ("burnable")

    burn()

    This function burns value of tokens from Call.caller.

    parameter
    type

    value

    int

    Events

    Burn - MUST trigger when tokens are burned and thus are no longer available in the given token contact.

    The burn event arguments should be as follows: (account, value)

    parameter
    type

    account

    address

    value

    int

    Extension Allowance ("allowances")

    create_allowance()

    Allows for_account to withdraw from your account multiple times, up to the value amount. If this function is called again it overwrites the current allowance with value.

    Note: To prevent attack vectors (like the ones possible in ERC20) clients SHOULD make sure to create user interfaces in such a way that they set the allowance first to 0 before setting it to another value for the same spender. THOUGH the contract itself shouldn't enforce it, to allow backwards compatibility with contracts deployed before.

    parameter
    type

    for_account

    address

    value

    int

    transfer_allowance()

    Transfers value amount of tokens from address from_account to address to_account, and MUST fire the Transfer event.

    The transfer_allowance method is used for a withdraw workflow, allowing contracts to transfer tokens on your behalf. This can be used for example to allow a contract to transfer tokens on your behalf and/or to charge fees in sub-currencies. The function SHOULD abort unless the from_account account has deliberately authorized the sender of the message via some mechanism.

    Note: Transfers of 0 values MUST be treated as normal transfers and fire the Transfer event.

    parameter
    type

    from_account

    address

    to_account

    address

    value

    int

    allowance()

    This function returns the amount which for_account is still allowed to withdraw from from_account, where record allowance_accounts = { from_account: address, for_account: address }. If no allowance for this combination of accounts exists, None is returned.

    parameter
    type

    allowance_accounts

    allowance_accounts

    allowances()

    This function returns all allowances stored in state.allowances record.

    return
    type

    allowances

    map(allowance_accounts, int)

    allowance_for_caller()

    This function will look up the allowances and return the allowed spendable amount from from_account for the transaction sender Call.caller. If there is no such allowance present result is None, otherwise Some(int) is returned with the allowance amount.

    parameter
    type

    from_account

    address

    return
    type

    option(int)

    change_allowance()

    This function allows the Call.caller to change the allowed spendable value for for_account with value_change. This adds the value_change to the current allowance value. If used for increasing allowance amount a positive value should be passed, if the desired outcome is to lower the value of the allowed spendable value a negative value_change should be passed.

    parameter
    type

    for_account

    address

    value_change

    int

    return
    type

    unit

    reset_allowance()

    Resets the allowance given for_account to zero.

    parameter
    type

    for_account

    address

    return
    type

    unit

    Events

    Allowance - MUST trigger on any successful allowance creation or change.

    The approval event arguments should be as follows: (from_account, for_account, value)

    parameter
    type

    from_account

    address

    for_account

    address

    value

    int

    Extension Swappable ("swappable")

    swap()

    This function burns the whole balance of the Call.caller and stores the same amount in the swapped map.

    parameter
    type

    value

    int

    return
    type

    ()

    unit

    check_swap()

    This function returns the amount of tokens that were burned trough swap for the provided account.

    parameter
    type

    account

    address

    return
    type

    int

    int

    swapped()

    This function returns all swapped tokens that are stored in contract state.

    return
    type

    swapped

    map(address, int)

    Events

    Swap - MUST trigger when tokens are swapped and thus are no longer available in the given token contact.

    The swap event arguments should be as follows: (account, value)

    parameter
    type

    account

    address

    value

    int

    Implementation

    There are several implementations available at the moment, but they lack a thing or two (that is why this standard is being proposed).

    Example implementations:

    • (REFERENCE) Aeternity Sophia Fungible Token

    • (OUTDATED) Fungible token implementation example

    • (OUTDATED) ERC20 Sophia Translation

    References

    ERC-20ERC-20 attack vectors

    AEX: 9
    Title: Fungible Token Standard
    Author: @mradkov, @thepiwo
    License: ISC
    Discussions-To: https://forum.aeternity.com/t/aex-9-fungible-token/3565
    Status: Review
    Type: Standards Track
    Created: 2019-05-11
    contract interface FungibleTokenInterface =
      record meta_info =
        { name : string
        , symbol : string
        , decimals : int }
    
      datatype event =
        Transfer(address, address, int)
    
      entrypoint aex9_extensions : ()             => list(string)
      entrypoint meta_info       : ()             => meta_info
      entrypoint total_supply    : ()             => int
      entrypoint owner           : ()             => address
      entrypoint balances        : ()             => map(address, int)
      entrypoint balance         : (address)      => option(int)
      entrypoint transfer        : (address, int) => unit
    entrypoint aex9_extensions() : list(string)
    entrypoint meta_info() : meta_info
    record meta_info =
      { name     : string
      , symbol   : string
      , decimals : int }
    entrypoint total_supply() : int
    entrypoint balances() : map(address, int)
    entrypoint balance(owner: address) : option(int)
    stateful entrypoint transfer(to_account: address, value: int) : unit
    Transfer(address, address, int)
    Mint(address, int)
    stateful entrypoint mint(account: address, value: int) : unit
    Mint(address, int)
    stateful entrypoint burn(value: int) : unit
    Burn(address, int)
    stateful entrypoint create_allowance(for_account: address, value: int) : unit
    stateful entrypoint transfer_allowance(from_account: address, to_account: address, value: int)
    entrypoint allowance(allowance_accounts : allowance_accounts) : option(int)
    record allowance_accounts =
      { from_account: address
      , for_account: address }
    entrypoint allowances() : allowances
    entrypoint allowance_for_caller(from_account: address) : option(int)
    stateful entrypoint change_allowance(for_account: address, value_change: int)
    stateful entrypoint reset_allowance(for_account: address)
    Allowance(address, address, int)
    stateful entrypoint swap() : unit
    stateful entrypoint check_swap(account: address) : int
    stateful entrypoint swapped() : map(address, int)
    Swap(address, int)
    https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/node/_api-low-level.js#L1-L19

    Changelog

    1.5.0 (2025-04-30)

    Features

    • add package version to footer ()

    • enhance signature verification ()

    (2025-04-29)

    Features

    • integrate routing and add documentation and FAQ pages ()

    Bug Fixes

    • hydration error ()

    • undefined event definition errors ()

    (2025-04-29)

    Refactorings

    • extract walletNodes initialization to improve network handling in wallet-sdk ()

    (2025-04-28)

    Features

    • enhance network change handling to validate nodes in pool before selection ()

    • increase security on request verification & add cleanup, pause, resume functions ()

    Bug Fixes

    • improve network fetching logic and connection status handling in WalletProvider ()

    • update bridge contract addresses and operator account in network configurations ()

    • update string concatenation to use semicolons ()

    (2025-04-28)

    Features

    • update operator account address and improve balance fetching logic ()

    Bug Fixes

    • add warning message to prevent incorrect token bridging between networks ()

    • conditionally render action history based on network support ()

    • increase retry limit for fetching bridge transaction ()

    (2025-04-25)

    Features

    • improve transaction processing & fixes ()

    (2025-04-24)

    Bug Fixes

    • update condition to check for data length ()

    1.0.0 (2025-04-24)

    Features

    • add Aeternity SDK integration and update project configuration ()

    • add assets folder which includes global styles, logos, favicon, and font ()

    • add bridge configuration script and enhance deployment scripts with save option for ACI ()

    • add currency support to wallet management and update balance display ()

    Bug Fixes

    • adjust legend class names for consistent styling in form components ()

    • change ClockIcon stroke color ()

    • correct amount handling in create_token_link_and_mint function ()

    • include current network in bridge form component ()

    Refactorings

    • adjust margin and padding in bridge and connected view components for better layout consistency ()

    • bridge contract and tests ()

    • improve table layout and alert visibility in BridgeActionDetailsModal ()

    • monorepo ()

    Miscellaneous

    • add Dockerfile for application containerization and remove build script ()

    AENS (æternity naming system)

    Introduction

    This guide shows you how to perform all the operations that you need within the lifecycle of æternity naming system (AENS) using the SDK.

    If you successfully claimed a name it will expire after 180000 key blocks (~375 days). You will need to update your name before it expires!

    1. Claim a name

    Claiming an AENS name requires you (at least) 2 transactions:

    • First you need to perform a pre-claim by providing a commitmentId (hash).

      • The commitmentId is calculated with a random salt and the provided name. The SDK automatically generates the random salt, calculates the commitmentId and includes it into the NamePreclaimTx

    Pre-claim

    Note:

    • After transaction is included, you have 300 key blocks to broadcast claim transaction with the same salt and it should be signed with the same private key as pre-claim. - As the pre-claim is required to avoid front running it is recommended to wait with the actual claim until at least 1 key block has been mined so that nobody knows which name you aim to claim. - The corresponding claim cannot be included in the same key block anyway. The protocol doesn't allow that.

    Claim

    This example assumes that you did a pre-claim before and kept an instance of Name.

    Depending on the length of the name in punycode the actual claim will result in direct ownership of the AENS name or start an auction:

    • Name length > 12: ownership of the name is immediately transferred to your account

    • Name length <= 12: an auction is started

    Note:

    • The nameFee that is required will be correctly calculated automatically for the initial claim.

      • It's still possible to pass it as additional param, see .

    • In case the claim triggers an auction the required nameFee is locked by the protocol.

    Bid during an auction

    In case there is an auction running for a name you want to claim you need to place a bid.

    Note:

    • It is required to provide a nameFee that is at least 5% higher than the current bid.

      • The node doesn't expose an API to request the nameFee of the last bid. You need to receive that information from the that you ideally host yourself.

    2. Update a name

    Now that you own your AENS name you might want to update it in order to:

    • Set pointers to accounts, oracles, contracts, channels, or store binary data.

    • Extend the TTL before it expires.

      • By default a name will have a TTL of 180000 key blocks (~375 days). It cannot be extended longer than 180000 key blocks.

    Set pointers & update TTL

    Note:

    • If you provide an empty pointers object and don't set extendPointers to true all of your current pointers will be removed.

    • If you provide a non-empty object of pointers to that function while using extendPointers the SDK will merge the existing pointers with those provided.

      • In case there already exists an account pointer and you provide an accounts address in the array the old account pointer will be overwritten

    Extend TTL while keeping pointers

    In case you want to extend a name using a custom TTL and keep the current pointers you can do this as follows:

    3. Transfer ownership of a name

    In some cases you might want to transfer the ownership of a name to another account. Of course this is also possible and you can do that as follows:

    4. Revoke a name

    In case you want to revoke a name prior to its expiration for whatever reason you can do that as follows:

    Note:

    • On revocation the name enters in a revoked state.

    • After a timeout of 2016 key blocks the name will be available for claiming again.

    Delegate signature to contract (AENS interface)

    It is possible to authorize a Sophia contract to manage an AENS name on behalf of your account. In order to achieve that you need to provide a delegation signature to the contract. The contract will then be able to use the and perform AENS related actions on behalf of your account.

    This functionality could for example be used to build an AENS marketplace.

    aerepl

    æREPL --- an interactive shell for Sophia

    Try Sophia, test your contracts, check "what if", calculate a factorial. Completely offline, independently from remote networks, no dockers required.

    If you are not familiar with Sophia, check first.

    AEX 2

    Simple Summary

    The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in .

    This document describes the technical specification and methods that the wallet provider (ex. Base æpp, Wællet, MetaMask) MUST use to interact with Aeternity based applications (hereinafter referred to as 'aepp' or 'aepps').

    https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-web-extension/src/content-script.js#L1-L30
    import { AeSdk, Node, AccountMemory, encode, Encoding } from '@aeternity/aepp-sdk';
    
    const aeSdk = new AeSdk({
      nodes: [
        {
          name: 'testnet',
          instance: new Node('https://testnet.aeternity.io'), // host your node for better decentralization
        },
      ],
      accounts: [new AccountMemory('sk_2CuofqWZHrABCrM7GY95YSQn8PyFvKQadnvFnpwhjUnDCFAWmf')],
    });
    
    const transactionInfo = await aeSdk.spend(
      100, // aettos
      'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E',
      { payload: encode(Buffer.from('spend tx payload'), Encoding.Bytearray) },
    );
    console.log(transactionInfo);
        async scanForWallets () {
          return new Promise((resolve) => {
            const handleWallets = async ({ wallets, newWallet }) => {
              newWallet = newWallet || Object.values(wallets)[0]
              if (confirm(`Do you want to connect to wallet ${newWallet.info.name} with id ${newWallet.info.id}`)) {
                console.log('newWallet', newWallet)
                stopScan()
    
                this.walletInfo = await this.aeSdk.connectToWallet(newWallet.getConnection())
                this.walletConnected = true
                const { address: { current } } = await this.aeSdk.subscribeAddress('subscribe', 'connected')
                this.$store.commit('aeSdk/setAddress', Object.keys(current)[0])
                resolve()
              }
            }
    
            const scannerConnection = new BrowserWindowMessageConnection()
            const stopScan = walletDetector(scannerConnection, handleWallets)
          })
        },

    add daisyUI for enhanced styling, improve token and network selection UI, and update balance formatting (b4dcd0e)

  • add disconnect icon and enhance wallet management UI with address copy functionality (eda4504)

  • add footer component, update button components to outlined style, and enhance color variables in global CSS (9ad1e65)

  • add initial project configuration with NextJS (b4cfbfa)

  • add launch configuration for debugging and refactor network configurations (a9dce6e)

  • add network and address validation before fetching balance in wallet provider (d707b3d)

  • add network configs (a1b2e35)

  • add periodic sync for events every 10 seconds in backend index (aa7a011)

  • add reusable Button component and enhance wallet management with detection status handling (1443086)

  • add SQLite database, update backend server configuration, and enhance script commands (499c12b)

  • add tests and improve testing utility (fcf0098)

  • add TTL option to deposit function in useBridgeActions hook (ca69829)

  • add usage instructions for deploy-token script (2934416)

  • add wallet and contract types, enhance bridge state management, and update network/token selection components (020e807)

  • adjust transaction history layout for better responsiveness (e42f174)

  • clean up imports in bridge configuration and deploy-token scripts (292d9a4)

  • complete bridge action (491c4e5)

  • docs: intro updated (c116983)

  • enhance bridge action components with history visibility and update date formatting (ec93d26)

  • enhance bridge action provider with transaction detail fetching and error handling (c8ef520)

  • enhance bridge form layout with fieldset and improve error message display (ad7dc7f)

  • enhance bridge form with error handling, validation logic, and improved input components (8060691)

  • enhance bridge functionality with improved wallet connection handling, UI adjustments, and new contract state utilities (8dedaa3)

  • enhance deposit function to return deposit index and improve test coverage (eb98a63)

  • enhance layout and add bridge component for asset management (e543f38)

  • enhance transaction handling with new Deposit interface, add explorer URLs, and refactor components (1620b05)

  • enhance transaction list display, fixes, improvements (bfece2f)

  • extend contracts with more getters, add data sync, fixes (f8ea8af)

  • handle token balance retrieval gracefully by returning "0" for undefined results (c0e9527)

  • implement bridge action context and notification system; refactor network handling and API routes (2efec3b)

  • implement bridge action verification and refactor SDK instance creation (abd05c5)

  • implement bridge context and provider (21e62cb)

  • implement Hyperchain bridge form with token and network selection, add token constants, and update deployment scripts (a53e4d0)

  • implement input components for amount and token selection, enhance bridge form functionality, and improve state management (9563d7a)

  • implement network constants and SDK initialization for Aeternity (d50f267)

  • implement network verification and deployment functionality (63c235b)

  • implement wallet management components (2d4e857)

  • improve amount input validation and integrate wallet context in bridge form (63769fd)

  • integrate notistack for notifications, enhance bridge form validation, and refactor network selection component (7451bec)

  • integrate Supabase for network data retrieval and refactor related components (fe9502b)

  • refactor bridge fe components and remove unused NetworkDisplay (7309a25)

  • Refactor bridge transaction handling and introduce new APIs (a749404)

  • refactor header component (e597bb0)

  • rewrite bridge contract (ae41a22)

  • simplify network and token selection components by removing unused props (6f2e4ff)

  • update cache deployments (2458d95)

  • update deployment file references and enhance HyperchainBridge contract with index handling (c4dd778)

  • update frontend structure by adding index and render files, and refactor package.json scripts (f13b053)

  • Update HyperchainBridge contract and related components (6087099)

  • update layout and styling, replace SVG icons, and enhance bridge form components (bec76f0)

  • update package.json to support concurrent frontend and backend development (5207fe2)

  • update TTL for allowance and deposit functions, enhance bridge page styling with background img (e0232cd)

  • update usage instructions in configure-bridge script to support multiple token and network registrations (8b495fc)

  • remove default values for network URLs in NetworkForm component (19633e9)

  • remove status code from error response in byUserAddress API (b02c660)

  • update AE_TESTNET bridge contract address and include in DEFAULT_NETWORKS (dc24459)

  • update bridge contract address for AE_MAINNET (0ed9668)

  • update bridge contract addresses and improve bridge action handling (a40d2a5)

  • update bridge contract addresses for AE_TESTNET and AE_MAINNET (3107947)

  • update Dockerfile and package.json for consistency and production environment setup (fedc618)

  • update token transfer logic in HyperchainBridge (30d3478)

  • use environment variable for server port configuration (f5eed97)

  • remove unused network display logic and clean up component structure (134f356)

  • replace app.ts with server.ts for improved server handling and update package scripts (62e5a6c)

  • replace useNetworks hook with WalletContext for network management and introduce NetworkBalanceProvider (05c4fa8)

  • restructure project by removing web package and consolidating frontend and backend components (b74b1e6)

  • smart contracts and packages (0fed5cc)

  • update bridge contract handling and improve token balance fetching logic (e0bf16f)

  • update font weight in connected view for improved emphasis on balance display (3caf71d)

  • update styling in bridge form title and alert message for improved readability (3f9269d)

  • update useBridgeContract hook to return loading state and adjust usage in components (1dc9ab1)

  • update variable declarations to use const, improve code readability, and clean up unused functions (bb6d25a)

  • 037ff17
    28b3545
    1.4.0
    5a62480
    45726b6
    6b54ae2
    1.3.1
    eceaf42
    1.3.0
    fbaf4c8
    95652e2
    7d06806
    0ec7693
    b6aa4a5
    1.2.0
    c4d2bb0
    4f5ad24
    3403948
    6974ef2
    1.1.0
    0acc7dc
    1.0.1
    abbd061
    72ce014
    a07a8a8
    0e1b54f
    ccc13f0
    f252221
    8949636
    d2890a7
    03537ab
    42f3686
    a81677d
    3107947
    d5763af
    de4f439
    .
  • After the NamePreclaimTx transaction has been mined you will be able to perform the actual claim of the name. When performing the actual claim via a NameClaimTx you will, depending on the length of the name:

    • immediately become owner of that name

    • initiate an auction

  • You should check if the name is still available before performing a pre-claim. The protocol itself doesn't reject a pre-claim transaction if the name isn't available anymore.
  • If you win the auction the nameFee is permanently deducted from your accounts balance and effectively burned.

    • It will be credited to ak_11111111111111111111111111111111273Yts which nobody can access. This reduces the total supply of AE over time.

  • If somebody else outbids you the provided nameFee is immediately released and returned to your account.

  • It's also possible to pass additional transaction options here, too.

    transaction options
    middleware
    AENS interface
    https://github.com/aeternity/aepp-sdk-js/blob/f60d1b8a1124b32781769342e4941c8dacf6ad53/examples/browser/aepp/src/StoreAeSdkPlugin.js#L1-L5
    import { AeSdk, Name } from '@aeternity/aepp-sdk'
    
    const aeSdk = new AeSdk({ ... }) // init the SDK instance with AeSdk class
    
    // `getContext` is used to bind AeSdk to Name instance
    // e.g. if you change the node in AeSdk it also would be changed in Name.
    // Alternatively, you need to provide `onAccount`, `onNode` options.
    const name = new Name('testNameForTheGuide.chain', aeSdk.getContext())
    
    const preClaimTx = await name.preclaim()
    console.log(preClaimTx)
    
    /*
    {
      blockHash: 'mh_2UsggiUaQQmEPjxLnXkXHpm1WawTWqZb1jBx6UzsQNHgirWAwd',
      blockHeight: 449499,
      hash: 'th_48RktjEutZC8TCubaq9YhjaF1cKLV9D3VRCJyzJLs7oSp4Ry6',
      signatures: [
        'sg_Da98k2EKMun1TkE7ytonRypvJwaKg9iBjp8rNcYuodFXqzRqwjQyuFQP5DhxWUpTYRzSTurrNtDmUft8eyTStjCyNqFf8'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        commitmentId: 'cm_2igvW9egddKh77gDdE8mjotmL8PzE7Tf2Q639Q5stUqWQoEfap',
        fee: 16620000000000n,
        nonce: 18,
        type: 'NamePreclaimTx',
        version: 1
      },
      rawTx: 'tx_+JkLAfhCuEBgFzAL0bPDufmzDq0558vaKtrIyRpNxCYVtkgnJjBrxDpQZHkfbwG+oRuBUAfgfrAKF0lO9mRI1zq0H6bXIq8KuFH4TyEBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhKhA+Jawe/spFaw823K+U59CWx+xD1i34gngUPiAAKJqv/fhg8dpTI4AAAGc20E',
      height: 449499
    }
    */
    // the minimum `nameFee` will be automatically generated by sdk
    // in case you want to provide a custom `nameFee` you can so so by providing it in an options object
    // in case of starting the auction `nameFee` will be the starting bid
    const claimTx = await name.claim();
    console.log(claimTx);
    
    /*
    {
      blockHash: 'mh_UvtuVNvK7k29G3anF48W4hgUMaFFLc1wKir55FFifgT49Egk',
      blockHeight: 449507,
      hash: 'th_2sWNusGUf2wuRn7d453wPWTAe8pKVbtNF4DqakvippsxjvF8g1',
      signatures: [
        'sg_LYsVj9zUoKFPDiSvFUWG5QaRhnqQ525YA314xMVzRhApYuPnFyMWgAQGpChKHHWyMbykBwVRrmoQtTENTFCaCoMj17CBK'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        fee: 16800000000000n,
        name: 'testNameForTheGuide.chain',
        nameFee: 2865700000000000000n,
        nameSalt: 7595805618692717,
        nonce: 19,
        type: 'NameClaimTx',
        version: 2
      },
      rawTx: 'tx_+KILAfhCuECVba2mm3Un3nrN9U+LpuB2wzqDDmAzXwvc+9sVkpkcALzqm14p7kGqyt8pwjGTyKeLM9lp+KgXWF4PHmHz0WAPuFr4WCACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhOZdGVzdE5hbWVGb3JUaGVHdWlkZS5jaGFpboca/FhPr2JtiCfFAveE1kAAhg9HjghAAADilhgr'
    }
    */
    import { computeBidFee, computeAuctionEndBlock } from '@aeternity/aepp-sdk'
    
    const name = new Name('auctiontest1.chain', aeSdk.getContext())
    
    const startFee = ... // request from middleware, e.g. https://testnet.aeternity.io/mdw/name/auctiontest1.chain
    const increment = 0.05 // 5%, the minimum required increment
    
    // startFee is OPTIONAL and defaults to minimum calculated fee for the name in general
    // startFee MUST be at least the nameFee of the last bid
    // increment is OPTIONAL and defaults to 0.05
    // `name.value` is a name as string
    const nameFee = computeBidFee(name.value, { startFee, increment })
    const bidTx = await name.bid(nameFee)
    
    console.log(bidTx)
    console.log(`BID PLACED AT ${bidTx.blockHeight} WILL END AT ${computeAuctionEndBlock(name, bidTx.blockHeight)}`)
    
    /*
    {
      blockHash: 'mh_Y5LDYPtPWzcop2FCbxnwTSwjWo9d3rYcBBcChCEHfzHo2YZpm',
      blockHeight: 449693,
      hash: 'th_2nZshewM7FtKSsDEP4zXPsGCe9cdxaFTRrcNjJyE22ktjGidZR',
      signatures: [
        'sg_7G49bziWjjZAjayBhFffRyfLbmFczs2foJgXcx1n1Vo7iGELQqggdH4w72MqWbNUbM9Jv2EBJnd2LFjv6LJhqTmvJBWyr'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        fee: 16520000000000n,
        name: 'auctiontest1.chain',
        nameFee: 3159434250000000000n,
        nameSalt: 0,
        nonce: 24,
        type: 'NameClaimTx',
        version: 2
      },
      rawTx: 'tx_+JQLAfhCuEAv2HQoyLa7krHpcQAsPpWdP+6PJYzdPSifmwNIgpWZtyrdgVD+IGMzzAqxkOQEDeAwc/Oh+dfXPBZpNslCNFgBuEz4SiACoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhiSYXVjdGlvbnRlc3QxLmNoYWluAIgr2JC2AnPkAIYPBly7UAAAm/NY1g=='
    }
    BID PLACED AT 449693 WILL END AT 479453
    */
    import { getDefaultPointerKey, encode, Encoding } from '@aeternity/aepp-sdk';
    
    const oracle = 'ok_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk';
    const pointers = {
      account_pubkey: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
      customKey: encode(Buffer.from('example data'), Encoding.Bytearray),
      [getDefaultPointerKey(oracle)]: oracle, // the same as `oracle_pubkey: oracle,`
      contract_pubkey: 'ct_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
      channel: 'ch_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
    };
    
    const nameUpdateTx = await name.update(pointers);
    console.log(nameUpdateTx);
    
    /*
    {
      blockHash: 'mh_AiaGtTWBRys7EX5apAidShyCw1kefocuWt49DgLE2fWNCgKvq',
      blockHeight: 449855,
      hash: 'th_LLef19g2mLWQfG7Ds1XZNGyb3SGvi8PGvk7mJczpD9iToBcqL',
      signatures: [
        'sg_Zm7kp1oBnXGnHwdzsim9nTXtrGoV4bWJhcC1nkw9f3eMPibVaYQRoM829iNrPandAfs8TK7ogEkYByxQx11xCAFMpwUBz'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        clientTtl: 3600,
        fee: 17800000000000n,
        nameId: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
        nameTtl: 180000,
        nonce: 27,
        pointers: [ [Object] ],
        type: 'NameUpdateTx',
        version: 1
      },
      rawTx: 'tx_+NQLAfhCuED6aLVAlIfcqczlZ4XzOjG3U23l5+egPFDVEKTSMuL0Zj18jUG6ctJxGGQubNoANFcwQl79T7w0dG4+FV7Qn3AKuIz4iiIBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhuhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbagwK/IPLxjmFjY291bnRfcHVia2V5oQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAoMBSniGEDBirVAAAJ7I9GA='
    }
    */
    const nameUpdateTx = await name.extendTtl(100000);
    console.log(nameUpdateTx);
    
    /*
    {
      blockHash: 'mh_2mbAuBtyPp7wN6hrcvkYD7LZRSegwZZKYnLcNQkGVGRZ3uVxW6',
      blockHeight: 449860,
      hash: 'th_2wXE8i5BUFCUPuioKwAuwNysm6RPQo8STf5m91CuT3LTh7q4ko',
      signatures: [
        'sg_E69tfR3STWi5Dg6yUHQj5D5waTCEhoFmb1LYWGU2bsCnuLkMgH1KqhRKrCZaatDMyg5szgABDuU1r6ZD5K74qXWW5pMJ'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        clientTtl: 100000,
        fee: 17800000000000n,
        nameId: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
        nameTtl: 100000,
        nonce: 28,
        pointers: [ [Object] ],
        type: 'NameUpdateTx',
        version: 1
      },
      rawTx: 'tx_+NQLAfhCuEABuZTyU+W5xmBpQn5GCJiSpK6fI0pYoMIQ5IqD2bs6pJ+oyU7HDGoSU0Mn6tsfYOn+MVRsxLR6yM1Vyv0c4JQNuIz4iiIBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAhyhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbagwGGoPLxjmFjY291bnRfcHVia2V5oQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAoMBhqCGEDBirVAAANKYAm0='
    }
    */
    const recipient = 'ak_...';
    const nameTransferTx = await name.transfer(recipient);
    console.log(nameTransferTx);
    
    /*
    {
      blockHash: 'mh_ZuYV5tmJM4PhrfxzXfo9e37uqPcYpCiAoEC2uRcqbUXeMSmLH',
      blockHeight: 449982,
      hash: 'th_xXqmZxR7WJDe6YTz1GnHWgNjtcZjpTPA5bVuiQstmd8o6Gg7x',
      signatures: [
        'sg_72fiMzprywNmFtuf1i1FFfhBBXcPHpHDfi1Uv2bDnYayoCRWe1yyzvwLmhM6cfA3TR6pBF9Kj3iyYm3mrC46rvNCpchyi'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        fee: 17300000000000n,
        nameId: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
        nonce: 33,
        recipientId: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E',
        type: 'NameTransferTx',
        version: 1
      },
      rawTx: 'tx_+LsLAfhCuEAuFNHG4gniZjJDQtbm5cIfJACkU/NI96mZpwMvdyuxxOYWYxSxUF2NF5oxjmsYLdXWfSrdmgWj40JzZU/TRA4DuHP4cSQBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAiGhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbaoQHVzwhADpiCIvJutLAsj4kHdFdGchGm5tlV7bcHScajO4YPu/hayAAABhgUgg=='
    }
    */
    const nameRevokeTx = await name.revoke();
    console.log(nameRevokeTx);
    
    /*
    {
      blockHash: 'mh_2Q5Xqd4vrmwkS98SBkN79k1t9VLNmDX4wk8xnUJYTEvkK3YoH4',
      blockHeight: 450018,
      hash: 'th_2XhJradAVKN2jR2tgNYdKNWikMc8XunqTdUhRPh2TyhAwMqijJ',
      signatures: [
        'sg_Tjbf8SJDQXgBhaYk7AzTTr7d1RF3bDcMp6BMgRoHcHcgBp13HjcMYmZJ8vvqrZ94An9gvQD4NegYrR7eaBLt6jEy99xyM'
      ],
      tx: {
        accountId: 'ak_2519mBsgjJEVEFoRgno1ryDsn3BEaCZGRbXPEjThWYLX9MTpmk',
        fee: 16620000000000,
        nameId: 'nm_1Cz5HGY8PMWZxNrM6s51CtsJZDU3DDT1LdmpEipa3DRghyGz5',
        nonce: 34,
        type: 'NameRevokeTx',
        version: 1
      },
      rawTx: 'tx_+JkLAfhCuEDMWOZac70tEHQ4AHGBIedZepwTvsBjIHk36vhTd5yBepmTemTQcUVrAtbNO3jZVZD4GUOhN+DfXm2lNrpZu+8FuFH4TyMBoQGMyNToF1flcYDSVsPl5DZ9ZY3FJWRpDRQYD32quWBEAiKhAgB4Gsn+dalOdWvHXJd+3LBBiO9HsZoHIF2/aQ4n/bbahg8dpTI4AAB44bma'
    }
    */
    const contractAddress = 'ct_asd2ks...';
    // AENS name
    const nameId = 'example.chain';
    const commonParams = {
      contractAddress,
      accountAddress: aeSdk.address,
    };
    let delegation;
    
    // this signature will allow the contract to perform a pre-claim on your behalf
    delegation = packDelegation({ tag: DelegationTag.AensPreclaim, ...commonParams });
    
    // this signature will allow the contract to perform
    // any name related transaction for a specific name that you own
    delegation = packDelegation({ tag: DelegationTag.AensName, nameId, ...commonParams });
    
    // alternatively, you can generate a delegation signature suitable for every name you own
    delegation = packDelegation({ tag: DelegationTag.AensWildcard, ...commonParams });
    
    const delegationSignature = await aeSdk.signDelegation(delegation);
    import { Node, AccountMemory, buildTxAsync, Tag, encode, Encoding } from '@aeternity/aepp-sdk';
    
    const onNode = new Node('https://testnet.aeternity.io'); // host your node for better decentralization
    const account = new AccountMemory('sk_2CuofqWZHrABCrM7GY95YSQn8PyFvKQadnvFnpwhjUnDCFAWmf');
    
    const spendTx = await buildTxAsync({
      tag: Tag.SpendTx,
      senderId: account.address,
      recipientId: 'ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E',
      amount: 100, // aettos
      payload: encode(Buffer.from('spend tx payload'), Encoding.Bytearray),
      onNode,
    });
    
    const signedTx = await account.signTransaction(spendTx, { networkId: await onNode.getNetworkId() });
    
    // broadcast the signed tx to the node
    const { txHash } = await onNode.postTransaction({ tx: signedTx });
    console.log(txHash);
    import { AeSdkAepp, Node } from '@aeternity/aepp-sdk';
    
    const TESTNET_NODE_URL = 'https://testnet.aeternity.io';
    const MAINNET_NODE_URL = 'https://mainnet.aeternity.io';
    const COMPILER_URL = 'https://compiler.aepps.com';
    Setup

    Dependencies

    Tools:

    • git

    • OTP 25 or 26

    • C++ compiler

    Libraries:

    Local build

    Clone the repo:

    Set up the environment:

    Build the project (the make step may need to be executed twice, see this issue):

    Launch the REPL

    Docker/podman image

    For a consistent setup, a docker image can be created:

    Then to start the dockerized REPL:

    Use make podman for a podman build.

    CLI usage

    æREPL usage patterns are highly inspired byGHCi. Most of the syntax is a direct adaptation of it to the needs of Sophia and FATE. This section shall provide an overview of the most fundamental features and typical workflows. If you find navigation clunky, please consider usingrlwrap.

    Main functionality of æREPL is to evaluate Sophia expressions:

    Aside from that, values can be assigned to REPL-local variables (pattern matching is supported)

    Functions and types are supported as well

    NOTE: in-REPL functions cannot use in-REPL variables and other functions yet.

    Typechecking

    A common query is to ask about the type of an expression. This is done using the:type command:

    Working with files

    æREPL allows loading files to call their code and deploy contracts defined in them. To load a file, the :load command may be used:

    If multiple files are loaded, only the most recent one is brought to the scope. To include other loaded files into the working scope, Sophia's include should be used:

    Note that :load reloads all listed files and unloads those skipped. Yet another useful command is :reload, which reloads all loaded files, preserving the included scope.

    :load and :reload clear out the scope, meaning that they will clean

    • User defined variables

    • User defined functions

    • User defined types

    • Includes

    • Deployed contracts

    • In-REPL state

    In-REPL state

    æREPL maintains its own Sophia state which can be accessed using standard operations put and state, as well as stateful functions. By default, the state is set to () : unit. In order to change it to some other type, :state command should be used:

    Note that :state is parameterized by value, not by type. The value has to have a fully instantiated, non-functional type. Changing the state using the :state commands clears out all user-defined variables and functions --- if that is not desired, put should be used to modify the state if possible.

    Configuration

    æREPL can be configured interactively using the :set command. The syntax for this command is :set OPTION [ARGS], for example

    Currently the supported options are:

    Option
    Arguments
    Description

    call_gas

    non-neg int

    Determines the amount of gas to be supplied to each query.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    call_value

    non-neg int

    The value, the amount of tokens supplied with the query.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    Output format

    By default, the REPL shall display values preserving compatibility with Sophia syntax. An exception from that rule are values containing functions which in FATE are represented as pairs of function name and closure. In that case, the output will take a form of "<fun $FUNHASH>" : $TYPE where $TYPE is the type of the function (according to the Sophia code, not FATE bytecode), and$FUNHASH is a hex-encoded shortcut of the original function's name hashed with BLAKE2B (as it is stored in the bytecode). For example

    If print_format is set to fate, the value shall be displayed as an Erlang term that describes the exact representation of the value in the runtime.

    If set to json, the values will be encoded in JSON format. Information about record fields and datatype constructor names shall not be dropped. Function values are represented as strings in the same manner as in the sophia format.

    Multiline input

    To type in a multiline block of code, surround it with :{ and :}:

    Generic server interface

    If REPL is used as a library for a different tool, its generic server can be used for more structured interface. The server is located insrc/aere_gen_server.erl and implements the standard gen_server Erlang behaviour.

    Startup

    Use aere_gen_server:start/1 to start up the server. aere_gen_server:start/2 allows to start a server under a custom name. The argument is property list with the following fields:

    • options --- parameter map for the repl configuration. See "Configuration" for more details.

    • accounts :: list(#{pubkey() => integer()}) --- list of initial accounts and their balances

    Call

    • quit --- terminates the server

    • skip --- does nothing

    • bump_nonce --- bumps internal REPL nonce (used in naming internal variables)

    • blockchain_state --- returns the chain state for the current session

    • theme --- returns the current display theme

    • {type, string()} --- parses the expression and returns its type in the session context

    • {state, string()} --- parses the expression and evaluates it in the session context. The restult is then assigned to the session's contract store. All locally defined functions, variables and types are pruned.

    • {eval, string()} --- parses the expression and evaluates it in the session context

    • {load, list(string())} --- Loads files from the file system. Includes the first one in the list.

    • reload --- Reloads the currently loaded files.

    • {set, Option :: atom(), Value :: list(term())} --- changes REPL's configuration (see {help, "set"} for more details)

    • help --- lists all available commands

    • {help, string()} --- returns the help text for the given command

    • {lookup, atom()} --- prints information about REPL's state or configuration

    • {disas, string()} --- parses a reference to a function and prints its FATE code

    • stop --- if at breakpoint, cancels the execution and rolls back all changes

    • {break, FileName :: string(), Line :: integer()} --- adds a breakpoint

    • {delete_break, integer()} --- removes a breakpoint with a given id

    • {delete_break_loc, string(), integer()} --- removes all breakpoints from the given file at the given line

    • continue --- resumes execution after a breakpoint stop

    • stepover --- proceeds to the next line in the current execution

    • stepin --- proceeds to the next line, or enters the function body if there is a function call upcoming

    • stepout --- resumes execution until the next breakpoint or current function return

    • location --- returns in-code location of current execution

    • {print_var, string()} --- returns in-code location of where the variable was introduced

    • print_vars --- returns values of all variables in scope

    • stacktrace --- returns the current stacktrace

    • {set_account, pubkey(), integer()} --- sets balance for an in-repl account

    • version --- returns version information

    • banner --- returns an ASCII "banner" presenting the REPL's logo and various version information

    Cast

    • {update_filesystem_cache, #{string() => binary()}} --- updates REPL's perception of the file system to the provided map. If this is set, all include and file load instructions will ignore system's file system, and will use this map instead.

    Functions

    All above calls and casts are exposed as function calls for convenience. Additionally, the following are offered:

    • format --- formats outputs of other commands into renderable texts to be used by the render function

    • render --- renders a renderable output to a string using REPL's theme

    • banner --- returns a nicely rendered banner for CLI interfaces

    • input --- parses a text command and interprets it as one of the calls above. Useful for CLI-like interfaces.

    • prompt --- proposes prompt to display in the CLI based on the REPL's state. For example, the default is AESO> .

    its documentation
    Motivation

    Currently, there exists no standard way for wallets and aepps to communicate and everything developed on the SDK side is developed only keeping the Base æpp in mind and rest of the wallet providers need to follow the same path. By defining the standard way of communication between aepps and Wallet we will not only reduce the dependency that other wallet providers have on the Base æpp as well as we'll have a clear standard method of communication on the SDK side that can be further extended upon whenever required.

    Specification

    Naming Convention

    Wherever possible, this document tries to closely follow the who.what.how naming convention for JSON-RPC methods.

    JSON-RPC 2.0 Specification

    Error

    JSON-RPC 2.0 response error object that is used to communicate any error occurred while processing the request.

    Types of errors

    Code

    Message

    Meaning

    1

    Invalid transaction

    MUST be returned whenever the transaction validity check fails and the node returns a similar error

    2

    Broadcast failed

    MUST be returned by the aepp or wallet if it has been unable to broadcast the transaction.

    3

    Rejected by user

    MUST be returned by the wallet when user denies the action request by aepp.

    4

    Unsupported protocol version

    MUST be returned by wallet when it does not support protocol version the aepp wants to connect through.

    Methods

    Aepp Invokable Methods

    This section defines the methods that the aepps MUST invoke to either get information from the wallet or request the wallet to perform an action.

    • connection.open: connection request sent by the aepp to the wallet.

      Parameters

      Object

      • version: protocol version. Currently defaults to 1.

      Returns

      Object

      • networkId: Network id used by the wallet

      Returns errors

      • Unsupported protocol version

      • Unsupported network

    • address.subscribe: request the wallet to get or subscribe to address changes. This method MUST return only if the aepp is successfully subscribed else it MUST throw the appropriate error.

      Parameters

      Object

      • type: payload indicating the type of update i.e. subscription or un-subscription. This supports two options:

    • transaction.sign: request wallet for signature

      Parameters

      Object

      • tx: unsigned encoded transaction (Datatype: String).

      • return

    Notifications

    Wallet Invokable Notifications

    • connection.announcePresence: MAY be used by the wallets to announce their presence wherever required (e.g. postMessage API). This message SHOULD NOT be used by the wallets where a 1-to-1 connection with the aepp is already established but instead wait for the aepp to initiate the connection using connection.open message.

      Note: This is a helper message for the aepp to identify the presence of a wallet.

      Parameters

      Object

      • networkId: Network id used by the wallet

    • networkId.update: MUST be used by Wallet for informing Aepp about the change of network id.

      Parameters

      Object

      • networkId: Updated network id.

    • address.update: MUST be used by the wallet to notify subscribed aepps about the address change.

      Parameters

      Object

      • address: JSON Object. This MAY contain 1 or more keys but only of the below types. The values in the object completely depend on the aepp's subscription.

        Subscription Type:

    Invokable by Wallet and Aepp

    • connection.close: SHOULD be used by Aepp or Wallet for informing the other party that it is disconnecting and further requests will either be denied or not acknowledged.

    Example Flow

    Reference Implementation

    • Aepp: https://github.com/aeternity/aepp-sdk-js/tree/feature/aex-2/examples/browser/vuejs/connect-two-ae

    • Extension Wallet: https://github.com/aeternity/aepp-sdk-js/tree/feature/aex-2/examples/browser/extension

    References

    • Transaction Encoding and Serialization https://github.com/aeternity/protocol/blob/master/node/api/api_encoding.md https://github.com/aeternity/protocol/blob/master/serializations.md

    • JSON-RPC 2.0 Specification https://www.jsonrpc.org/specification

    RFC 2119
    https://github.com/aeternity/aepp-sdk-js/blob/1cd128798018d98bdd41eff9104442b44b385d46/examples/browser/wallet-web-extension/src/background.js#L1-L163
    git clone https://github.com/aeternity/aerepl.git
    export ERLANG_ROCKSDB_OPTS="-DWITH_SYSTEM_ROCKSDB=ON -DWITH_LZ4=ON -DWITH_SNAPPY=ON -DWITH_BZ2=ON -DWITH_ZSTD=ON"
    export CXXFLAGS="-Wno-error=shadow -Wno-deprecated-copy -Wno-redundant-move -Wno-pessimizing-move"
    cd aerepl
    make
    ./aerepl
    make docker
    docker run -i aeternity/aerepl:local
    AESO> 2 + 2
    4
    AESO> let x = 2
    AESO> let (q, w) = (x + 1, x - 1)
    AESO> q
    3
    AESO> w
    1
    AESO> record point = {x : int, y : int}
    AESO> function get_x(p : point) = p.x
    AESO> get_x({x = 100, y = 42})
    100
    AESO> :type Oracle.query
    (oracle('a, 'b), 'a, int, Chain.ttl, Chain.ttl) => oracle_query('a, 'b)
    // File: Test.aes
    namespace N =
      function f() = 100
    
    contract C =
      entrypoint f() = N.f() + 23
    AESO> :load Test.aes
    AESO> N.f()
    100
    AESO> let c = Chain.create() : C
    AESO> c.f()
    123
    AESO> include "List.aes"
    AESO> :load X.aes Y.aes
    AESO> Y.y()  // defined in Y.aes
    "y"
    AESO> X.x()  // defined in X.aes
    1:1 Unbound variable: X.x
    AESO> include "X.aes"
    AESO> X.x()  // Now it works
    "x"
    AESO> :set print_unit true
    AESO> state
    ()
    AESO> :state 1000
    AESO> state + 1
    1001
    AESO> put(state / 2)
    ()
    AESO> state
    500
    AESO> :set print_unit true
    AESO> () => ()
    "<fun E3472E14>" : () => unit
    AESO> :set print_format fate
    AESO> record r = {x : int, y : int}
    AESO> {y = 100, x = 7}
    {tuple,{7,100}}
    AESO> Some(1)
    {variant,[0,1],1,{1}}
    AESO> () => ()
    {tuple,{<<227,71,46,20>>,{tuple,{}}}}
    AESO> :set print_format json
    AESO> record r = {x: int, y : int}
    AESO> ({x = 3, y = 4}, "STRING")
    [
      {
        "x": 3,
        "y": 4
      },
      "STRING"
    ]
    AESO> :{
    | let x = 123
    | x
    | :}
    123
    AEX: 2
    Title: Third-party Wallet Provider Support
    Author: Shubhendu Shekhar (@shekhar-shubhendu), Andrea Giacobino (@noandrea), Enrico Icardi (@ricricucit) & Nazar Duchak (@nduchak)
    License: BSD-3-Clause
    Discussions-To: https://forum.aeternity.com/t/aex-2-js-sdk-interfaces-for-wallets/2715
    License-Code: Apache-2.0
    Status: Withdrawn
    Type: Standards Track
    Created: 2019-03-04
    import browser from 'webextension-polyfill';
    import {
      BrowserRuntimeConnection,
      BrowserWindowMessageConnection,
      MESSAGE_DIRECTION,
      connectionProxy,
    } from '@aeternity/aepp-sdk';
    
    (async () => {
      console.log('Waiting until document is ready');
      await new Promise((resolve) => {
        const interval = setInterval(() => {
          // TODO: ensure that there is no corresponding event
          if (document.readyState !== 'complete') return;
          clearInterval(interval);
          resolve();
        }, 100);
      });
      console.log('Document is ready');
    
      const port = browser.runtime.connect();
      const extConnection = new BrowserRuntimeConnection({ port });
      const pageConnection = new BrowserWindowMessageConnection({
        target: window,
        ...(window.origin !== 'null' && { origin: window.origin }),
        sendDirection: MESSAGE_DIRECTION.to_aepp,
        receiveDirection: MESSAGE_DIRECTION.to_waellet,
      });
      connectionProxy(pageConnection, extConnection);
    })();

    call_gas_price

    non-neg int

    The result of Call.gas_price

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    call_origin

    pubkey

    The account to initiate execution of in-REPL code.

    Defines Call.origin and initial Call.caller.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    call_contract_creator

    pubkey

    The result of Contract.creator.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    call_fee

    non-neg int

    The result of Call.fee.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    call_height

    non-neg int

    The result of Chain.block_height.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    print_gas

    true/false

    If true, REPL will print gas used for evaluating each expression.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    print_format

    sophia/fate/json

    Determines the syntax used to display values.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    print_unit

    true/false

    Whether to display unit (()).

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    print_type

    true/false

    Whether to display the type after each eval.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    loc_backwards

    non-neg int

    Number of previous lines to be displayed when using location.

    -------------------------

    --------------------

    :--------------------------------------------------------------------

    loc_forwards

    non-neg int

    Number of further lines to be displayed when using location.

    import browser from 'webextension-polyfill';
    import {
      AeSdkWallet,
      CompilerHttp,
      Node,
      AccountMemory,
      BrowserRuntimeConnection,
      WALLET_TYPE,
      RpcConnectionDenyError,
      RpcRejectedByUserError,
      RpcNoNetworkById,
      unpackTx,
      unpackDelegation,
    } from '@aeternity/aepp-sdk';
    import { TypeResolver, ContractByteArrayEncoder } from '@aeternity/aepp-calldata';
    
    function stringifyBigint(value) {
      return JSON.stringify(value, (k, v) => (typeof v === 'bigint' ? `${v} (as BigInt)` : v), 2);
    }
    
    let popupCounter = 0;
    async function confirmInPopup(parameters) {
      const popupUrl = new URL(browser.runtime.getURL('./popup.html'));
      const popupId = popupCounter;
      popupCounter += 1;
      popupUrl.searchParams.set('data', stringifyBigint({ ...parameters, popupId }));
      await browser.windows.create({
        url: popupUrl.toString(),
        type: 'popup',
        height: 600,
        width: 600,
      });
      return new Promise((resolve) => {
        const handler = (message, sender, sendResponse) => {
          if (message.popupId !== popupId) return;
          resolve(message.response);
          sendResponse();
          browser.runtime.onMessage.removeListener(handler);
        };
        browser.runtime.onMessage.addListener(handler);
      });
    }
    
    const aeppInfo = {};
    const genConfirmCallback = (action) => async (aeppId, parameters, aeppOrigin) => {
      const isConfirmed = await confirmInPopup({
        ...parameters,
        action,
        aeppId,
        aeppInfo: aeppInfo[aeppId],
        aeppOrigin,
      });
      if (!isConfirmed) throw new RpcRejectedByUserError();
    };
    
    class AccountMemoryProtected extends AccountMemory {
      async signTransaction(transaction, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
        if (id != null) {
          const opt = { ...options, transaction, unpackedTx: unpackTx(transaction) };
          if (opt.onCompiler) opt.onCompiler = '<Compiler>';
          if (opt.onNode) opt.onNode = '<Node>';
          await genConfirmCallback('sign transaction')(id, opt, aeppOrigin);
        }
        return super.signTransaction(transaction, options);
      }
    
      async signMessage(message, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
        if (id != null) {
          await genConfirmCallback('sign message')(id, { ...options, message }, aeppOrigin);
        }
        return super.signMessage(message, options);
      }
    
      async signTypedData(data, aci, { aeppRpcClientId: id, aeppOrigin, ...options }) {
        if (id != null) {
          const dataType = new TypeResolver().resolveType(aci);
          const decodedData = new ContractByteArrayEncoder().decodeWithType(data, dataType);
          const opt = {
            ...options,
            aci,
            data,
            decodedData,
          };
          await genConfirmCallback('sign typed data')(id, opt, aeppOrigin);
        }
        return super.signTypedData(data, aci, options);
      }
    
      async unsafeSign(data, { aeppRpcClientId: id, aeppOrigin, ...options } = {}) {
        if (id != null) {
          await genConfirmCallback(`sign raw data ${data}`)(id, options, aeppOrigin);
        }
        return super.unsafeSign(data, options);
      }
    
      async signDelegation(delegation, { aeppRpcClientId: id, aeppOrigin, ...options }) {
        if (id != null) {
          const opt = { ...options, ...unpackDelegation(delegation) };
          await genConfirmCallback('sign delegation')(id, opt, aeppOrigin);
        }
        return super.signDelegation(delegation, options);
      }
    
      static generate() {
        return new AccountMemoryProtected(super.generate().secretKey);
      }
    }
    
    const aeSdk = new AeSdkWallet({
      onCompiler: new CompilerHttp('https://v8.compiler.aepps.com'),
      nodes: [
        { name: 'ae_uat', instance: new Node('https://testnet.aeternity.io') },
        { name: 'ae_mainnet', instance: new Node('https://mainnet.aeternity.io') },
      ],
      accounts: [
        new AccountMemoryProtected('sk_2CuofqWZHrABCrM7GY95YSQn8PyFvKQadnvFnpwhjUnDCFAWmf'),
        AccountMemoryProtected.generate(),
      ],
      id: browser.runtime.id,
      type: WALLET_TYPE.extension,
      name: 'Wallet WebExtension',
      async onConnection(aeppId, params, aeppOrigin) {
        const isConfirmed = await confirmInPopup({
          action: 'connect',
          aeppId,
          aeppInfo: params,
          aeppOrigin,
        });
        if (!isConfirmed) throw new RpcConnectionDenyError();
        aeppInfo[aeppId] = params;
      },
      onDisconnect(aeppId, payload) {
        console.log('Client disconnected:', aeppId, payload);
      },
      onSubscription: genConfirmCallback('subscription'),
      onAskAccounts: genConfirmCallback('get accounts'),
      async onAskToSelectNetwork(aeppId, parameters, origin) {
        await genConfirmCallback('select network')(aeppId, parameters, origin);
        if (parameters.networkId) {
          if (!this.pool.has(parameters.networkId)) throw new RpcNoNetworkById(parameters.networkId);
          await this.selectNode(parameters.networkId);
        } else {
          this.pool.delete('by-aepp');
          this.addNode('by-aepp', new Node(parameters.nodeUrl));
          await this.selectNode('by-aepp');
        }
      },
    });
    // The `ExtensionProvider` uses the first account by default.
    // You can change active account using `selectAccount(address)` function
    
    browser.runtime.onConnect.addListener((port) => {
      // create connection
      const connection = new BrowserRuntimeConnection({ port });
      // add new aepp to wallet
      const clientId = aeSdk.addRpcClient(connection);
      // share wallet details
      aeSdk.shareWalletInfo(clientId);
      const interval = setInterval(() => aeSdk.shareWalletInfo(clientId), 3000);
      port.onDisconnect.addListener(() => clearInterval(interval));
    });
    
    console.log('Wallet initialized!');

    subscribe (datatype: string): MUST be used by the aepp to request a subscription.

  • unsubscribe (datatype: string): MUST be used by the aepp to request an un-subscription.

  • value: indicating the subscription/un-subscription that needs to be handled Currently supported options:

    • current (datatype: string): MUST be used to for current user account

    • connected (datatype: string): MUST be used for connected wallet accounts.

  • Returns

    Object

    • subscription: Array of string indicating the current subscriptions. Example: ['current', 'connected']

    • address: This is a nested JSON Object containing the subscribed addresses in the below defined format. Same as address.update notification, please refer for more details. This field MUST be included in the response when the wallet receives a subscription request i.e. when type == 'subscribe'. This field is OPTIONAL in the response when the wallet receives an un-subscription request i.e. when type == 'unsubscribe'.

    Returns errors

    • Rejected by user

    Account Format:

    : Boolean (DEFAULT:
    false
    ).
    • true: the aepp is indicating that it is expecting a signed transaction back in return and do not want the wallet to perform a transaction broadcast.

    • false: the aepp wants the wallet to sign and broadcast the transaction and return only the transaction id.

    Returns

    Object

    • result: this can be either of two values depending on the request (as mentioned in the above description of return):

      • signed transaction: signed encoded transaction (Datatype: String).

      • transaction hash: encoded transaction hash (Datatype: String).

    Returns errors

    • Invalid transaction

    • Rejected by user

    • Broadcast failed

    current: Object containing only a single account currently in use by the wallet. The account MAY also have an embedded name key which is a human-readable name for the account.

  • connected: Object containing multiple connected accounts. The accounts MAY also have an embedded name key which is a human-readable name for the account.

  • Account Format:

      {
          "<subscription_type>": {
              "<account_public_key>": {
                  "name": "<optional_human_readable_account_name>"
              }
          }
      }
      {
          "<subscription_type>": {
              "<account_public_key>": {
                  "name": "<optional_human_readable_account_name>"
              }
          }
      }

    AE MDW Architecture

    The new Aeternity Middleware is a complete rewrite of the legacy middleware.

    Goals

    • Versioned API: Implement a versioning strategy for the API to ensure backward compatibility and allow for future updates without breaking existing integrations. This helps to manage changes and provide a stable interface for clients.

    • Rapid Sync Speed: Optimize the sync process to achieve faster data synchronization. This can involve improving algorithms, utilizing parallel processing, optimizing database queries, or implementing efficient caching mechanisms. By reducing sync times, you can provide real-time or near real-time data updates to users.

    • Lean, Fast, and Easy Development and Deployment: Focus on improving the middleware's performance, reducing resource consumption, and enhancing its development and deployment process. Employ efficient coding practices, utilize lightweight frameworks, and automate deployment pipelines to streamline development and ensure faster, hassle-free deployments.

    • Reliable Paginated Retrieval: Enhance the API endpoints to support reliable paginated retrieval of information. Implement mechanisms such as cursor-based pagination or offset-based pagination to allow clients to retrieve data in manageable chunks, improving performance and preventing overwhelming large result sets.

    • Complex Search Queries: Enable the ability to perform complex search queries across multiple endpoints. Implement advanced search capabilities, such as filtering, sorting, and aggregations, to empower users to retrieve specific and relevant information from the middleware. This can be achieved by integrating powerful search engines or implementing custom search functionalities.

    Implementation keeping these goals in mind should result in a middleware usable as a data source for the frontend, as well as a generic service component in any other setup working with Aeternity chain.

    Design

    The design decision with the greatest impact was to run the middleware logic in the same BEAM process where AE node runs.

    By using Elixir for implementation, we can understand middleware as an application running alongside the AE node, via.

    The extension of this decision is using the same database as AE node does (RocksDB).

    The benefits of these decisions were:

    • No network transfers between middleware and AE node

    • No network transfers between middleware and datastore

    • Much simpler and cheaper flow of data

    • Significant speedup in syncing (approx 100 times faster)

    Main components

    Middleware could be understood as an application running inside of Aeternity node OS process, along with Aecore application which implements the Aeternity node logic.

    Image below depicts how these two large blocks fit together.

    Database model

    By merging the database types of AE node and Middleware, we can save a significant amount of space and work with both datasets in the same way - using RocksDB transactions and working with similar data model - sets of records.

    The Middleware keeps track of several distinct types of information:

    • Plain data indices - blocks, transactions and ids (public keys) inside transactions - keyed by integers or tuples of integers

    • Objects with lifecycle - names, oracles and channels - keyed by strings or hashes

    • Supporting information - origin of objects and data, valency of public keys, name ownership and pointers

    • Feature specific information - contract logs, events and calls, AEx9 and AEx141 (token) support

    All DB tables used by Middleware are of type ordered_set. All keys of the tables (except - oracle identifiers which are public keys) are then meaningfully ordered - either by history (blocks, transactions) or lexicographically (names).

    Plain data indices don't evolve - change their state - as the chain progresses. A spend transaction (for example) is still the same transaction, 1 or 100K generations after it was executed.

    Objects with the lifecycle are different. As the chain progresses, each object changes its state at specific heights. The state of the object and height when the state is changed depends on the sequence of transactions related to the object.

    For each new generation, the sync process needs to check if some objects expired.

    The lifecycle model of names, oracles and channels have the following states:

    • active - after claim/create/register transaction, extended by update/extend transaction

    • inactive - happens automatically after time period (or, for names via revoke or close transactions)

    Supporting information is needed for quick resolving of the origin (of name, oracle, contract or channel) or database invalidations in case of chain fork event. Another example of supporting information is tracking of the counts of public keys in transaction fields. These counts are used for optimization of transaction queries.

    When constructing detailed replies to the requests, Middleware often looks into data belonging to the AE node's Merkle-Patricia Tries.

    Plain data indices

    Block index

    The key and micro blocks are identified by hash, but for usable investigation of history or specifying the scope we want to look into, integer indices are very useful. From the hash of the block only, we can't know which generation the block belongs to, and by extension, we don't know which block precedes it or succeeds it.

    The block index solves this by indexing the block hash with tuple in the format:{key_block_index, micro_block_index}

    key_block_index identifies the generation (or height) of the block,micro_block_index identifies the position of the micro block in the generation.

    Both indices start from 0, but since we are mapping two different types of block to the same set, we need a special value of micro_block_index for the key block. Since the key block starts the generation, and is followed by micro blocks with micro block index from 0, the special micro block index for key block has always the value -1.

    This ensures ordering of both key and micro blocks as per Erlang's term order.

    The database model of the table record is defined as:

    Table holding these records is Model.Block.

    Transaction index

    Transaction index is a non-negative, always increasing integer, uniquely identifying the transaction.

    It is a fundamental piece of information used as a reference to transactions in all other, specialized indices in the Middleware.

    Specialized indices like time, type or field are not unique on their own, so for the purpose of ensuring uniqueness of specialized index entries, transaction index is part of the key. The database model of the table record is defined as:

    The table holding these records is Model.Tx.

    The id/hash of the transaction is used for fetching the transaction details.

    Since the transaction index is an integer, it's easy to see which transaction precedes or succeeds another transaction. Transaction index also allows us to specify a scope (start_index..end_index) in the queries to state what we are interested in.

    Specialized index - time

    The time index is useful for mapping time to the transaction. While the public endpoints don't support time based queries, the internal query language supports it.

    The database model of the table record is defined as:

    Stored in table Model.Time.

    The time (in milliseconds) marks when the whole micro block is added to the DB. Since there can be many transactions in one micro block, the transaction index is used in the key to keep uniqueness of the time entry.

    Specialized index - type

    The type index is mapping transaction type to the transactions. It allows us to quickly filter transactions per transaction type, and are also used for queries with multiple types or type groups.

    The database model of the table record is defined as:

    Stored in table Model.Type.

    Similarly as in time record key, the transaction index serves the purpose of keeping uniqueness of the type record.

    Objects with lifecycle

    Representing objects with a lifecycle is a lot more challenging than plain data. While plain data like blocks or transactions are inserted once during syncing, objects with lifecycles need to be actively managed and potentially updated every time a new generation starts.

    The simplified model of objects has states:

    • in auction (some names only (*))

    • active

    • inactive

    (*) names (without domain) shorter than 12 ascii characters and claimed after Lima hard-fork

    After objects expire, they are in an inactive state, and can be moved to an active (or "in auction") state again. The periods during which the objects are in an active state are called "epochs".

    The state changes are tracked via manipulating of expiration table records stored in object specific tables, defined as:

    The states are mapped to DB tables - e.g. if some object is stored in it's active table, we know the object is in active state. Changing states means removing the object from one table, and inserting it into another. This way we can conveniently list objects of specific state, and have them sorted lexicographically where it makes sense (e.g. names).

    A lot of information in objects takes the shape named as bi_txi_idx, composed of{block_index, txi_idx} where the block index is {key block index, micro block index} and the txi_idx is composed of {transaction index, contract call index} where the contract call index is -1 is the raw transaction (no contract call) is being referenced.

    Names

    Names use following expiration tables for tracking generations when are the states changed:

    • Model.AuctionExpiration

    • Model.ActiveNameExpiration

    • Model.InactiveNameExpiration

    The auction table record has following definition:

    The name table records represent both active and inactive names, depending on the table there are stored:

    Tables below store the actual objects:

    • Model.AuctionBid (auction)

    • Model.ActiveName (name)

    • Model.InactiveName (name)

    Oracles

    Oracles use following expiration tables for tracking generations when are the states changed:

    • Model.ActiveOracleExpiration

    • Model.InactiveOracleExpiration

    The oracle table records represent both active and inactive oracles, depending on the table there are stored in:

    Tables below store the actual objects:

    • Model.ActiveOracle

    • Model.InactiveOracle

    Supporting information

    Tables for keeping supporting information are needed for several reasons:

    Tracking origin of objects

    When objects (with or without lifecycle) like contracts, channels, oracles and names are created via their creation transaction, the identifier of such objects is not part of the creation transaction. It is useful to maintain the mapping between transactions and the created objects.

    The origin table record has the following definition:

    Rev origin records are kept in the Model.RevOrigin table.

    In both origin and rev_origin models, ideally we could represent the necessary information without storing the transaction type. The reason why we need transaction type here, is because oracles are identified with the same public key as the account which created the oracle. Since we don't keep tags (e.g.: account_pubkey, contract, oracle, ...) in our identifiers - just public key binaries - the transaction type allows us to differentiate between spend transactions and oracle transactions.

    Tracking public keys inside transaction fields and their valency

    The query language supports constructs where we can provide identifiers in the transaction fields to match.

    For illustration, a typical spend transaction looks as follows:

    Here, the identifiers in transaction fields we index would be sender_id (at position 1) and recipient_id (at position 2) - extracted from the AE node spend transaction representation, having the fields: [sender_id,recipient_id, amount, fee, ttl, nonce, payload].

    The field table record allowing us to quickly operate on this information is defined as:

    Records of this shape are stored in the Model.Field table.

    When the query contains more than one transaction field to match, we have several ways to search for the result. The role of the query optimizer is to select the optimal way to traverse the tables. For this selection, the query optimizer uses the counts of the occurrences of the public keys in the transaction fields.

    Below is the definition of the table records keeping this information:

    Records of this shape are stored in table Model.IdCount.

    Tracking name ownership and pointees

    The data stored by the AE node name system doesn't provide all the information we want to be able to query. Due to this reason, we need to maintain separate tables.

    Tables Model.AuctionOwner and Model.ActiveNameOwner hold answers to the query which names (in auction, or currently active) belong to a given owner public key.

    The table record is defined as:

    Another table - Model.Pointee - holds answers to queries on who (which account public key) points to a name. The table record are defined as:

    State and Store

    On the latest version, a new concept called has been introduced. This concept serves as a declarative representation of the Middleware state, encompassing all the models and their key-value records in a sorted manner.

    The State is defined alongside its internal component called. The purpose of the Store is to provide an interface for getting, putting, and deleting values. This abstraction allows for flexibility in defining various types of storage that may be needed. Here are some examples:

    • : This implementation directly interacts with RocksDb, performing queries and storing data without relying on a transaction.

    • : This implementation encapsulates all operations within a RocksDb transaction.

    • : This implementation stores operations in memory using a Map data structure.

    By utilizing this functional abstraction, it becomes easier to perform in-memory syncing for a specific range (e.g., the last 10 generations) while retaining the rest of the data in a persistent storage system like RocksDb. This approach allows for efficient data management and synchronization, leveraging the benefits of both in-memory and persistent storage solutions.

    Syncing

    The goal of the syncing process is to translate AE node data to actionable middleware data which allows querying.

    The syncing process (AeMdw.Sync.Watcher) listens to the AE node top_changed event which references a new block added on the main chain. For every block added, a new message is sent to the syncing server process (AeMdw.Sync.Server) for it to be processed accordingly.

    Synchronization happens in two steps:

    First, the top state of the chain is compared to the top state of the middleware to decide on which blocks to synchronize next. Once decided which generations are going to be synced next mutations are built for each of the key/micro blocks of these generations. Secondly, the mutations are then executed.

    In order to be able to synchronize and invalidate forks data fast, the middleware stores the output of the sync data in two separate places:

    • All data generated from the genesis up to 10 generations before the top block is stored in RocksDb tables (this is done using AeMdw.Db.TxnDbStore).

    • Data from the last 10 generations is stored in memory using theAeMdw.Db.MemStore, this occurs almost instantly.

    Every time any of the last 10 generations change (via forks or new blocks added), the new generations needed to be added onto the database are first processed (if any), and then the new in-memory generations are processed.

    When retrieving data through the endpoints, the MemStore is first queried, and the results are merged with the data stored on the DbStore.

    Mutations

    Mutations are meant to be a single, atomic database change. The most basic mutation would be the WriteMutation, which simply writes a new record on a table. More complex use cases are needed when you need to read from the database to calculate the changes needed to be performed.

    Here's an example of a WriteMutation usage:

    Sync Server states and transitions

    The Sync.Server was built to be a GenStateMachine, which has the following states:

    • :idle - There's nothing to process yet.

    • :stopped - The server failed too many times, it is now in a stopped state and will retry later.

    • {:syncing_db, ref} - There's a new Task with reference ref which is syncing changes and writing them to the database.

    While in any state, if any new updates to the node change arrives (new_height) the internal state of the Server is updated, and acheck_sync event is triggered.

    While in idle state, if a check_sync event arrives, it is processed accordingly:

    • If there's at least 1 generation which should belong to the database but has not yet been synced, it spawns an new Task to store these changes and enters into {:syncing_db, ref} state. When the task is done, it triggers a :done event.

    • If there's at least 1 key or micro block that is not yet part of the memory, it spawns a new Task to store these changes and enters into{:syncing_mem, ref} state. When the task is done it triggers a :done event.

    Visualization of the different Server states:

    Database searching

    All the functionality described above - database design, syncing - has one goal, to keep database records in a shape usable for performing queries over transactions and additionally over lifecycle objects - names, channels and oracles.

    Object state query engine

    Name, oracle and channels querying works conceptually in the same way. These objects can be in several states - "inactive", "active", and in case of name also "in auction". Objects in the same state are represented by these tables:

    • Object table, keyed by identifier of the object (plain name for names and public key for oracles), e.g. Model.InactiveName, Model.InactiveOracle,Model.ActiveName, Model.ActiveOracle, Model.AuctionBid,Model.ActiveChannel, Model.InactiveChannel.

    • Expiration table, keyed by tuple {expiration height, identifier}

    All these types of tables are sorted. This allows listing of names in any state either by expiration date or plain name. Since listing of oracles by sorted public keys doesn't make much sense, although technically possible, oracles are listed by their expiration only. Since there aren't any filtering or selection criteria needed for listing these objects (just state represented by a pair of tables), no query planner is needed.

    Transaction query engine

    The transaction query engine is a core functionality of the Middleware.

    The query engine runs is several steps:

    • utilize the indices in Model.Type, Model.Time, Model.Field andModel.Tx to construct all variants how to traverse and pull the matching records from the tables

    • use Model.IdCount table to pick the optimal variant which would generate the stream of results

    The query engine doesn't provide collecting or counting or additional processing of the results - it's only goal is to return a stream of results, which can be suspended and it's continuation stored and resumed later.

    Clauses

    Without clauses, the query engine returns transactions in requested scope and direction. With clauses, the engine selects only results matching the clauses.

    The clauses are key value pairs, where the keys can be:

    • type constraints: :type, :type_group

    • generic ids: :account, :contract, :channel, :oracle, :name

    The values are either transaction types (for :type and :type_group), plain names (for :name) or identifiers - encoded public keys of accounts, contracts, oracles and channels (for fields).

    Paginated endpoints and streams

    Middleware acts as an indexing tool of the Node to provide users more useful and friendlier information. This is done mostly by indexing data that can then be queried through endpoints that provide a list of results.

    Since the amount of results for these endpoints is unlimited and can ultimately be a large number, all endpoints (since v2) are paginated by using cursors. Acursor is a reference to the next record that should be returned on the paginated list, and it should contain any information needed to reference it (numbers, string, etc). This cursor is included as a query parameter and returned on the prev and next URL of any paginated endpoint. The result of the endpoint should end up looking like this:

    Internal representation

    Internally, for all paginated endpoints, a stream is built that would then be accesed to return the list of results. This is done by using regular, usually built by using the Collection.stream/3 or Collection.stream/5 functions.

    Collection.stream(state, table, direction, scope, cursor) iterates over the keys provided by the state on that specific table, where:

    • state is the object which requires a to be initialized.

    • table is the atom specifying the table name.

    • direction is either forward or backward.

    An example of its usage is the following:

    In the first example, it iterates over the table Model.Tx where the keys are a consecutive list of txi values. It begins at txi 300, iterating over values up until 400.

    Collection.stream(state, table, cursor) is a shorthand forCollection.stream(state, table, :forward, nil, cursor).

    Scope and direction

    All endpoints that are paginated allow you to specify query parameters to scope and order the results presented. This is done via the direction and scope query parameter.

    Direction determines the order of the results, and it can be eitherdirection=forward or direction=backward.

    Scope allows to specify a range of generations endpoint points. The following values are supported:

    • scope=gen:<a>-<b> - from generation a to b (forward if a < b, backward otherwise). This is represented as {:gen, a..b} internally.

    • scope=txi:<a>-<b> - from transaction index a to b (forward if a < b, backward otherwise). Represented as {:txi, a..b}

    Appendix - reasons for a new Middleware

    We will summarize the main defects of previous middleware and the need for the rewrite.

    The legacy middleware consisted of several hosts:

    • Aeternity Node for synchronization and sourcing the chain data

    • PostgreSQL for keeping denormalized chain data

    • Server in Rust for business logic and managing requests

    • Optional NodeJS for server side rendering

    The main defects are summarized below.

    Complexity

    Splitting the functionality between logic, data and presentation parts is a common industry practice. However, it doesn't mean that this architecture should be used everywhere, especially when we want a lean, simple and fast software stack.

    Old middleware has 3-4 diverse components, where data is stored in 2 locations - AE node, and SQL host.

    New middleware has 2 components which are operationally just one OS process - the AE node with Middleware extensions, with additional middleware data in the same DB used by AE node as well.

    Instability

    The instability stems from breaking down the functionality into several components which must communicate via network. Synchronization step requires 2 network requests (4 transmissions, as request/reply) - fetching data from the node and then inserting data to the SQL.

    Client reply requires either DB network request or AE node network request, sometimes both. Network performance varies, connections between different parts of the service sometimes break.

    Another large source of service breakage is when a fork happens in the chain, resulting in crashes of the Rust server.

    Lack of performance

    Once the legacy Middleware synchronizes, the performance is tolerable, sans occasional response time spikes.

    The main problem is synchronization performance. In a hosted environment, with 400K+ generations, synchronization from scratch would take several months. Asking for data via a public AE Node endpoint, with necessary JSON encoding/decoding for network transfer is simply way too slow.

    New Middleware completely removed intra service network traffic. By placing Middleware into the AE node, we can synchronize Middleware data in less than a day.

    Incorrectness

    Legacy middleware has severely broken support for paginations. Many endpoints return just the first page and rely on retrieving older data via paginations. There are two major issues.

    Requesting a page doesn't remember the starting position - e.g. page 2 can return the same transactions as page 1 if the top of the chain changed between requests.

    Fetching data for pages from SQL doesn't use SQL cursors - it collects all entries up to those which should be in the reply, and discards all except those in the requested page. Pagination is then progressively slower with each subsequent page.

    Besides pagination being incorrect, wasteful and slow, they also allow DDOSing of the service. Malicious user just needs to send a request to a paginable endpoint, asking for a very high numbered page. This way the legacy Middleware can be tricked to collect millions of entries and trash the DB.

    Lack of flexibility

    While legacy Middleware uses the SQL for storing the denormalized data model of the chain, public endpoints don't provide any means for more flexible searching of the transaction history. The endpoints were designed only for a single purpose - to support frontend application. Another large use case, using Middleware as part of the stack for other, non-frontend related logic, is not possible with legacy Middleware.

    Changelog

    5.0.0 (2024-12-06)

    ⚠ BREAKING CHANGES

    • update to sdk 14

    • drop custom get function, require node >= 18

    • drop cjs support

    • use sdk provided filesystem util, remove aeproject util implementation

    Bug Fixes

    • build artifact files ()

    • sdk import usage ()

    Refactorings

    • drop cjs support ()

    • drop custom get function, require node >= 18 ()

    • update to sdk 14 ()

    • use sdk provided filesystem util, remove aeproject util implementation ()

    Miscellaneous

    • update dependencies ()

    • update eslint ()

    • upgrade to chai@5 for new projects ()

    • use npm pack in tests ()

    (2024-08-16)

    Bug Fixes

    • publish ()

    Miscellaneous

    • update dependencies ()

    (2024-07-22)

    Refactorings

    • replace chai/mocha with vitest ()

    Miscellaneous

    • update compatible node version ()

    • update dependencies ()

    • update dependency versions, temp fix ci ()

    (2024-04-26)

    Features

    • default to use ceres ()

    (2024-04-23)

    Refactorings

    • optimize docker healthcheck ()

    Miscellaneous

    • upgrade sdk and docker for next versions ()

    (2024-03-07)

    Features

    • add ceres initializer and docs ()

    Bug Fixes

    • add debug await key block after creating snapshot ()

    • check for actually supported node >= 16 requirement ()

    • rollback to correct height ()

    CI / CD

    • fix workflow for incompatible versions ()

    • skip certain tests for aux ci runs ()

    Testing

    • add library usage tests ()

    Refactorings

    • improve library typescript defs ()

    • init command to take current aeproject library version ()

    Miscellaneous

    • add chai as promised test rejection example ()

    • document and improve release process ()

    • improve env initialisation and test setup ()

    • introduce prettier ()

    (2023-09-20)

    CI / CD

    • add matrix for compiler/node versions ()

    • use matrix test suite ()

    Refactorings

    • improve env command ()

    Miscellaneous

    • update default compiler tag ()

    • update dependencies ()

    (2023-08-24)

    Miscellaneous

    • remove unneeded await ()

    • update sdk ()

    • update to latest compiler ()

    • upgrade to latest sdk ()

    (2023-07-18)

    Bug Fixes

    • add back wait additional block workaround ()

    Miscellaneous

    • prepare for fix release 4.8.1 ()

    (2023-07-18)

    Features

    • allow rollback to specific height ()

    Miscellaneous

    • prepare for release 4.8.0 ()

    • upgrade dependencies ()

    • upgrade node to v6.11.0 with devmode timout fix ()

    (2023-07-06)

    Features

    • upgrade to compiler 7.4.0 ()

    Miscellaneous

    • upgrade dependencies ()

    (2023-05-17)

    Miscellaneous

    • fix scripts, prepare for 4.6.3 ()

    (2023-05-16)

    Refactorings

    • use typescript to build project, migrate lib to ts ()

    Miscellaneous

    • rollback unintended code-style changes ()

    • upgrade dependencies ()

    (2023-04-12)

    Bug Fixes

    • minor fixes, adjust docs ()

    (2023-04-11)

    Features

    • upgrade to compiler image 7.3.0 for ARM64/Apple Silicon support ()

    • upgrade to sdk 13 beta and compiler 7 ()

    Miscellaneous

    • prepare for release 4.6.0 ()

    • upgrade to final release sdk ()

    (2023-03-07)

    Miscellaneous

    • update dependencies ()

    • update to node v6.8.1 ()

    (2023-03-01)

    Features

    • add support for node v6.8.0 ()

    Miscellaneous

    • deps: mkdocs version update ()

    (2023-01-09)

    Features

    • generate .gitignore ()

    Bug Fixes

    • use specific version of node to fix tests ()

    Miscellaneous

    • update dependencies ()

    Refactorings

    • remove the need for axios ()

    • simplify getFilesystem regexes ()

    (2022-11-04)

    Features

    • add image versions in env --info ()

    (2022-09-28)

    Bug Fixes

    • add missing stdlib includes in getFilesystem ()

    (2022-08-31)

    Features

    • allow usage of native docker-compose without specifying env ()

    Bug Fixes

    • correct escaping to use - in filesystem contracts ()

    (2022-08-22)

    Bug Fixes

    • use fixed compiler version as latest is not supported by sdk ()

    (2022-07-25)

    Bug Fixes

    • remove log for docker compose checks ()

    (2022-07-25)

    Bug Fixes

    • fix support for docker compose without minus ()

    (2022-07-25)

    Bug Fixes

    • add support for docker compose without minus ()

    (2022-07-08)

    Bug Fixes

    • fix dependencies upgrade, prepare for 4.1.1 release ()

    (2022-06-24)

    Features

    • adjust for sdk 12 usage ()

    • upgrade to sdk 12 ()

    Bug Fixes

    • fix breaking changes for sdk 12 usage ()

    Miscellaneous

    • prepare for 4.1.0 release ()

    (2022-04-12)

    ⚠ BREAKING CHANGES

    • improve update from previous aeproject version

    • use calldata lib sdk, use snapshotting in tests

    • tx-inspector: refactor inspector command

    • cleanup code

    Features

    • env: abort tests if env is not running ()

    • init: add optional folder parameter to init ()

    • init: check for up-to-date nodejs version ()

    • lib: add all accounts to default client ()

    Bug Fixes

    • consider env running check if any container is up ()

    • docker-compose v2 up/running check ()

    • incorrect default includes regex fix (resolves ) ()

    Refactorings

    • improve update from previous aeproject version ()

    • init: init command adjustments ()

    • prepare for new project structure ()

    • tx-inspector: refactor inspector command ()

    Testing

    • improved exec env, assert env and test results ()

    • improved exec env, assert file existence ()

    • link to use local aeproject utils ()

    Miscellaneous

    • adapt to naming convention of sdk examples ()

    • beta 5 release ()

    • beta 6 release ()

    • clean unused code and formatting ()

    use the same sdk (a90943e)

    update dependencies (5faaf66)

  • upgrade support latest aeternity node (afd36a5)

  • init: init command adjustments

  • prepare for new project structure

  • sdk 11 upgrade (#408) (44ff5db)

  • test: better example test and contract (f98e1df)

  • use updated sdk and rollback http usage (1dc45f2)

  • use calldata lib sdk, use snapshotting in tests (0c6d010)

    cleanup code (2244394)

  • cleanup folders (46d73f3)

  • deps: bump mkdocs version from 1.2.3 to 1.2.4 (59bbded)

  • deps: sdk v11.0.1 (90d9cf6)

  • prepare for 4.0.0 release (9da6a85)

  • repo: add commitlint and release-please (00d08ba)

  • repo: add issue template and action docs generation (7fc04cc)

  • repo: re-add license (85f29c9)

  • tests: happy path tests (without assertions) (f8e3e3f)

  • tests: improved env to wait for node to come up (0992920)

  • tests: more test cases (28e0859)

  • update dependencies (5650a31)

  • update dependencies (397c3c5)

  • update dependencies (c42c2e4)

  • update dependencies, add lint check (adc54a4)

  • update node, sdk & compiler version (c625c38)

  • update release please ci action (aa56ac6)

  • update to lockfile v2 (0e3e3ee)

  • update version, use fixed node image (bf92a20)

  • update version, use latest bundle image (3b5cc81)

  • f4059cd
    5609660
    a92df6e
    ef569b9
    ecbdf3c
    93cf8c5
    6494ded
    db4f3e5
    dce8f50
    e82cd51
    4.10.2
    c11f856
    1cfc5ba
    4.10.1
    eb717e5
    97bef2c
    eee28ef
    e53bcca
    4.10.0
    104cbe4
    4.9.1
    77f7506
    63b0fb2
    4.9.0
    0721822
    53fa2f9
    f50464e
    17a8262
    e2080d2
    e41d0b7
    cd81972
    30a83f8
    124e8c9
    6a0d491
    b302647
    d39e5d4
    388f867
    4.8.3
    c6c7ea4
    0be215e
    18022a4
    068b081
    78be83d
    4.8.2
    cf4b19e
    f666101
    e65237c
    6de93f6
    4.8.1
    1a135b4
    b448b44
    4.8.0
    670c11e
    5462ea3
    6f570b3
    3c5d558
    4.7.0
    72cccf7
    03a0caa
    4.6.3
    06ea397
    4.6.2
    1f7a164
    a4fd777
    3482f75
    4.6.1
    abaa364
    4.6.0
    83814e2
    0b717a5
    9910426
    2317283
    4.5.1
    fb1578c
    f247730
    4.5.0
    b6b97cd
    138e5b5
    4.4.0
    eecf555
    53a2446
    e88b1df
    ed6cea0
    61e4dbc
    4.3.0
    d2c9ba8
    4.2.1
    c29ae0d
    4.2.0
    f8577e2
    3704bab
    4.1.5
    945e3a5
    4.1.4
    b372d69
    4.1.3
    84561fe
    4.1.2
    6e44339
    4.1.1
    58a83ab
    4.1.0
    5fda5f2
    8f8de6f
    357c3d5
    045f61e
    4.0.0
    fb780c6
    ad00bea
    66edcf4
    f97e992
    deaf578
    7d1d37a
    #394
    d81fc8a
    d71bfe8
    8f2f47d
    64d58d0
    b500968
    a79bcf3
    a9a96e1
    e058b54
    3d22a19
    8afb026
    1bc12bb
    11ba445

    Significant speedup when serving requests

  • Greater stability (network isn't a variable factor anymore, all data are local)

  • Easier deployment and upgrading

  • Model.ActiveOracleExpiration
  • Model.InactiveOracleExpiration

  • Model.OracleQueryExpiration

  • NullStore: This implementation does not return any results or store anything, primarily used for testing purposes.
  • {:syncing_mem, ref} - There's a new Task with reference ref which is syncing changes and writing them to memory.

  • , e.g.
    Model.InactiveNameExpiration
    ,
    Model.InactiveOracleExpiration
    ,
    Model.ActiveNameExpiration
    ,
    Model.ActiveOracleExpiration
    ,
    Model.AuctionExpiration
    .
  • Activation tables, keyed by the tuple {activation height, identifier}, e.g.Model.ActiveNameActivation, Model.InactiveNameActivation,Model.ActiveChannelActivation.

  • wrap the optimal variant producing the results in lazy, on-demand stream

    freestanding fields: :sender_id, :from_id, :contract_id, ...

  • typed fields: :'spend.sender_id', :'name_transfer.recipient_id', ...

  • scope is either nil or a tuple of two values {first_key, last_key}, this has to be provided in forward order (e.g. first_key <= last_key always).

  • cursor is the initial key to start iterating from. If nil it will begin from the first element of the scope.

  • internally. This last one is DEPRECATED, to avoid exposing internal information like
    txi
    , which is not a concept used in the node.
    State
    Store
    DbStore
    TxsDbStore
    MemStore
    Elixir Streams
    State
    Store
    MDW Architecture
    Sync Server

    Migration to 13.0.0

    This guide describes all breaking changes introduced with v13.0.0.

    Wallet

    onSign, onMessageSign callbacks were removed on the wallet side

    Check allowance to sign on the account side instead, using aeppOrigin, aeppRpcClientId options.

    Aepp

    All wallet provided nodes have the same name

    Specified in name option of connectToWallet.

    Select option removed from connectToWallet

    If you are using connectNode then the current node would always be the same as wallet provides.

    Contract

    ACI format used the same as returned by aesophia_cli

    aesophia_http old format

    aesophia_cli format

    params argument in $deploy and $call is required

    Contract methods accessible on the instance itself

    Apply a patch:

    contract.methods.<name>.get,send removed

    Use callStatic option instead.

    contract.bytecode,sourceCode moved to contract.$options

    contract.calldata renamed to contract._calldata

    Use contract._calldata (considered to be a private field) or aepp-calldata package directly.

    contract.options renamed to contract.$options

    contract.deployInfo removed

    Use the return value of contract.$deploy instead.contract.deployInfo.address moved to contract.$options.address.

    contract.decodeEvents renamed to contract.$decodeEvents

    contract.call renamed to contract.$call

    contract.compile renamed to contract.$compile

    contract.deploy renamed to contract.$deploy

    createAensDelegationSignature, createOracleDelegationSignature removed

    Use createDelegationSignature instead.

    use sourceCode instead of source

    It is related to getContractInstance and signing using Generalized accounts. Apply a change:

    getContractInstance accepts address instead of contractAddress

    Apply a change:

    getContractInstance function replaced with Contract class

    Apply a patch:

    AeSdk.getContractInstance renamed to AeSdk.initializeContract

    prepareTxParams, getVmVersion are not exported anymore

    Use buildTx instead.

    isGA method removed

    Use (await aeSdk.getAccount(<address>)).kind === 'generalized' instead.

    Transaction builder

    writeInt function removed

    Use toBytes util instead.

    returnType of contract call result structure is a value of CallReturnType enum

    Apply a patch:

    writeId, readId functions removed

    Use transaction builder instead.

    readPointers, buildPointers functions removed

    Use transaction builder instead.

    formatSalt function removed

    Use Buffer.from(<salt>.toString(16).padStart(64, '0'), 'hex') instead.

    validateParams, unpackRawTx functions removed

    Use transaction builder instead.

    AMOUNT constant removed

    If necessary, use 0 instead.

    StateTrees fields decoded as objects mapping key to decoded entry instead of internals

    The content of Tag.*Mtree entries decoded and moved to payload field

    TX_SCHEMA, TxParamsCommon, TxSchema, TxTypeSchemas are not exported anymore

    TX_TTL is not exported anymore

    Use 0 instead.

    Enum FIELD_TYPES is not exported anymore

    Not able to build/unpack CompilerSophia entry (tag 70)

    Enums PROTOCOL_VM_ABI, interface CtVersion not exported anymore

    Enums VM_VERSIONS, ABI_VERSIONS, PROTOCOL_VERSIONS renamed

    They are exported as VmVersion, AbiVersion, ConsensusProtocolVersion.

    stateHash of Channel entry decoded as st_-prefixed string instead of hex

    SpendTx payload doesn't accept arbitrary strings anymore

    Provide a ba_-encoded string instead.

    verifyTransaction doesn't accept parent tx types anymore

    buildTx doesn't accept excludeKeys option anymore

    Consider opening an issue, if you need this functionality.

    Use version instead of VSN, vsn in unpackTx, buildTx

    buildTx accepts transaction type and version in the first argument

    Apply a change:

    AeSdk.buildTx accepts tag in options

    Replace aeSdk.buildTx(Tag.SpendTx, { ... }) with aeSdk.buildTx({ ..., tag: Tag.SpendTx }).

    sync buildTx accepts denomination in the first argument

    unpackTx return an object of transaction parameters

    Use unpackTx(...) instead of unpackTx(...).tx.

    unpackTx doesn't return rlpEncoded anymore

    Use decode(buildTx(unpackTx(...))) instead.

    unpackTx doesn't return txType anymore

    Use unpackTx(...).tag instead.

    buildTx return string instead of object

    Use just buildTx(...) instead of buildTx(...).tx.

    buildTx doesn't return txObject anymore

    Use unpackTx(buildTx(...)) instead.

    buildTx doesn't return binary anymore

    Use require('rlp').decode(decode(buildTx(...))) instead.

    buildTx doesn't return rlpEncoded anymore

    Use decode(buildTx(...)) instead.

    key of MtreeValue entry decoded as a buffer instead of a hex

    TxBuilder accepts and returns poi field unpacked as TreesPoi

    get method of MPTree accepts and returns typed values

    Apply a change:

    Compiler

    Compiler export renamed to CompilerHttp

    removed AeSdk:compilerUrl, AeSdk:setCompilerUrl

    A compiler instance needs to be passed explicitly in onCompiler option:

    Methods of CompilerHttp moved to api property

    Apply a patch:

    Dropped compatibility with aesophia_http below 7.1.1, aesophia_cli below 7.0.1

    Account

    createGeneralizedAccount accepts sourceCode in options

    Apply a patch:

    createMetaTx removed

    Use AccountGeneralized.signTransaction instead.

    AccountRpc constructor accepts arguments one by one

    Apply a change:

    AccountMemory requires networkId in signTransaction

    AccountBase simplified

    • networkId removed

    • getNetworkId method removed

    • signTransaction, signMessage made abstract

    address in AccountBase is a property

    Apply a change:

    MemoryAccount accepts only secretKey

    Apply a change:

    MemoryAccount is not compatible with GA

    Apply a change:

    Node

    url property of Node removed

    Use autorest's $host property instead.

    Oracle

    QUERY_FEE is not exported anymore

    Use 30000 instead if necessary.

    Oracles created without queryFee by default

    Specify queryFee in registerOracle if needed.

    AeSdk:extendOracleTtl, AeSdk:respondToQuery doesn't accept oracleId

    Remove the first argument.

    onQuery callback of pollForQueries, oracle.pollQueries accepts a single query

    It was accepting an array before. Apply a patch:

    Chain

    send inlined into sendTransaction

    Pass not signed transaction to sendTransaction. If you need to post signed transaction use Node:postTransaction.

    AENS

    height removed from the output of aensPreclaim

    Use blockHeight instead:

    Channel

    Channel:state returns unpacked entries

    Use buildTx to pack them back if needed.

    All channel events emitted in snakeCase

    Affected events: 'own_withdraw_locked', 'withdraw_locked', 'own_deposit_locked', 'deposit_locked', 'peer_disconnected', 'channel_reestablished'.

    Channel:poi returns unpacked TreesPoi

    Use just await channel.poi(...) instead of unpackTx(await channel.poi(...)).

    Other

    onAccount doesn't accept keypair

    Apply a change:

    bigNumberToByteArray removed

    Use toBytes instead.

    str2buf function removed

    Use Buffer.from(<data>, <encoding>) instead.

    getAddressFromPriv doesn't accept private key as base64-encoded or raw string

    isValidKeypair doesn't accept public key as base64-encoded string

    bytesToHex function removed

    Use Buffer.from(<bytes>).toString('hex') instead.

    hexToBytes function removed

    Use Buffer.from(<hex string>, 'hex') instead.

    rename umd export to Aeternity

    Subpaths imports of SDK are not allowed

    SDK does versioning only for the API provided in the root export. Replace subpaths imports with imports of the package root.

    Removed getNetworkId from AeSdkBase

    Use Node.getNetworkId instead.

    address a getter in AeSdkBase

    Apply a change:

    addAccount is a sync function

    verifyMessage removed from accounts and AeSdkBase

    Use verifyMessage exported in the root instead.

    verify and verifyMessage accepts address instead of hex string or Uint8Array

    Convert public key in Uint8Array to address using encode(pk, 'ak'). Convert public key in hex to address using encode(Buffer.from(pk, 'hex'), 'ak').

    node@12 not supported

    Use [email protected] or newer.

    removeAccount throws an error if the account is not found

    signMessage always returns Uint8Array

    Use Buffer.from(signature).toString('hex') to convert it to hex.

    encryptKey, decryptKey are not exported anymore

    Use 'sha.js' and 'aes-js' packages directly instead.

    sha256hash is not exported anymore

    Use SubtleCrypto.digest or sha.js package instead.

    height method removed

    Use getHeight instead.

    signUsingGA method removed

    Use AccountGeneralized.signTransaction instead.

    POINTER_KEY_BY_PREFIX removed

    Use getDefaultPointerKey instead.

    ID_TAG_PREFIX, PREFIX_ID_TAG, ID_TAG removed

    Use transaction builder instead.

    TX_TYPE removed.

    Use Tag instead.

    GAS_MAX removed

    The maximum gas limit depends on transaction size, this value is outdated, sdk check/provides gasLimit by itself while building a transaction.

    calculateMinFee removed

    Use buildTx to generate a transaction, unpack it and refer to fee field.

    salt, createSalt removed

    Use genSalt instead.

    Pointer removed

    Use NamePointer from apis/node instead.

    defrecord :block,
      [index: {-1, -1}, # {key_block_index, micro_block_index}
      tx_index: nil, # first transaction index in this block
      hash: <<>>] # block hash for lookup into AE node DB
    defrecord :tx,
      [index: -1, # transaction index value
      id: <<>>, # transaction hash for lookup into AE node DB
      block_index: {-1, -1}, # in which block the tx resides
      time: -1] # micro block time in milliseconds
    defrecord :time,
      [index: {-1, -1}, # as {micro block milliseconds, transaction index}
      unused: nil # unused as RocksDB value
    defrecord :type,
      [index: {nil, -1}, # as {transaction type, transaction index}
      unused: nil] # unused as RocksDB value
    defrecord :expiration,
      [index: {nil, nil}, # {expiration height, object identifier}
      value: nil] # possible metadata
    defrecord :auction_bid,
      # ame, bi_txi, expire height, owner, previous bids [bi_txi, ..]}
      [index: plain_name(),
       block_index_txi_idx: bi_txi_idx(),
       expire_height: height(),
       owner: pubkey(),
       bids: [bi_txi_idx()]]
    defrecord :name,
      [index: nil, # plain name
      active: nil, # height from which name became active
      expire: nil, # height when the name expires (expired)
      claims: [], # claims (auction bids) as [bi_txi]
      updates: [], # updates as [bi_txi]
      transfers: [], # transfers as [bi_txi]
      revoke: nil, # revoke transaction as bi_txi or nil
      auction_timeout: 0, # if 0, name wasn't auctioned
      owner: nil, # owner's public key
      previous: nil] # previous version of the name as #name{}
    defrecord :oracle,
      [index: nil, # public key of the oracle
      active: nil, # height from which the oracle became active
      expire: nil, # height when the oracle expires (expired)
      register: nil, # registration bi_txi
      extends: [], # extensions a [bi_txi]
      previous: nil] # previous version of the oracle as #oracle{}
    defrecord :origin,
      [index: {nil, nil, nil}, # {tx type, object pubkey, tx index}
      tx_id: nil] # transaction hash
      # The records are stored in the Model.Origin table.
      # For the query execution logic and invalidations, rev_origin table record is needed:
    defrecord :rev_origin,
      [index: {nil, nil, nil}, # {tx index, tx type, object pubkey}
      unused: nil]
    %{
      block_hash: <<201, 228, 14t6, …>>,
      block_height: 322515,
      hash: <<72, 94, 35, …>>,
      micro_index: 57,
      micro_time: 1601651331156,
      signatures: [<<1, 120, 56, ...>>],
      tx: %{
        amount: 20000,
        fee: 19320000000000,
        nonce: 3287310,
        payload: "322515:kh_2m...iH:1601651331",
        recipient_id: {:id, :account, <<123, 165, 128, ...>>},
        sender_id: {:id, :account, <<123, 165, 128, ...>>},
        ttl: 322525,
        type: :spend_tx
      },
      tx_index: 16284706
    }
    defrecord :field,
      # {tx_type, tx_field_pos, object_pubkey, tx_index}
      [index: {nil, -1, nil, -1},
      unused: nil]
    defrecord :id_count,
      [index: {nil, nil, nil}, # {tx type, field position, object pubkey}
      count: 0] # valency
    defrecord :owner,
      [index: {pubkey, object}, # {owner pubkey, object pubkey}
      unused: nil]
    defrecord :pointee,
      # {pointer value (name), {block index, tx index}, pointer key}
      [index: {nil, {{nil, nil}, nil}, nil},
      unused: nil]
    ...---- First n - 10 gens -----> <-------------- Top 10 gens ----------------->
    +-----+----+----+---------+-----+---------+----+----+----+-----+------+----+---
    | ... K(n-11) | M0 | M1 | | ... | K(n-10) | M0 | M1 | M2 | ... | K(n) | M0 | M1
    +-----+----+----+---------+-----+---------+----+----+----+-----+------+----+---
    ...--- Synced into Rocksdb ----> <----------- Synced into memory ------------->
    tx = Model.tx(index: 1, id: <<0, 21, 30>>, block_index: {1, 10}, time: 1_000_000)
    mutation = WriteMutation.new(Model.Tx, tx)
    
    state = State.new()
    State.commit(state, [mutation])
    {
      "data": [
        record1,
        record2,
        ...
      ],
      "next": "/v2/...?cursor=<cursor-next>"
      "prev": "/v2/...?cursor=<cursor-prev>"
    }
    state = State.new()
    stream = Collection.stream(state, Model.Tx, :forward, {200, 400}, 300)
    Enum.take(stream, 4) # => [200, 201, 202, 203]
    
    stream = Collection.stream(state, Model.ActiveName, :backward, nil, "c.chain")
    Enum.take(stream, 4) # => ["c.chain", "ba.chain", "b.chain"]
    {
      "encoded_aci": { contract: <1> },
      "external_encoded_aci": [<2>]
    }
    [<2>, { contract: <1> }]
    -const contract = aeSdk.getContractInstance(<contract args>);
    +const contract = aeSdk.getContractInstance<{ foo: (a: bigint) => bigint }>(<contract args>);
    -await contract.methods.foo(<arguments>);
    +await contract.foo(<arguments>);
    -aeSdk.getContractInstance({ source: <contract source code>, ... })
    +aeSdk.getContractInstance({ sourceCode: <contract source code>, ... })
    -aeSdk.spend(..., { authData: { source: <contract source code>, args: [...] } })
    +aeSdk.spend(..., { authData: { sourceCode: <contract source code>, args: [...] } })
    -aeSdk.getContractInstance({ contractAddress: <contract address>, ... })
    +aeSdk.getContractInstance({ address: <contract address>, ... })
    -contract = await getContractInstance(<options>);
    +contract = await Contract.initialize(<options>);
    -contractCall.returnType === "error"
    +contractCall.returnType === CallReturnType.Error
    -payload: 'test',
    +payload: encode(Buffer.from('test'), Encoding.Bytearray),
    -buildTx({ ... }, Tag.SpendTx, { version: 2 })
    +buildTx({ ..., tag: Tag.SpendTx, version: 2 })
    -buildTx({ ... }, { denomination: AE_AMOUNT_FORMATS.AETTOS })
    +buildTx({ ..., denomination: AE_AMOUNT_FORMATS.AETTOS })
    -unpackTx(tree.get(decode('ak_97...')))
    +tree.get('ak_97...')
    -import { AeSdk } from '@aeternity/aepp-sdk';
    +import { AeSdk, CompilerHttp } from '@aeternity/aepp-sdk';
    
    const aeSdk = new AeSdk({
    -  compilerUrl: <compiler url>,
    +  onCompiler: new CompilerHttp(<compiler url>),
    });
    -compilerHttp.generateACI({ code: sourceCode });
    +compilerHttp.api.generateACI({ code: sourceCode });
    -aeSdk.createGeneralizedAccount('authorize', sourceCode, ['arg-1']);
    +aeSdk.createGeneralizedAccount('authorize', ['arg-1'], { sourceCode });
    -new AccountRpc({ rpcClient: <rpc client>, address: <address> })
    +new AccountRpc(<rpc client>, <address>)
    -await accountMemory.address(options)
    +accountMemory.address
    -new MemoryAccount({ keypair: { publicKey: 'ak_..', secretKey: <secret key> } })
    +new MemoryAccount(<secret key>)
    -new MemoryAccount({ gaId: <address> })
    +new AccountGeneralized(<address>)
    -aeSdk.pollForQueries(oracleId, (queries) => queries.forEach(handleQuery));
    +aeSdk.pollForQueries(oracleId, handleQuery);
    const res = aeSdk.aensPreclaim('name.chain');
    -res.height
    +res.blockHeight - 1
    -aeSdk.<metnod name>(..., { onAccount: <keypair> })
    +aeSdk.<metnod name>(..., { onAccount: new MemoryAccount(<keypair>.secretKey) })
    -import MemoryAccount from '@aeternity/aepp-sdk/es/account/Memory.mjs';
    +import { MemoryAccount } from '@aeternity/aepp-sdk';
    -await aeSdk.address()
    +aeSdk.address

    CHANGELOG

    Changelog

    All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

    7.0.0 (2025-01-30)

    aecli migrates to a new secret key format. Use SDK's page to convert secret keys.

    ⚠ BREAKING CHANGES

    • account: aecli account address accepts --secretKey instead --privateKey

    • contract: uses v8 compiler by default

    • contract: not compatible with v7 compiler

    Features

    • narrow first column and remove _ in tables ()

    • oracle: make oracleTtl optional ()

    Bug Fixes

    • contract: print details of static call ()

    • name keystore as filename instead of full path ()

    • race condition while setting options ()

    Commits with breaking changes

    • account: consistently use secret key instead private key ()

    • deps: update sdk to 14.0.0 ()

    (2024-04-22)

    Bug Fixes

    • don't show stacktrace for ACI-not-match error ()

    • update sdk to 13.3.2 ()

    (2024-04-16)

    Check out the new documentation at

    ⚠ BREAKING CHANGES

    oracle: aecli oracle get removed

    Use aecli inspect instead.

    oracle: aecli don't accept already known account address in oracles

    Remove extra argument:

    account: aecli account verify-message accepts signer address instead wallet

    chain: aecli chain network_id removed

    Use aecli chain status instead.

    Commands don't accept --no-waitMined anymore

    In the most cases transactions gets mined immediately. In case of NameClaim, tx needs to be submitted in the next keyblock after preclaim. In that case it would be mined also immediately, with no early name revealing. If still needed, use aecli chain broadcast tx_... --no-waitMined instead.

    account: account save removed

    Use account create instead:

    account: aecli account spend renamed to aecli spend

    chain: aecli connects to mainnet by default

    Use the below to switch back to testnet.

    require nodejs@18 or newer

    Because nodejs@16 is not maintained currently.

    name: name lookup command removed

    Use inspect instead.

    account: account generate command removed

    Use account create in a cycle instead.

    crypto: crypto sign command removed

    Use account sign instead.

    crypto: crypto unpack command removed

    Use inspect instead.

    crypto: crypto decode removed

    Use another base58 decoder if necessary.

    account: account balance, account nonce commands removed

    Use inspect <ak-address> instead.

    account: remove useless output option

    account: account spend returns unwrapped JSON

    account: account transfer command removed

    Use spend instead.

    Features

    • account: accept password in env variable, notice password recorded ()

    • account: show approximate tx execution cost before asking password ()

    • account: verify message by address instead wallet ()

    • aens: don't require name ttl in

    Bug Fixes

    • account: don't ask for password if it is empty ()

    • account: don't ask password if it is not required ()

    • aens: handle revoked names, refactor docs ()

    • chain: use mainnet instead testnet by default ()

    Other commits with breaking changes

    • account: combine account create and account save ()

    • account: combine spend and transfer commands ()

    • account: move aecli account spend to aecli spend

    (2023-04-08)

    ⚠ BREAKING CHANGES

    The format of contract descriptor file changed

    Contract descriptors needs to be regenerated.

    contract: contract call accepts wallet_path as the last argument

    For example, replace

    with

    account spend doesn't accept denomination parameter

    Features

    • accept amount suffixed with ae instead of denomination option ()

    • add select-node, select-compiler commands ()

    • add update-notifier to ask user to switch to the latest version ()

    Bug Fixes

    • account: show network id in sign call output ()

    • contract: allow to static calls without wallet ()

    • contract: stringify maps as arrays ()

    • don't show stack trace when entered an invalid password to wallet ()

    (2022-07-28)

    Features

    • don't print stack traces for cli errors ()

    Bug Fixes

    • commands in crypto module ()

    • contract: always store aci in descriptor, override descr by options ()

    • contract: clear error when can't parse call arguments ()

    • contract: create file descriptor at not existing path ()

    (2022-04-07)

    ⚠ BREAKING CHANGES

    • contract deploy: accept args and bytecode, custom descrPath

    Run aecli contract deploy --help to get the latest documentation.

    • contract call: accept arguments as JSON-encoded array

    Affected commands: contract deploy, contract call.

    • contract: decode call result, make args flexible

    Removed commands: contract encodeData, contract decodeCallData. Added commands: contract encode-calldata, contract decode-call-result.

    Features

    • contract deploy: accept args and bytecode, custom descrPath ()

    Bug Fixes

    • account transfer: remove unimplemented excludeFee option ()

    • account transfer: remove unused denomination option ()

    • contract call: accept arguments as JSON-encoded array ()

    • name full-claim: key of created pointer (

    (2021-06-10)

    Bug Fixes

    • docker: enable dry-run endpoints ()

    • test: aens suite ()

    • test: contract suite ()

    • test: oracle suite lint ()

    Features

    • ci: add github actions workflow ()

    • env: bump node and compiler version ()

    • oracle: implement Oracle Test's ()

    • oracle: Implement Oracle Test's ()

    (2020-06-10)

    Bug Fixes

    • AENS: Change tld from aet to chain () ()

    • Contract: Fix compiler test's ()

    • tests: Regenerate lock files to fix build on CI () ()

    Features

    • Account: Add verify-message command to account module ()

    • Account: Add message sign command ()

    • Account: Adjust printing and json serialization for sign-message result ()

    (2019-10-07)

    Features

    • Lima: Add support for lima () ()

    • Compiler: Add backend option to compiler(Can be fate or aevm. fate by default)

    • AENS: Add

    2.5.0 (2019-08-28)

    Features

    • Node Node 5.0.0-rc1 compatibility

    2.4.0 (2019-08-21)

    Features

    • ACCOUNT: Add command for generating and printing bulk of Key Pairs () ()

    2.3.0 (2019-08-05)

    Bug Fixes

    • Account: Fix --json for account commands. Add proper error code to AENS commands. () ()

    • CLI: Fix exit codes around the CLI () ()

    Features

    • sdk: Update sdk version to 4.3.0 () ()

    2.2.0 (2019-07-16)

    Features

    • Node: Compatibility for node 4.0.0

    • Inspect Ability to unpack transaction using inspect command

    Bug Fixes

    • CLI: Fix exit codes around the CLI () ()

    2.1.0 (2019-05-20)

    Bug Fixes

    • README: Adjust readme () ()

    Features

    • Fortuna: Add Fortune(3.0.0) compatibility

    • Account: Feature/allow to spend percentage of balance (#68)

    (2019-04-26)

    Features

    • Commitizen: Configurte commitizen () ()

    • CI: Configure Jenkins pipeline

    • Account: Add option to get balance on specific heigh/hash

    BREAKING CHANGES

    • Remove contract call and deploy commands. Remove aens claim, revoke andupdate commands.

    1.0.1 (2019-01-10)

    Features

    • Contract: Add contract inspect command

    • CLI Improve error printing

    • TX: Add --networkId flag to each command which build a tx

    • CLI: Remove default fee for each command's (SDK calculate fee by itself)

    BREAKING CHANGES

    • Default node url changed to

    aepp details

    reference

    AECLI commands

    • account

    aepps list

    aens: commitmentId removed from the JSON output of aecli name pre-claim Use tx.commitmentId instead.

  • some fields in node responses returned as numbers instead of strings Namely:

    • abiVersion

    • vmVersion

    • callerNonce

    • senderNonce

    • oracleTtl.value

    • responseTtl.value

    • queryTtl.value

    • endsAt

  • tabbed data aligned without underscores

  • width of the first column in tabbed data depends on the content

  • name extend
    (
    )
  • aens: print missed name details, be human-friendly (91c7731)

  • aens: show auction details (75217c3)

  • chain: show protocol version in config (35496fb)

  • contract: accept amount in contract and tx builder commands (1dbd195)

  • show extra info in tx details, consistent fields naming (5a9f4cc)

  • contract: don't show stacktrace if static contract call failed (694d400)

  • contract: don't use -G flag for both gas and gas price (047cf8e)

  • don't accept --networkId in commands where node is required (cfd7ac5)

  • don't print contract deposit because it can't be used (47e0306)

  • don't show stacktraces for RestErrors (e7f2e58)

  • oracle: don't require extra arguments, refactor examples (4fada6e)

  • oracle: remove extra arguments in tx builder, refactor, fix examples (e3be365)

  • (
    )
  • account: remove extra object wrapping json output (b1d4585)

  • account: remove unnecessary account generate command (1c6abd8)

  • account: remove unnecessary balance, nonce commands (b4792e6)

  • account: remove useless output option (74a8a37)

  • chain: remove network_id command (4d4adce)

  • crypto: remove duplicate crypto sign command (bb39f07)

  • crypto: remove duplicate crypto unpack command (37b9965)

  • crypto: remove unnecessary crypto decode command (a0d9b05)

  • name: remove duplicate name lookup command (e4f9b50)

  • oracle: remove oracle get (6db5dc2)

  • remove --no-waitMined option (5fe7dc4)

  • require nodejs@18 (5fd3bfa)

  • aesophia_cli support (a74fc2b)

  • contract: includes support (818f375)

  • get urls from AECLI_NODE_URL, AECLI_COMPILER_URL env variables (78a9953)

  • specify and check contract descriptor file version (ea17f80)

  • tx: remove missed deposit field in contract call tx (a1aa7c7)

  • tx: show bytecode and call data instead of missed payload (75f5eee)

  • tx: show name of transaction type (18ee736)

  • chain: calculation of relative ttl (651ba1a)

  • chain: height calculation, improve markup, remove confusing timeout (4f5329d)

  • chain: padding of top output (ca661d7)

  • chain: show correctly consensus protocol version (a5fa358)

  • don't override files by default (d09eabe)

  • inspect: encoded tx, plain contract output, oracle queries in json (dae4df9)

  • oracle: decoding of oracle query (fa2764b)

  • oracle: providing oracleTtl, queryTtl, responseTtl (a0cc66c)

  • show name pointers line by line (9dbcf41)

  • contract: fall if descriptor file specified but not exists (37b490f)

  • remove broken crypto decrypt command (03c645c)

  • remove broken crypto genkey command (32e5b0f)

  • )
  • config command (27a1169)

  • usage show correct command name (223f05d)

  • contract: decode call result, make args flexible (b0a5cdc)

  • test: tx suite (64993ba)

  • exit code of get address command (fddd2b0)

  • remove compiler decodeData commend that depends on unsupported api (e198ea2)

  • typo in gasPrice (347e733)

  • oracle: Implement Oracle Test's (854ce61)

    Fix test for AENS (fae6ce8)

    Account: Spend by name. Extend account spend command with ability to put recipient address or name (#117) (043d1a2)

  • AENS: Add bid, transfer, revoke and fullClaim commands (a5eb23a)

  • AENS: Add test for auction (9f4f6b2)

  • AENS: extend name ttl command (63c99ae)

  • AENS: Fix transfer command. Add more test for transfer AENS names (547af5a)

  • AENS: Fix BC for all of AENS commands. (77d2d3c)

  • AENS: Implement name update command (b65c5e6)

  • CLI: Refactor constant(Use constant from sdk). Refactor error handling in AENS module. Add pre-claim command. Refactor claim command (7038629)

  • Contract: Add test for calling contract using cointract descriptor file or source code and address (3f77138)

  • Contract: contract call command (ae723d5)

  • Contract: Contract high level commands (#116) (8848a7b)

  • Contract: Enable test's for contract (ed48a83)

  • Oracle: Oracle commands (#134) (05b079a)

  • Tests: Fix Breaking Changes and adjust tests (#126) (60b7910)

  • nameFee
    option to
    claim
    command
    CLI: Make compatible with spec
  • Contract: Implement standalone compiler commands

  • DOCS add command for auto generating CHANGELOG

  • AENS: Add AENS transaction's build commands for offline mode to tx module

  • Contract: Add contract transaction's build commands for offline mode to tx module

  • Oracle: Add oracle transaction's build commands for offline mode to tx module

  • TX: tx root command, which allow to build transaction's in offline-mode

  • TX: Add broadcast sub-command to tx

  • Account: Add 'sign' sub-command to account

  • tools
    b5dfdda
    457e4c4
    5c119c5
    d8325f6
    1f03275
    476aec1
    894083f
    6.0.1
    b1b53b5
    2b63f5f
    6.0.0
    docs.aeternity.com/aepp-cli-js
    302c8b3
    9c97844
    4128276
    daefd21
    54d70fb
    70b46c2
    5a81814
    fdaeeff
    2a2a94b
    5.0.0
    70ceb67
    87b2ede
    2516446
    836f421
    7bf7bb6
    b80e3b4
    8d24bec
    4.1.0
    e62be74
    6d6da0c
    278a6ff
    34ae285
    485117e
    4.0.0
    cb25bb7
    cddbbe9
    4c4d215
    201a7e0
    7c278f1
    3.0.0
    3afa3f5
    0fe69eb
    334f4dd
    960bb4a
    3e0589e
    b5103e4
    26e8820
    23296dd
    2.7.0
    #115
    8279579
    b748003
    #128
    23168ae
    f26de1e
    d05e611
    7399377
    2.6.0
    #105
    f7b061a
    #95
    1cb3e5b
    #90
    7de13eb
    #84
    c775e1d
    #92
    454385d
    #84
    c775e1d
    #69
    b1cdb2e
    2.0.0
    #53
    e7f2d0a
    sdk-mainnet.aepps.com
    0d4aa51
    4af1b4c
    - $ aecli oracle extend ./wallet.json ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi 200
    + $ aecli oracle extend ./wallet.json 200
    - $ aecli oracle respond-query ./wallet.json ok_2a1j2Mk9YSmC1gi... oq_6y3N9KqQb74QsvR... +16Degree
    + $ aecli oracle respond-query ./wallet.json oq_6y3N9KqQb74QsvR... +16Degree
    -$ aecli account save ./my-wallet.json <hex secret key>
    +$ aecli account create ./my-wallet.json <hex secret key>
    $ aecli select-node https://testnet.aeternity.io
    - aecli name lookup <name.chain>
    + aecli inspect <name.chain>
    - aecli crypto unpack <tx-prefixed transaction>
    + aecli inspect <tx-prefixed transaction>
    - aecli account balance wallet.json --password=123
    - aecli account nonce wallet.json --password=123
    + address=$(aecli account address wallet.json --json | jq -r .publicKey)
    + aecli inspect $address
    - aecli account spend ... | jq .tx.tx.amount
    + aecli spend ... | jq .tx.amount
    - aecli account transfer 0.42 <recipient>
    + aecli spend 42% <recipient>
    $ aecli contract call ./wallet.json foo '[1, 2]'
    $ aecli contract call foo '[1, 2]' ./wallet.json
    — sign a transaction using wallet
  • sign-message — sign a personal message using wallet

  • verify-message — check if message was signed by address

  • address — get wallet address and optionally secret key

  • create — create a wallet by a secret key or generate a new one

  • spend — send coins to another account or contract

  • name

    • full-claim — claim an AENS name in a single command

    • pre-claim — pre-claim an AENS name

    • claim — claim an AENS name (requires pre-claim)

    • — bid on name in auction

    • — update a name pointer

    • — extend name TTL

    • — revoke an AENS name

    • — transfer a name to another account

  • contract

    • compile — compile a contract to get bytecode

    • encode-calldata — encode calldata for contract call

    • decode-call-result — decode contract call result

    • — execute a function of the contract

    • — deploy a contract on the chain

  • oracle

    • create — register current account as oracle

    • extend — extend oracle's time to leave

    • create-query — create an oracle query

    • — respond to an oracle query

  • chain

    • top — query the top key/micro block of the chain

    • status — query node version, network id, and related details of the selected node

    • ttl — get relative TTL by absolute TTL

    • — prints blocks from top until condition

    • — send signed transaction to the chain

  • inspect — get details of a node entity

  • tx

    • spend — build spend transaction

    • name-preclaim — build name preclaim transaction

    • name-claim — build name claim transaction

    • — build name update transaction

    • — build name transfer transaction

    • — build name revoke transaction

    • — build contract deploy transaction

    • — build contract call transaction

    • — build oracle register transaction

    • — build oracle extend transaction

    • — build oracle post query transaction

    • — build oracle respond transaction

    • — verify transaction using node

  • config — print the current sdk configuration

  • select-node — specify node to use in other commands

  • select-compiler — specify compiler to use in other commands

  • account group

    sign

    Sign a transaction using wallet. Useful in offline signing scheme.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --networkId [networkId] Network id. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). --json Print result in json format.

    Example calls

    sign-message

    Sign a personal message using wallet.

    Options

    --filePath [path] Specify the path to the file for signing (ignore "data" argument and use file instead). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). --json Print result in json format.

    Example calls

    verify-message

    Check if message was signed by address.

    Options

    --filePath [path] Specify the path to the file (ignore "data" argument and use file instead). --json Print result in json format.

    Example calls

    address

    Get wallet address and optionally secret key.

    Options

    --secretKey Print secret key. --forcePrompt Force prompting. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). --json Print result in json format.

    Example calls

    create

    Create a password-encrypted wallet by a secret key. Secret key can be provided in options, or cli will generate one. This command creates ethereum-like keyfile.

    Arguments

    wallet_path secretKey Secret key in sk_ or hex encoding.

    Options

    --overwrite Overwrite if exist. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). --json Print result in json format.

    Example calls

    spend

    Sends coins to another account or contract.

    Arguments

    wallet A path to wallet file. receiver Address or name of recipient account. amount Amount of coins to send in aettos/ae (example: 1.2ae), or percent of sender balance (example: 42%).

    Options

    --payload [payload] Transaction payload as text (default: ""). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -N, --nonce [nonce] Override the nonce that the transaction is going to be sent with. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    name group

    full-claim

    Claim an AENS name in a single command. This command signs and sends a pre-claim transaction and waits until one block gets mined. After that, it sends a claim transaction. At the end, the update transaction is submitted, making a name point to the current account.

    A name in arguments should end with ".chain". Be careful, shorter names are more expensive. If the name is shorter than 13 characters (without ".chain") then it won't be claimed immediately but would start an auction instead.

    Options

    --nameFee [nameFee] Amount of coins to pay for name. --nameTtl [nameTtl] A number of blocks until name expires (default: 180000 (1 year)). --clientTtl [clientTtl] A suggestion measured in seconds on how long clients should cache name pointers (default: 3600 (1 hour)). -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    pre-claim

    Pre-claim an AENS name. The name should be claimed after one key block since the pre-claim gets mined. This command sends a pre-claim transaction, and outputs a salt that needs to be provided to aecli name claim.

    A name in arguments should end with ".chain". Be careful, shorter names are more expensive. If the name is shorter than 13 characters (without ".chain") then it won't be claimed immediately but would start an auction instead.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    claim

    Claim an AENS name, it requires a salt provided by aecli name pre-claim.

    A name in arguments should end with ".chain". Be careful, shorter names are more expensive. If the name is shorter than 13 characters (without ".chain") then it won't be claimed immediately but would start an auction instead.

    Options

    --nameFee [nameFee] Amount of coins to pay for name. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    bid

    Bid on name in auction.

    Arguments

    wallet_path name nameFee Amount of coins to pay for name.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    update

    Update a name pointer.

    Options

    --extendPointers Extend pointers (default: false). --nameTtl [nameTtl] A number of blocks until name expires (default: 180000 (1 year)). --clientTtl [clientTtl] A suggestion measured in seconds on how long clients should cache name pointers (default: 3600 (1 hour)). -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    extend

    Extend name TTL.

    Arguments

    wallet_path name nameTtl A number of blocks until name expires (default: 180000 (1 year)).

    Options

    --clientTtl [clientTtl] A suggestion measured in seconds on how long clients should cache name pointers (default: 3600 (1 hour)). -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    revoke

    Revoke an AENS name. After that nobody will be able to claim it again. This action is irreversible!

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    transfer

    Transfer a name to another account.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    contract group

    compile

    Compile a contract to get bytecode.

    Options

    --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    encode-calldata

    Encode calldata for contract call.

    Arguments

    fn args JSON-encoded arguments array of contract call (default: []).

    Options

    -d, --descrPath [descrPath] Path to contract descriptor file. --contractSource [contractSource] Contract source code file name. --contractAci [contractAci] Contract ACI file name. --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    decode-call-result

    Decode contract call result.

    Options

    -d, --descrPath [descrPath] Path to contract descriptor file. --contractSource [contractSource] Contract source code file name. --contractAci [contractAci] Contract ACI file name. --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    call

    Execute a function of the contract.

    Arguments

    fn Name of contract entrypoint to call. args JSON-encoded arguments array of contract call (default: []). wallet_path Path to secret storage file, not needed to make a static call.

    Options

    --contractAddress [contractAddress] Contract address to call. -s, --callStatic Estimate the return value, without making a transaction on chain. -t, --topHash Hash of block to make call. -d, --descrPath [descrPath] Path to contract descriptor file. --contractSource [contractSource] Contract source code file name. --contractAci [contractAci] Contract ACI file name. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -G, --gas [gas] Amount of gas to call/deploy the contract. --gasPrice [gasPrice] Gas price to call/deploy the contract (default: based on network demand). -N, --nonce [nonce] Override the nonce that the transaction is going to be sent with. -a, --amount [amount] Amount of coins to send (default: 0ae). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    deploy

    Deploy a contract on the chain and create a deployment descriptor with the contract information that can be used to invoke the contract later on. The generated descriptor will be made in the same folder of the contract source file or at the location provided in descrPath. Multiple deploys of the same contract file will generate different deploy descriptors.

    Arguments

    wallet_path args JSON-encoded arguments array of contract call (default: []).

    Options

    --contractBytecode [contractBytecode] Contract bytecode file name. -d, --descrPath [descrPath] Path to contract descriptor file. --contractSource [contractSource] Contract source code file name. --contractAci [contractAci] Contract ACI file name. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -G, --gas [gas] Amount of gas to call/deploy the contract. --gasPrice [gasPrice] Gas price to call/deploy the contract (default: based on network demand). -N, --nonce [nonce] Override the nonce that the transaction is going to be sent with. -a, --amount [amount] Amount of coins to send (default: 0ae). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    oracle group

    create

    Register current account as oracle.

    Options

    --oracleTtl [oracleTtl] A number of blocks until oracle expires (default: 500 (1 day)). --queryFee [queryFee] Oracle query fee (default: 0ae). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    extend

    Extend oracle's time to leave.

    Arguments

    wallet_path oracleTtl A number of blocks until oracle expires (default: 500 (1 day)).

    Options

    -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    create-query

    Create an oracle query.

    Options

    --queryTtl [queryTtl] A number of blocks while oracle can respond (default: 10 (30 minutes)). --responseTtl [responseTtl] A number of blocks while response available (default: 10 (30 minutes)). --queryFee [queryFee] Oracle query fee (default: provided by oracle). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    respond-query

    Respond to an oracle query.

    Options

    --responseTtl [responseTtl] A number of blocks while response available (default: 10 (30 minutes)). -P, --password [password] Wallet Password, may be recorded to shell history (env: AECLI_WALLET_PASSWORD). -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: 3). -F, --fee [fee] Override the transaction fee. --nonce [nonce] Override the nonce that the transaction is going to be sent with. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    chain group

    top

    Query the top key/micro block of the chain.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    status

    Query node version, network id, and related details of the selected node.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    ttl

    Get relative TTL by absolute TTL.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    play

    Prints blocks from top until condition.

    Options

    -L, --limit [playLimit] Amount of blocks to print (default: 10). -P, --height [playToHeight] Print blocks till the height. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    broadcast

    Send signed transaction to the chain. Useful in offline signing scheme.

    Options

    -W, --no-waitMined Don't wait until transaction gets mined. --verify Verify Transaction before broadcasting. -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    inspect

    Prints details of:

    • account (ak_-prefixed string),

    • name (string ending with '.chain'),

    • contract (ct_-prefixed string),

    • oracle (ok_-prefixed string),

    • keyblock or microblock (prefixed with kh_, mh_),

    • keyblock by height (integer),

    • transaction (by th_-string or tx_).

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    tx group

    spend

    Build spend transaction.

    Arguments

    senderId receiverId amount Amount of coins to send. nonce Unique number that is required to sign transaction securely.

    Options

    --payload [payload] Transaction payload (default: ""). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    name-preclaim

    Build name preclaim transaction.

    Arguments

    accountId name nonce Unique number that is required to sign transaction securely.

    Options

    -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    name-claim

    Build name claim transaction.

    Arguments

    accountId salt name nonce Unique number that is required to sign transaction securely.

    Options

    --nameFee [nameFee] Amount of coins to pay for name. -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    name-update

    Build name update transaction.

    Arguments

    accountId nameId nonce Unique number that is required to sign transaction securely. pointers

    Options

    --nameTtl [nameTtl] A number of blocks until name expires (default: 180000 (1 year)). --clientTtl [clientTtl] A suggestion measured in seconds on how long clients should cache name pointers (default: 3600 (1 hour)). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    name-transfer

    Build name transfer transaction.

    Arguments

    accountId recipientId name nonce Unique number that is required to sign transaction securely.

    Options

    -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    name-revoke

    Build name revoke transaction.

    Arguments

    accountId name nonce Unique number that is required to sign transaction securely.

    Options

    -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    contract-deploy

    Build contract deploy transaction.

    Arguments

    ownerId contractBytecode initCallData nonce Unique number that is required to sign transaction securely.

    Options

    -G, --gas [gas] Amount of gas to call/deploy the contract. --gasPrice [gasPrice] Gas price to call/deploy the contract (default: 1000000000). -a, --amount [amount] Amount of coins to send (default: 0ae). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    contract-call

    Build contract call transaction.

    Arguments

    callerId contractId callData nonce Unique number that is required to sign transaction securely.

    Options

    -G, --gas [gas] Amount of gas to call/deploy the contract. --gasPrice [gasPrice] Gas price to call/deploy the contract (default: 1000000000). -a, --amount [amount] Amount of coins to send (default: 0ae). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    oracle-register

    Build oracle register transaction.

    Arguments

    accountId queryFormat responseFormat nonce Unique number that is required to sign transaction securely.

    Options

    --queryFee [queryFee] Oracle query fee (default: 0ae). --oracleTtl [oracleTtl] A number of blocks until oracle expires (default: 500 (1 day)). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    oracle-extend

    Build oracle extend transaction.

    Arguments

    oracleId oracleTtl nonce Unique number that is required to sign transaction securely.

    Options

    -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    oracle-post-query

    Build oracle post query transaction.

    Arguments

    accountId oracleId query nonce Unique number that is required to sign transaction securely.

    Options

    --queryFee [queryFee] Oracle query fee (default: provided by oracle). --queryTtl [queryTtl] A number of blocks while oracle can respond (default: 10 (30 minutes)). --responseTtl [responseTtl] A number of blocks while response available (default: 10 (30 minutes)). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    oracle-respond

    Build oracle respond transaction.

    Arguments

    oracleId queryId response nonce Unique number that is required to sign transaction securely.

    Options

    --responseTtl [responseTtl] A number of blocks while response available (default: 10 (30 minutes)). -F, --fee [fee] Override the transaction fee. -T, --ttl [ttl] Validity of the transaction in number of keyblocks, or without this limit if 0 (default: undefined). --json Print result in json format.

    Example calls

    verify

    Verify transaction using node.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). -f, --force Ignore node version compatibility check. --json Print result in json format.

    Example calls

    config

    Print the current sdk configuration.

    Options

    -u, --url [nodeUrl] Node to connect to (default: mainnet, env: AECLI_NODE_URL). --compilerUrl [compilerUrl] Compiler to connect to (default: stable compiler, env: AECLI_COMPILER_URL).

    select-node

    Specify node to use in other commands.

    Arguments

    nodeUrl Node URL.

    select-compiler

    Specify compiler to use in other commands.

    Arguments

    compilerUrl Compiler URL.

    sign
    aecli account sign [options] <wallet_path> <tx>
    $ aecli account sign ./wallet.json tx_+FoMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhARX7Ovvi4N8rfRN/Dsvb2ei7AJ3ysIkBrG5pnY6qW3W7iQVrx14tYxAAAIYPUN430AAAKoBebL57
    aecli account sign-message [options] <wallet_path> [data...]
    $ aecli account sign-message ./wallet.json 'message to sign'
    aecli account verify-message [options] <address> <hexSignature> [data...]
    $ aecli account verify-message ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E f2f268f195d4747568f38f9efd36e72606dc356c0b8db9fdfae5f1f9c207dbc354c57c29397837d911516aef184b0ddbed7d16d77caf9ffb3f42fe2bcc15c30e 'message to sign'
    aecli account address [options] <wallet_path>
    $ aecli account address ./wallet.json  # show only public key
    $ aecli account address ./wallet.json --secretKey  # show public key and secret key
    aecli account create [options] <wallet_path> [secretKey]
    $ aecli account create ./wallet.json
    $ aecli account create ./wallet.json sk_2CuofqWZHrABCrM7GY95YSQn8PyFvKQadnvFnpwhjUnDCFAWmf
    aecli spend [options] <wallet> <receiver> <amount>
    $ aecli spend ./wallet.json ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E 100
    $ aecli spend ./wallet.json example-name.chain 1.23ae
    $ aecli spend ./wallet.json ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E 20% --ttl 20
    aecli name full-claim [options] <wallet_path> <name>
    $ aecli name full-claim ./wallet.json example-name.chain
    aecli name pre-claim [options] <wallet_path> <name>
    $ aecli name pre-claim ./wallet.json example-name.chain
    aecli name claim [options] <wallet_path> <name> <salt>
    $ aecli name claim ./wallet.json example-name.chain 12327389123
    aecli name bid [options] <wallet_path> <name> <nameFee>
    $ aecli name bid ./wallet.json example-name.chain 4.2ae
    aecli name update [options] <wallet_path> <name> [addresses...]
    $ aecli name update ./wallet.json example-name.chain ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh
    aecli name extend [options] <wallet_path> <name> [nameTtl]
    $ aecli name extend ./wallet.json example-name.chain 180000
    aecli name revoke [options] <wallet_path> <name>
    $ aecli name revoke ./wallet.json example-name.chain
    aecli name transfer [options] <wallet_path> <name> <address>
    $ aecli name transfer ./wallet.json example-name.chain ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E
    aecli contract compile [options] <file>
    $ aecli contract compile ./contract.aes
    aecli contract encode-calldata [options] <fn> [args]
    $ aecli contract encode-calldata --descrPath ./contract.aes.deploy.229e.json sum '[1, 2]'
    $ aecli contract encode-calldata --contractSource ./contract.aes sum '[1, 2]'
    $ aecli contract encode-calldata --contractAci ./contract.json sum '[1, 2]'
    aecli contract decode-call-result [options] <fn> <encoded_result>
    $ aecli contract decode-call-result --descrPath ./contract.aes.deploy.229e.json test cb_DA6sWJo=
    $ aecli contract decode-call-result --contractSource ./contract.aes test cb_DA6sWJo=
    $ aecli contract decode-call-result --contractAci ./contract.json test cb_DA6sWJo=
    aecli contract call [options] <fn> [args] [wallet_path]
    $ aecli contract call ./wallet.json sum '[1, 2]' --descrPath ./contract.aes.deploy.229e.json
    $ aecli contract call ./wallet.json sum '[1, 2]' --contractAddress ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh --callStatic
    $ aecli contract call ./wallet.json sum '[1, 2]' --descrPath ./contract.aes.deploy.229e.json --gas 2222222 --nonce 4 --ttl 1243
    aecli contract deploy [options] <wallet_path> [args]
    $ aecli contract deploy ./wallet.json --contractSource ./contract.aes '[1, 2]'
    $ aecli contract deploy ./wallet.json --descrPath ./contract.aes.deploy.229e.json --gas 2222222
    $ aecli contract deploy ./wallet.json --contractBytecode ./contract.txt --contractAci ./contract.json
    aecli oracle create [options] <wallet_path> <queryFormat> <responseFormat>
    $ aecli oracle create ./wallet.json string string
    aecli oracle extend [options] <wallet_path> [oracleTtl]
    $ aecli oracle extend ./wallet.json 200
    aecli oracle create-query [options] <wallet_path> <oracleId> <query>
    $ aecli oracle create-query ./wallet.json ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi WhatTheWeatherIs?
    aecli oracle respond-query [options] <wallet_path> <queryId> <response>
    $ aecli oracle respond-query ./wallet.json oq_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh +16Degree
    aecli chain top [options]
    $ aecli chain top
    aecli chain status [options]
    $ aecli chain status
    aecli chain ttl [options] <absoluteTtl>
    $ aecli chain ttl
    aecli chain play [options]
    $ aecli chain play --limit 3  # print 3 blocks from top
    $ aecli chain play --height 929796  # print blocks from top until reach height
    aecli chain broadcast [options] <tx>
    $ aecli chain broadcast tx_+FoMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhARX7Ovvi4N8rfRN/Dsvb2ei7AJ3ysIkBrG5pnY6qW3W7iQVrx14tYxAAAIYPUN430AAAKoBebL57
    aecli inspect [options] <identifier>
    $ aecli inspect ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E  # get account details
    $ aecli inspect example-name.chain  # get details of AENS name
    $ aecli inspect ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh  # get contract details
    $ aecli inspect ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi  # get contract details
    $ aecli inspect kh_CF37tA4KiiZTFqbQ6JFCU7kDt6CBZucBrvineVUGC7svA9vK7  # get key block details by hash
    $ aecli inspect mh_k1K9gLLtdikJhCdKfBbhYGveQs7osSNwceEJZb1jD6AmraNdr  # get micro block details by hash
    $ aecli inspect 929796  # get key block details by height
    $ aecli inspect th_2nZshewM7FtKSsDEP4zXPsGCe9cdxaFTRrcNjJyE22ktjGidZR  # get transaction details by hash
    $ aecli inspect tx_+FoMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhARX7Ovvi4N8rfRN/Dsvb2ei7AJ3ysIkBrG5pnY6qW3W7iQVrx14tYxAAAIYPUN430AAAKoBebL57  # get transaction details
    aecli tx spend [options] <senderId> <receiverId> <amount> <nonce>
    $ aecli tx spend ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E ak_AgV756Vfo99juwzNVgnjP1gXX1op1QN3NXTxvkPnHJPUDE8NT 100ae 42
    aecli tx name-preclaim [options] <accountId> <name> <nonce>
    $ aecli tx name-preclaim ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E example-name.chain 42
    aecli tx name-claim [options] <accountId> <salt> <name> <nonce>
    $ aecli tx name-claim ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E 12327389123 example-name.chain 42
    aecli tx name-update [options] <accountId> <nameId> <nonce> [pointers...]
    $ aecli tx name-update ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E example-name.chain 42 ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh
    aecli tx name-transfer [options] <accountId> <recipientId> <name> <nonce>
    $ aecli tx name-transfer ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E ak_AgV756Vfo99juwzNVgnjP1gXX1op1QN3NXTxvkPnHJPUDE8NT example-name.chain 42
    aecli tx name-revoke [options] <accountId> <name> <nonce>
    $ aecli tx name-revoke ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E example-name.chain 42
    aecli tx contract-deploy [options] <ownerId> <contractBytecode> <initCallData> <nonce>
    $ aecli tx contract-deploy ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E cb_dGhpcyBtZXNzYWdlIGlzIG5vdCBpbmRleGVkdWmUpw== cb_DA6sWJo= 42
    aecli tx contract-call [options] <callerId> <contractId> <callData> <nonce>
    $ aecli tx contract-call ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E ct_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh cb_DA6sWJo= 42
    aecli tx oracle-register [options] <accountId> <queryFormat> <responseFormat> <nonce>
    $ aecli tx oracle-register ak_21A27UVVt3hDkBE5J7rhhqnH5YNb4Y1dqo4PnSybrH85pnWo7E '{"city": "string"}' '{"tmp": "number"}' 42
    aecli tx oracle-extend [options] <oracleId> <oracleTtl> <nonce>
    $ aecli tx oracle-extend ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi 100 42
    aecli tx oracle-post-query [options] <accountId> <oracleId> <query> <nonce>
    $ aecli tx oracle-post-query ak_AgV756Vfo99juwzNVgnjP1gXX1op1QN3NXTxvkPnHJPUDE8NT ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi '{"city": "Berlin"}' 42
    aecli tx oracle-respond [options] <oracleId> <queryId> <response> <nonce>
    $ aecli tx oracle-respond ok_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi oq_6y3N9KqQb74QsvR9NrESyhWeLNiA9aJgJ7ua8CvsTuGot6uzh '{"tmp": 1}' 42
    aecli tx verify [options] <tx>
    $ aecli tx verify tx_+FoMAaEBzqet5HDJ+Z2dTkAIgKhvHUm7REti8Rqeu2S7z+tz/vOhARX7Ovvi4N8rfRN/Dsvb2ei7AJ3ysIkBrG5pnY6qW3W7iQVrx14tYxAAAIYPUN430AAAKoBebL57
    aecli config [options]
    aecli select-node [options] [nodeUrl]
    aecli select-compiler [options] [compilerUrl]
    bid
    update
    extend
    revoke
    transfer
    call
    deploy
    respond-query
    play
    broadcast
    name-update
    name-transfer
    name-revoke
    contract-deploy
    contract-call
    oracle-register
    oracle-extend
    oracle-post-query
    oracle-respond
    verify

    Changelog

    All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

    1.17.5 (2025-04-24)

    Miscellaneous

    • Update AE GHA to latest ()

    (2025-04-24)

    Bug Fixes

    • show correct icons for ETH and WAE () ()

    (2025-02-10)

    Features

    • update metadata ()

    (2025-02-10)

    Features

    • add bridge contracts ()

    • readme: add title ()

    Bug Fixes

    • update ethers package and adjust related code for compatibility ()

    Miscellaneous

    • trigger testing docs updater ()

    • trigger testing docs updater ()

    (2024-12-18)

    Bug Fixes

    • AE wallet select prompting issue ()

    (2024-12-18)

    Bug Fixes

    • remove persistance show of wallet extension missing error ()

    (2024-11-30)

    Features

    • support aeternity MM snap ()

    • update ae sdk package & adapt changes ()

    Miscellaneous

    • remove redundant context prop ()

    (2024-11-16)

    Bug Fixes

    • scientific notation issue ()

    • validations for amount's new type ()

    (2024-09-13)

    Features

    • add PageContainer style prop ()

    • adjust content height for page container component ()

    • set smaller paddings for smaller screens ()

    Bug Fixes

    • headings & margins across pages ()

    • supported token list heading ()

    • transaction history box metrics ()

    • transaction page mobile screen text positions ()

    Refactorings

    • page components to create reusable PageContainer ()

    (2024-09-11)

    Features

    • wallet connection flow improvements ()

    Bug Fixes

    • auto wallet connect & display message ()

    • only fetch bridge info when wallets detected ()

    • only try to connect to aeternity wallet when wallet detected ()

    (2024-09-10)

    Features

    • added sub menu to left bar & reorganized menus ()

    Bug Fixes

    • left sub menu responsiveness ()

    Miscellaneous

    • wording updates ()

    (2024-09-09)

    Features

    • added view customization features to WalletConnection component ()

    • connect wallet view in transaction history ()

    • transaction page ()

    Bug Fixes

    • add react node keys to wallet connect buttons ()

    • console warning for nth-child ()

    • wording, half button issue ()

    Refactorings

    • WalletConnection component ()

    Miscellaneous

    • update material icons package ()

    (2024-09-06)

    Features

    • improve left menu navigation ()

    • left menu component with responsiveness updates () ()

    • left menu styling ()

    • transaction history route fundamentals ()

    Bug Fixes

    • code formatting ()

    (2024-09-02)

    Bug Fixes

    • update blockchain name with proper spelling and symbols ()

    (2024-08-30)

    Bug Fixes

    • typo ()

    • update wording in FAQ ()

    (2024-08-25)

    Features

    • Added "what's next?" entry to faq & created a token list page ()

    Bug Fixes

    • typo ()

    Miscellaneous

    • Fix formatting issue in summary view ()

    (2024-08-23)

    Features

    • further information about bridge action & bug fixes/improvements ()

    Miscellaneous

    • remove unused import ()

    (2024-08-15)

    Features

    • Add link to GitHub repository ()

    • Update ViewContainer footer with Acurast's link ()

    Bug Fixes

    • typo ()

    Miscellaneous

    • Update README with deployment instructions ()

    (2024-08-15)

    Features

    • Update sponsorship information in terms and conditions ()

    Miscellaneous

    • update terms and conditions ()

    (2024-08-12)

    Refactorings

    • remove powered by aeternity remark ()

    (2024-08-12)

    Features

    • update AE address in bridge form ()

    Bug Fixes

    • update bridge transaction link to use correct blockchain explorer ()

    Refactorings

    • improve destination token value display in Bridge form ()

    (2024-07-15)

    Bug Fixes

    • checkAeAccountHasEligibleBridgeUse function's transactions call ()

    (2024-07-11)

    Miscellaneous

    • add "How To" link to the top menu ()

    (2024-07-01)

    Bug Fixes

    • header and footer for small screens ()

    (2024-07-01)

    Features

    • restrict bridge usage to once in every 12 hours ()

    Refactorings

    • snack message display function & restriction interval var ()

    (2024-06-30)

    Bug Fixes

    • check for AE bridging to EVM ()

    (2024-06-30)

    Features

    • refactor bridge info object and adjust views accordingly to the bridge operator fund account balance ()

    • setup snack notificator lib ()

    Refactorings

    • dialogs & display bridge action summary ()

    Miscellaneous

    • Add check for sufficient balance in Ethereum bridge contract ()

    • Disable bridge usage depending on the contract flag ()

    • replace error dialogs with snack alerts ()

    (2024-06-27)

    Bug Fixes

    • nginx config and Dockerfile ()

    • remove nginx config ()

    (2024-06-27)

    Miscellaneous

    • Update Dockerfile to remove unnecessary file copy and nginx configuration ()

    (2024-06-27)

    Miscellaneous

    • Update Dockerfile to copy files and directories for nginx deployment ()

    (2024-06-27)

    Miscellaneous

    • Update nginx.conf to use /index.html as fallback for all routes ()

    (2024-06-27)

    Features

    • Add FAQ and Terms and Conditions pages ()

    (2024-06-24)

    Features

    • auto connect SH on AE chain selection ()

    Bug Fixes

    • network switch auto wallet connection issue ()

    • WAE contract address ()

    Miscellaneous

    • Add deployment links to README.md ()

    • remove confusing expressions from the amount input ()

    • Update AeternityBridgeInfo component to check if AE and EVM bridges are enabled ()

    • Update default AE and WAE contract addresses ()

    (2024-05-21)

    Miscellaneous

    • Update AeternityBridgeLogo component to use correct icon file name ()

    • Update ViewContainer to improve readability of the revision information in the footer ()

    (2024-05-16)

    Bug Fixes

    • Update constants.ts to include assets from chainConfig ()

    Miscellaneous

    • Add version and revision information to footer ()

    • Update integration.yml to include BUILD_ARGS with revision information ()

    • Update ViewContainer to conditionally display revision information in the footer ()

    (2024-05-16)

    Bug Fixes

    • update package name to match GH repo ()

    • use custom GH token to able to trigger releases ()

    1.0.0 (2024-05-16)

    Features

    • implement mainnet config and assets ()

    Refactorings

    • Update Aeternity logo in NavigationBar component ()

    Miscellaneous

    • add complete asset list ()

    • Add wallet disconnect button to header, copy connected wallet address, and handle account change ()

    • Update Dockerfile to use multi-stage build for improved performance ()

    update mainnet contracts (3d8f7c9)

  • update testnet contracts and assets (e966f11)

  • 2cc4a33
    1.17.4
    #92
    0a28d0f
    1.17.0
    3b6e2a0
    1.16.0
    9eaa820
    edd193d
    42ad9f9
    b225056
    bf1edc6
    1.15.2
    #82
    73b539a
    1.15.1
    #80
    a4eb249
    1.15.0
    #73
    d9ccf50
    c1ccd7d
    b7aecf2
    1.14.1
    524dc34
    3f3f061
    1.14.0
    903155f
    #62
    bfdc96b
    3e78575
    73dd6d5
    4a6441a
    6eb60ae
    692852f
    1738902
    1.13.0
    a4795b4
    b9d2875
    ae54572
    f0ea95a
    1.12.0
    d28814b
    5c8b9e3
    8036c59
    1.11.0
    5b69c80
    #61
    cfe619f
    4d055e0
    49b83eb
    2e29c8d
    9462050
    a664a02
    29a1a7f
    1.10.0
    109fc78
    #58
    c1189ef
    93691e7
    ffdfb82
    0a62371
    1.9.2
    #56
    231caf5
    1.9.1
    #49
    b04e200
    #54
    2b18aae
    1.9.0
    21118bf
    2088ed7
    9b4bb29
    1.8.0
    #27
    4751eb2
    c73f412
    1.7.0
    #37
    d32d2ec
    #36
    15198fd
    b01740a
    2c0c676
    1.6.0
    d1eb346
    52761f5
    1.5.1
    848e799
    1.5.0
    68801cb
    c5e1638
    524e1b3
    1.4.3
    24d21a6
    1.4.2
    4cb1e75
    1.4.1
    a26a810
    1.4.0
    77ca54f
    1e44ec1
    1.3.1
    70f6ab6
    1.3.0
    b24f22d
    7712d55
    fe7c69d
    aa3b09a
    c50fcf3
    b5ad38d
    1.2.4
    5c643cc
    37786c3
    1.2.3
    6143e8e
    1.2.2
    ab6e449
    1.2.1
    50f3a97
    1.2.0
    57c3d1a
    1.1.0
    #12
    bc83b3a
    026d66d
    c5a5c82
    7f7d68c
    #13
    01e99b8
    9c9715a
    119f6bf
    1.0.3
    c06cd4c
    2cdbcea
    1.0.2
    7140c1d
    e709577
    6608f9a
    5c06b27
    1.0.1
    66fc798
    d352239
    0e0dec4
    04cbb07
    2bf5501
    3257a9e
    549137b

    aex-141

    AEX-141: Non-Fungible Token Standard

    Abstract

    A standard implementation of non-fungible tokens for the æternity ecosystem. Initially, the design goal of the primary interface was to be as compatible with ERC-721 as possible, so that anyone who can work with ERC-721 can work with this interface. However, specifically when it comes to dealing with metadata a decision was taken to provide contract developers as much flexibility as possible.

    Core differences to the well-known ERC-721 standard:

    • Unsafe transactions are not supported. Therefore, all transactions are ought to be safe

    • Usage of zero-address for minting or burning is avoided. Thus, explicit events for minting and burning have been defined

    • Token transfers do not require the (owner) address to be passed. Only the recipient address needs to be provided to the entrypoint

    • High flexibility when it comes to dealing with metadata is provided

    Motivation

    The following standard describes standard interfaces for non-fungible tokens. The proposal contains a primary interface and secondary interfaces (extensions) for optional functionality that not everyone might need.

    AEX141 NFT

    IAEX141

    Methods

    aex141_extensions()

    Returns a hardcoded list of all implemented extensions on the deployed contract.

    meta_info()

    Returns meta information associated with the contract.

    Note:

    • The base_url is optional and is only intended to be used if the metadata_type is URL. As known from ERC-721 this can be used to resolve metadata for a specific NFT which can be fetched from an URL based on the token id

    • The metadata_type MUST be defined on contract level and MUST NOT be mixed across various NFTs in a contract

    return
    type

    meta_info

    meta_info

    metadata()

    Returns metadata associated with an NFT.

    Note:

    • The metadata can be set in the constructor, as well as by implementing extensions like e.g. mintable

    • The metadata to use depends on the metadata_type defined on contract level and provides certain flexibility:

      • for URL and OBJECT_ID use MetadataIdentifier

        • URL can represent any URL and typically the NFT id is used to resolve the metadata using that URL, e.g.

          • ipfs:// serving as base_url and pointing to a folder stored on IPFS where immutable metadata is stored (recommended)

          • https:// serving as

      • for MAP use MetadataMap

        • MAP provides almost unlimited flexibility and allows any kind of metadata to be represented in a map

    parameter
    type

    token_id

    int

    return
    type

    data

    option(metadata)

    total_supply()

    Returns the total amount of NFTs in circulation.

    return
    type

    total_supply

    int

    balance()

    Returns the number of NFTs owned by the account with address owner in the contract. If the owner address is unknown to the contract, None will be returned. Using option type as a return value allows us to determine if the account owns 0, more than 0, or the account has never owned a balance and is still unknown to the contract.

    parameter
    type

    owner

    address

    return
    type

    balance

    option(int)

    owner()

    Returns the owner's address for the provided token_id if the NFT is minted. If the NFT isn't minted, None will be returned.

    parameter
    type

    token_id

    int

    return
    type

    owner

    option(address)

    transfer()

    Transfers NFT with ID token_id from the current owner to the to address. Will invoke IAEX141Receiver.on_aex141_received if the to address belongs to a contract. If provided, data will be submitted with the invocation of IAEX141Receiver.on_aex141_received. Emits the Transfer event.

    Note: For security reasons reentrancy is not possible. Therefore contracts cannot use this entrypoint to transfer NFTs to itself. Use transfer_to_contract instead to cover this scenario.

    Throws if:

    • Call.caller is NOT the current owner or NOT approved to transfer on behalf of the owner;

    • token_id is NOT a valid token;

    • the invocation of IAEX141Receiver.on_aex141_received fails.

    parameter
    type

    token_id

    int

    data

    option(string)

    transfer_to_contract()

    Transfers NFT with ID token_id from the current owner to the contract calling this entrypoint. As reentrancy is not possible for security reasons, this entrypoint MUST be used if a contract (e.g. NFT marketplace) wants to transfer the NFT to itself on behalf of the owner. Emits the Transfer event.

    Throws if:

    • Call.caller is NOT a contract or NOT approved to transfer on behalf of the owner;

    • token_id is NOT a valid token;

    parameter
    type

    to

    address

    token_id

    int

    data

    option(string)

    approve()

    Sets the approved address to interact on behalf of an owner for the NFT with ID token_id. If enabled is true the operator address is approved, if false the approval is revoked. Throws unless caller is the current NFT owner, or an authorized operator of the current owner. Emits the Approval event.

    parameter
    type

    approved

    address

    token_id

    int

    enabled

    bool

    approve_all()

    Enables or disables approval for an operator address to manage all of the caller's NFTs. If enabled is true, the operator address is approved, if false, the approval is revoked. Emits the ApprovalForAll event.

    parameter
    type

    operator

    address

    enabled

    bool

    get_approved()

    Returns the address approved to interact with the NFT with ID token_id or returns None if no approval has been set. Throws if NFT with ID token_id does not exist.

    parameter
    type

    token_id

    int

    return
    type

    approved

    option(address)

    is_approved()

    Returns true if approved address is approved to transact for NFT with ID token_id.

    parameter
    type

    token_id

    int

    approved

    address

    return
    type

    approved

    bool

    is_approved_for_all()

    Returns true if operator is approved to commit transactions on behalf of owner.

    Indicates whether an address is an authorized operator for another address.

    parameter
    type

    owner

    address

    approved

    address

    return
    type

    approved

    bool

    Events

    Transfer

    This event MUST be triggered and emitted when tokens are transferred.

    The event arguments should be as follows: (from, to, token_id)

    parameter
    type

    from

    address

    to

    address

    token_id

    int

    Approval

    This event MUST be triggered and emitted upon approval, including revocation of approval.

    The event arguments should be as follows: (owner, approved, token_id, enabled). Enabled is of type string, because of a limit of 3 on indexed values. Since address, int and bool are automatically indexed, having enabled as bool would cause an error, as it would be the 4th indexed item. Use "true" or "false" as return values instead.

    parameter
    type

    owner

    address

    approved

    address

    token_id

    int

    enabled

    string

    ApprovalForAll

    This event MUST be triggered and emitted upon a change of operator status, including revocation of approval for all NFTs in the contract.

    The event arguments should be as follows: (owner, operator, approved)

    For idiomatic reasons approved is, just as with Approval, of type string

    parameter
    type

    owner

    address

    operator

    address

    approved

    string

    Receiver contract interface

    The standard only allows safe transfers of tokens. On transfer a check MUST be performed which checks if the recipient is a contract and if so the transfer MAY ONLY happen if on_aex141_received returns true.

    AEX141Receiver

    on_aex141_received()

    Deals with receiving NFTs on behalf of a contract. Contracts MUST implement this interface to be able to receive NFTs. Mint and transfer transactions will invoke the on_aex141_received function.

    Returns true or false to signal whether processing the received NFT was successful or not.

    parameter
    type

    from

    option(address)

    token_id

    int

    data

    option(string)

    Extensions

    This section covers the extendability of the basic token - e.g. mintable, burnable.

    When an NFT contract implements an extension its name should be included in the aex141_extensions array, in order for third party software or contracts to know the interface. Any extensions should be implementable without permission. Developers of extensions MUST choose a name for aex141_extensions that is not yet used. Developers CAN make a pull request to the reference implementation for general purpose extensions and maintainers choose to eventually include them.

    Extension Mintable ("mintable")

    The mintable extension SHOULD be used for generic NFT minting without specific requirements in regards to minting.

    Note: If you aim to reuse the same metadata across many NFTs you might prefer the mintable_templates extension.

    mint()

    Issues a new token to the provided address. If the owner is a contract, IAEX141Receiver.on_aex141_received will be called with data if provided.

    Emits the Mint event.

    Throws if the call to IAEX141Receiver.on_aex141_received implementation failed (safe transfer)

    parameter
    type

    owner

    address

    metadata

    option(metadata)

    data

    option(string)

    return
    type

    token_id

    int

    Extension Mintable Limit ("mintable_limit")

    The mintable_limit extension SHOULD be used if the amount of NFTs to mint should be limited/capped. It MAY ONLY be used in combination with the mintable extension.

    The initially defined token limit MUST be greater than or equal to 1.

    Emits the TokenLimit event on contract creation.

    token_limit()

    Returns the limit / max amount of NFTs that can be minted.

    return
    type

    token_limit

    int

    decrease_token_limit()

    Decreases the NFT limit/cap defined in the collection. An increase of the limit is forbidden.

    Emits the TokenLimitDecrease event.

    Throws if:

    • new_limit equals the current token_limit

    • new_limit is lower than the current total_supply

    parameter
    type

    new_limit

    int

    Extension Burnable ("burnable")

    The burnable extension SHOULD be used if NFTs within a contract are intended to be burnable.

    burn()

    Burns the NFT with the provided token_id.

    Emits the Burn event.

    Throws if Call.caller is NOT the current owner or NOT approved to transfer on behalf of the owner.

    parameter
    type

    token_id

    int

    Extension Mintable Templates ("mintable_templates")

    The mintable_templates extension SHOULD be used if multiple NFTs within a contract should share the same metadata. The extension provides the possbility to create templates. Optionally an edition limit for each template can be defined on template creation. If no edition limit is provided, it's considered to be unlimited. The edition limit can be decreased at any point of time as long as the new value does not exceed the current edition supply. Also, templates can be deleted if no NFT has been created using the template.

    Note:

    • On contract level the MAP MUST be used as metadata_type

      • the map stores the template_id and edition_serial of each NFT

      • if mutable_attributes extension is used, it also stores the mutable attributes

    • The template_metadata_type can either be T_URL (string, e.g. ipfs:// pointing to a JSON stored on IPFS) or T_MAP (map(string, string))

      • it is defined during contract creation

      • it is applied to ALL templates created with the contract

    template_metadata_type()

    Returns the metadata type which is used for templates.

    return
    type

    template_metadata_type

    template_metadata_type

    template()

    Returns the template for the provided template_id in case it exists, otherwise None.

    return
    type

    template

    option(template)

    template_supply()

    Returns the total amount of templates that currently exist.

    return
    type

    template_supply

    int

    create_template()

    Creates a new template for specific immutable metadata. The immutable_metadata needs to be MetadataIdentifier in case template_metadata_type is T_URL and MetadataMap for T_MAP. The edition limit defines how many NFTs can be minted based on a specific template. If no edition limit is provided, an unlimited amount of NFTs can be created using the template. The edition limit can be decreased at any time.

    Emits the TemplateCreation event.

    Note: It's recommended to perform a check if immutable_metadata is considered valid according to individual requirements.

    Throws in case the wrong variant for metadata is provided:

    • variant MUST be MetadataIdentifier if template_metadata_type is T_URL

    • variant MUST be MetadataMap if template_metadata_type is T_MAP

    parameter
    type

    immutable_metadata

    metadata

    edition_limit

    option(int)

    return
    type

    template_id

    int

    delete_template()

    Deletes the template with the provided id.

    Emits the TemplateDeletion event.

    Throws if:

    • the provided template_id does not exist

    • an NFT based on this template has already been created

    parameter
    type

    template_id

    int

    template_mint()

    Mints a new NFT for the provided template id. If to is a contract, IAEX141Receiver.on_aex141_received will be called with data if provided.

    Emits the TemplateMint event.

    Throws if:

    • the provided template_id does not exist

    • the mint would exceed the current edition_limit of the template

    • the call to IAEX141Receiver.on_aex141_received implementation failed (safe transfer)

    parameter
    type

    to

    address

    template_id

    int

    data

    option(string)

    return
    type

    token_id

    int

    decrease_edition_limit()

    Decreases the edition limit of a specific template. An increase of the edition limit of a template is forbidden.

    Emits the EditionLimitDecrease event.

    Throws if:

    • the provided template_id does not exist

    • the new_limit is equal to or lower than 0

    • the new_limit is equal to or higher than the current edition limit

    • the new_limit is lower than the current edition supply

    parameter
    type

    template_id

    int

    new_limit

    int

    Extension Mintable Templates Limit ("mintable_templates_limit")

    The mintable_templates_limit extension SHOULD be used to introduce a limit/cap for the amount of templates that may be in existence. It MAY ONLY be used in combination with the mintable_templates extension.

    template_limit()

    Returns the limit / max amount of templates that can be created.

    return
    type

    template_limit

    int

    decrease_template_limit()

    Decreases the template limit/cap defined in the contract. An increase of the limit is forbidden.

    Emits the TemplateLimitDecrease event.

    Throws if:

    • new_limit equals to or is lower than 0

    • new_limit equals the current token_limit

    • new_limit is lower than the current total_supply

    parameter
    type

    new_limit

    int

    Extension Mutable Attributes ("mutable_attributes")

    The mutable_attributes extension SHOULD be used if NFTs in the contract should store attributes which can change over time. This can e.g. be beneficial for game assets where users could level up their characters. The mutable attributes are expected to be provided in a JSON string.

    update_mutable_attributes()

    Updates the JSON string that contains mutable attributes of the NFT.

    Emits the MutableAttributesUpdate event.

    Throws if the provided token_id does not exist.

    parameter
    type

    token_id

    int

    mutable_attributes

    string

    Extension Events

    Mint

    This event is defined by the mintable extension and MUST be triggered whenever a new token is minted.

    The event arguments should be as follows: (to, token_id)

    parameter
    type

    to

    address

    token_id

    int

    TokenLimit

    This event is defined by the mintable_limit extension and MUST be triggered in the init entrypoint during contract creation.

    The event arguments should be as follows: (limit)

    parameter
    type

    limit

    int

    TokenLimitDecrease

    This event is defined by the mintable_limit extension and MUST be triggered whenever the decrease_token_limit entrypoint is called.

    The event arguments should be as follows: (old_limit, new_limit)

    parameter
    type

    old_limit

    int

    new_limit

    int

    Burn

    This event is defined by the burn extension and MUST be triggered whenever an NFT is burned.

    The event arguments should be as follows: (owner, token_id)

    parameter
    type

    owner

    address

    token_id

    int

    TemplateCreation

    This event is defined by the mintable_templates extension and MUST be triggered whenever a new template is created.

    The event arguments should be as follows: (template_id)

    parameter
    type

    template_id

    int

    TemplateDeletion

    This event is defined by the mintable_templates extension and MUST be triggered whenever a template is deleted.

    The event arguments should be as follows: (template_id)

    parameter
    type

    template_id

    int

    TemplateMint

    This event is defined by the mintable_templates extension and MUST be triggered whenever a new NFT is minted.

    The event arguments should be as follows: (to, template_id, token_id, edition_serial). Sophia does not allow 4 "indexed" values as of writing the standard. For this reason edition_serial defined as type string.

    The event arguments should be as follows: (to, template_id, token_id, edition_serial)

    parameter
    type

    to

    int

    template_id

    int

    token_id

    int

    edition_serial

    string

    EditionLimit

    This event is defined by the mintable_templates extension and MUST be triggered whenever a new template is created which specifies an edition limit.

    The event arguments should be as follows: (template_id, edition_limit)

    parameter
    type

    template_id

    int

    edition_limit

    int

    EditionLimitDecrease

    This event is defined by the mintable_templates extension and MUST be triggered whenever the decrease_edition_limit entrypoint is called.

    The event arguments should be as follows: (template_id, old_limit, new_limit)

    parameter
    type

    template_id

    int

    old_limit

    int

    new_limit

    int

    TemplateLimit

    This event is defined by the mintable_templates_limit extension and MUST be triggered in the init entrypoint during contract creation.

    The event arguments should be as follows: (limit)

    parameter
    type

    limit

    int

    TemplateLimitDecrease

    This event is defined by the mintable_templates_limit extension and MUST be triggered whenever the decrease_template_limit entrypoint is called.

    The event arguments should be as follows: (old_limit, new_limit)

    parameter
    type

    old_limit

    int

    new_limit

    int

    MutableAttributesUpdate

    This event is defined by the mutable_attributes extension and MUST be triggered whenever the mutable attributes of an NFT are updated.

    The event arguments should be as follows: (token_id, mutable_attributes)

    parameter
    type

    token_id

    int

    mutable_attributes

    string

    Implementation

    There are currently following reference implementations available which follows defined standard:

    • aex141-nft-collection-example

      • CollectionUniqueNFTs.aes implements the following extensions:

        • mintable

        • mintable_limit

        • burnable

      • implements the following extensions:

        • mintable_templates

        • mintable_templates_limit

        • mutable_attributes

    Additionally there exists following showcase for a simple NFT marketplace using AEX-141:

    • aex141-nft-simple-marketplace

    AEX: 141
    Title: Non-Fungible Token Standard
    Author: Arjan van Eersel <[email protected]> (@zkvonsnarkenstein), Marco Walz (@marc0olo), Philipp (@thepiwo), Rogerio (@jyeshe)
    License: ISC
    Discussions-To: https://forum.aeternity.com/t/aeternity-nft-token-standard/9781
    Status: Review
    Type: Interface
    Created: 2021-09-11
    contract interface IAEX141 =
        datatype metadata_type = URL | OBJECT_ID | MAP
        datatype metadata = MetadataIdentifier(string) | MetadataMap(map(string, string))
    
        record meta_info = 
            { name: string
            , symbol: string 
            , base_url: option(string)
            , metadata_type : metadata_type }
    
        datatype event 
            = Transfer(address, address, int)
            | Approval(address, address, int, string)
            | ApprovalForAll(address, address, string)
    
        entrypoint aex141_extensions : () => list(string)
    
        entrypoint meta_info : () => meta_info
    
        entrypoint metadata : (int) => option(metadata)
    
        entrypoint total_supply : () => int
    
        entrypoint balance : (address) => option(int)
    
        entrypoint owner : (int) => option(address)
       
        stateful entrypoint transfer : (address, int, option(string)) => unit
    
        stateful entrypoint transfer_to_contract : (int) => unit
    
        stateful entrypoint approve : (address, int, bool) => unit
    
        stateful entrypoint approve_all : (address, bool) => unit
    
        entrypoint get_approved : (int) => option(address)
    
        entrypoint is_approved : (int, address) => bool
    
        entrypoint is_approved_for_all : (address, address) => bool
    entrypoint aex141_extensions() : list(string)
    entrypoint meta_info() : meta_info
    entrypoint metadata(token_id: int) : option(metadata)
    entrypoint total_supply() : ínt
    entrypoint balance(owner: address) : option(int)
    entrypoint owner(token_id: int) : option(address)
    stateful entrypoint transfer(to: address, token_id: int, data: option(string)) : unit
    stateful entrypoint transfer(to: address, token_id: int, data: option(string)) : unit
    stateful entrypoint approve(approved: address, token_id: int, enabled: bool) : unit
    stateful entrypoint approve_all(operator: address, enabled: bool) : unit
    entrypoint get_approved(token_id: int) : option(address)
    entrypoint is_approved(token_id: int, approved: address) : bool
    entrypoint is_approved_for_all(owner: address, operator: address) : bool
    datatype event 
            = Transfer(address, address, int)
            | Approval(address, address, int, string)
            | ApprovalForAll(address, address, string)
    Transfer(address, address, int)
    Approval(address, address, int, string)
    ApprovalForAll(address, address, string)
    contract interface IAEX141Receiver = 
        entrypoint on_aex141_received : (option(address), int, option(string)) => bool
    entrypoint on_aex141_received(from: option(address), token_id: int, data: option(string)) : bool
    contract interface IAEX141Mintable =
    
        datatype event = Mint(address, int)
    
        stateful entrypoint mint : (address, option(metadata), option(string)) => int
    stateful entrypoint mint(owner: address, metadata: option(metadata), data: option(string)) : int
    contract interface IAEX141MintableLimit =
    
        datatype event
            = TokenLimit(int)
            | TokenLimitDecrease(int, int)
    
        entrypoint token_limit : () => int
        stateful entrypoint decrease_token_limit : (int) => unit
    entrypoint token_limit() : ínt
    stateful entrypoint decrease_token_limit(new_limit: int) : unit
    contract interface IAEX141Burnable =
    
        datatype event = Burn(address, int)
    
        stateful entrypoint burn : (int) => unit
    stateful entrypoint burn(token_id: int) : unit
    contract interface IAEX141MintableTemplates =
    
        datatype template_metadata_type = T_URL | T_MAP
    
        datatype event 
            = TemplateCreation(int)
            | TemplateDeletion(int)
            | TemplateMint(address, int, int, string)
            | EditionLimit(int, int)
            | EditionLimitDecrease(int, int, int)
    
        record template =
            { immutable_metadata: metadata
            , edition_limit: option(int)
            , edition_supply: int }
    
        entrypoint template_metadata_type : () => template_metadata_type
        entrypoint template : (int) => option(template)
        entrypoint template_supply : () => int
    
        stateful entrypoint create_template : (metadata, option(int)) => int
        stateful entrypoint delete_template : (int) => unit
        stateful entrypoint template_mint : (address, int, option(string)) => int
        stateful entrypoint decrease_edition_limit : (int, int) => unit
    entrypoint template_metadata_type() : template_metadata_type
    entrypoint template(template_id: int) : option(template)
    entrypoint template_supply() : ínt
    stateful entrypoint create_template(immutable_metadata: metadata, edition_limit: option(int)) : int
    stateful entrypoint delete_template(template_id: int) : unit
    stateful entrypoint template_mint(to: address, template_id: int, data: option(string)) : int
    stateful entrypoint decrease_edition_limit(template_id: int, new_limit: int) : unit
    contract interface IAEX141MintableTemplatesLimit =
    
        datatype event 
            = TemplateLimit(int)
            | TemplateLimitDecrease(int, int)
    
        entrypoint template_limit : () => int
    
        stateful entrypoint decrease_template_limit : (int) => unit
    entrypoint template_limit() : ínt
    stateful entrypoint decrease_template_limit(new_limit: int) : unit
    contract interface IAEX141MutableAttributes =
    
        datatype event = MutableAttributesUpdate(int, string)
    
        stateful entrypoint update_mutable_attributes : (int, string) => unit
    stateful entrypoint update_mutable_attributes(token_id: int, mutable_attributes: string) : unit
    Mint(address, int)
    TokenLimit(int)
    TokenLimitDecrease(int, int)
    Burn(address, int)
    TemplateCreation(int)
    TemplateMint(address, int, int, string)
    EditionLimit(int, int)
    EditionLimitDecrease(int, int, int)
    TemplateLimit(int)
    TemplateLimitDecrease(int, int)
    MutableAttributesUpdate(token_id, string)
    base_url
    and pointing to a traditional website where metadata is stored
  • ...

  • OBJECT_ID can be used to refer to any kind of item which typically already exists (e.g. the VIN of a car)

  • burnable

  • CollectionTemplateEditionNFTs.aes

    AeMdw - Aeternity Middleware

    Table of Contents

    • Overview

    • Prerequisites

    • Setup

    Overview

    The middleware is a caching and reporting layer which sits in front of the nodes of the . Its purpose is to respond to queries faster than the node can do, and to support queries that for reasons of efficiency the node cannot or will not support itself.

    The architecture of the app is explained .

    Prerequisites

    For running it without Docker, ensure that you have installed, using Erlang 26 or newer.

    If using Docker, make sure you have or newer.

    Setup

    Firstly, clone the middleware repo:

    git clone https://github.com/aeternity/ae_mdw && cd ae_mdw

    Before running it, it's recommended to use a Node database snapshot for faster syncing.

    Database Snapshot

    1. Download one of the full backups from https://downloads.aeternity.io

    2. Create a 'data' directory under the root repo dir and extract the backup to it (it creates a mnesia directory).

    To start a docker container on mainnet, simply run: docker compose up.

    You can check on /status page that the node_height is higher than 600000.

    In case you want to use it on testnet or for development purposes please follow the instructions below.

    Node configuration

    The middleware runs along with an Aeternity Node on the same docker container and BEAM VM instance.

    Its configuration file is found at docker/aeternity.yaml. Under fork_management key, the network_id options are: ae_mainnet and ae_uat (testnet).

    If you are running your own build, on dev environment, with docker-compose-dev.yml the docker/aeternity.yaml is copied when the container is started and it is used as a node configuration file.

    For docker hub images, you can create a volume to copy your local /home/aeternity/aeternity.yaml by uncommenting it on docker-compose.yml.

    You may also redefine other Aeternity node configurations. More information regarding configuration can be found

    Volumes configuration

    The aeternity/ae_mdw docker image runs with unprivileged user (uid=1000).

    Therefore permissions should be given when mapping the data/mnesia and/or data/mdw.db volumes:

    Genesis accounts

    In case you want to setup different accounts on testnet with initial balance you can add this volume to docker-compose-dev.yml:

    - ${PWD}/accounts_test.json:/home/aeternity/node/data/aecore/.genesis/accounts_test.json

    An example of accounts_test.json is:

    Docker

    Starting the middleware with docker is described , to start the middleware as a hyperchain you can follow guide.

    Docker setup for local dev

    The project comes with a two docker compose files:

    • docker-compose.yml: to run the middleware as is

    • docker-compose-dev.yml: for development env that includes dev tools

    A helper script might be used to get a docker shell on dev env: ./scripts/do.sh docker-shell

    You should now be able to navigate through the project having the /app as working directory.

    Tools for local development

    When inside the docker container shell, some useful commands that you might want to run are:

    Hosted Infrastructure

    We currently provide hosted infrastructure at https://mainnet.aeternity.io/mdw/ , all examples here are based on it.

    NOTE: Local deploy with default configuration endpoints will not contain /mdw/ segment on the path.

    HTTP v3 (latest) endpoints

    The routes and respective responses are:

    OpenAPI specs

    The swagger specification of the endpoints can be downloaded from:

    • https://testnet.aeternity.io/mdw/v3/api/

    It can be visualized on a swagger UI at:

    • https://testnet.aeternity.io/mdw/swagger

    This npm package can be also used for a self-hosted app to visualize these specs: https://www.npmjs.com/package/swagger-ui

    Pagination

    The application does not support paginated page-based endpoints. Instead, a cursor-based pagination is offered. This means that in order to traverse through a list of pages for any of the paginated endpoints, either the next or prev field from the current page has to be used instead.

    Asking for an arbitrary page, without first retrieving it from the next orprev field is not supported.

    The paginated endpoints return JSON in the following format:

    The continuation-URL, when concatenated with host, has to be used to retrieve a new page of results.

    Examples

    Getting the first transaction:

    Getting the next transaction by prepending host (https://mainnet.aeternity.io/mdw) to the continuation-URL from last request:

    Once there are no more transactions for a query, the next and/or prev key is set to null.

    Limit

    The client can set limit explicitly if he wishes to receive different number of transactions in the reply than 10 (max 100).

    Scope

    The scope parameter specifies the time period to look for results matching the criteria:

    • gen:A-B - from generation A to B (forward if A < B, backward otherwise)

    Not all paginated endpoints support all scopes.

    Direction

    All paginated endpoints support a direction parameter that specifies the order in which results are expected to be returned.

    It can be either forward or backward (default).

    Additional endpoint options

    In many of the endpoints there's some additional query parameters that can be sent to change the endpoint behavior.

    top

    When top=true, it displays the latest state of the changes by querying the node directly. This is allowed on some of the AEx9 endpoints to obtain the latest balances state for a given contract.

    int-as-string

    If this flag is set to true, the response will have all integers set as strings


    Transactions

    /v3/transactions

    Querying for transactions via /v3/transactions endpoint supports 3 kinds of parameters specifying which transactions should be part of the reply:

    • types

    • generic ids

    • transaction fields

    Types

    Types of transactions in the resulting set can be constrained by providing type and/or type_group parameter. The query allows providing of multiple type & type_group parameters - they form a union of admissible types. (In other words - they are combined with OR.)

    Supported types:

    • channel_close_mutual, channel_close_solo, channel_create, channel_deposit, channel_force_progress, channel_offchain, channel_settle, channel_slash, channel_snapshot_solo, channel_withdraw.

    Supported type groups:

    • channel

    • contract

    • ga

    • name

    Examples:

    type parameter:

    type_group parameter:

    Generic IDs

    Generic ids allow selecting of transactions related to the provided id in any way.

    With generic ids, it is possible to select also create/register transactions of particular AEternity object (like contract, channel or oracle), despite the fact that these transactions don't have the ID of the created object among its transaction fields.

    Supported generic IDs:

    • account

    • contract

    • channel

    • oracle

    Examples

    Transaction fields

    Every transaction record has one or more fields with identifier, represented by public key. Middleware is indexing these fields and allows them to be used in the query.

    Supported fields with provided transaction type:

    The syntax of the field with provided type is: type.field - for example: spend.sender_id

    The fields for transaction types are:

    • channel_close_mutual - channel_id, from_id

    • channel_close_solo - channel_id, from_id

    • channel_create - initiator_id, responder_id

    • channel_deposit - channel_id, from_id

    Supported freestanding fields:

    In case a freestanding field (without transaction type) is part of the query, it deduces the admissible set of types to those which have this field.

    The types for freestanding fields are:

    • account_id - name_claim, name_preclaim, name_revoke, name_transfer, name_update, oracle_register

    • caller_id - contract_call

    • channel_id - channel_close_mutual, channel_close_solo, channel_deposit, channel_force_progress, channel_offchain, channel_settle, channel_slash, channel_snapshot_solo, channel_withdraw

    • commitment_id - name_preclaim

    Supported inner transactions fields:

    The ga_meta and paying_for transactions have inner transactions which might be filtered as if they were not inner.

    For example, for a GAMetaTx with inner SpendTx, one might request with the following query params:

    • spend.recipient_id or

    • spend.sender_id or

    • spend.recipient_id and spend.sender_id

    Examples

    with provided transaction type (name_transfer):

    freestanding field from_id, and via jq extracting only hash and transaction type:

    Mixing of query parameters

    The query string can mix types, global ids and transaction fields.

    The resulting set of transactions must meet all constraints specified by parameters denoting ID (global ids and transaction fields) - the parameters are combined with AND.

    If type or type_group is provided, the transaction in the result set must be of some type specified by these parameters.

    Examples

    transactions where each transaction contains both accounts, no matter in which field:

    spend transactions between sender and recipient (transaction type = spend is deduced from the fields):

    name related transactions for account:

    /v3/transactions/:hash

    Single transactions can be obtained by either the identifying hash or transaction index.

    /txs/count

    Counting all transactions

    It can also be scoped by generations:

    Or by address:

    Or by type:

    NOTE: It cannot be filtered by more than one of these filters.


    Blocks

    /v3/key-blocks

    There are several endpoints for querying block(s) or generation(s). A generation can be understood as key block and micro blocks containing transactions.

    Since we are returning whole generations, replies can be very large.

    Examples below are trimmed heavily.

    With /v3/key-blocks endpoint:

    Numeric range:

    /v3/key-blocks/:hash_or_kbi

    Retrieves a single key block including the micro_blocks_count and transactions_count counters.

    Or alternatively, by kbi:

    /v3/key-blocks

    Returns a paginated list of key-blocks together with the amount of micro blocks and transactions each key-block generation has.

    /v3/key-blocks/:hash_or_kbi/micro-blocks

    /v3/micro-blocks/:hash

    /v3/micro-blocks/:hash/txs


    Naming System

    There are several endpoints for querying of the Naming System.

    Name objects in Aeternity blockchain have a lifecycle formed by several types of transactions. Names can become claimed (directly or via name auction), updated the lifespan or pointers, transferred the ownership and revoked when not needed.

    Information about the name returned from the name endpoints summarizes this lifecycle in vectors of transaction indices, under keys claims, updates, transfers and optional transaction index in revoke.

    Transaction index is useful for retrieving detailed information about the transaction via txi/:index endpoint.

    Using transactions/:hash endpoint is flexible, on-demand way to get detailed transaction information, but in some situations leads to multiple round trips to the server.

    Due to this reason, all name endpoints except name/pointers and name/pointees support expand parameter (either set to true or without value), which will replace the transaction indices with the JSON body of the transaction detail.

    /v3/names

    Names can be filtered by state, which can contain the following values:

    • inactive - for listing inactive names (expired or revoked)

    • active - for listing active names

    • auction - for listing auctions

    They support ordering via parameters by (with value activation, deactivation or name).

    Using the by=activation requires state=active and includes only successfully claimed names (those in auction won't appear yet).

    Using the by=deactivation means for inactive names that they are sorted by the height of deactivation, whether the name had expired or had been revoked. For active names it means they are sorted by expiration height.

    Without these parameters, the endpoints return results ordered as if by=deactivation were provided.

    Active names

    Additionally, this endpoint allows you to filter by name owner using the query param owned_by:

    An example of by usage:

    Names can also be filtered by prefix, as long as they are NOT filtered by owner and ordered by name (e.g. ?prefix=somenam&by=name).

    /v3/names/auctions

    To show auctions ordered by name, from the beginning:

    /v3/names/:name_or_hash

    It's possible to use encoded hash as well:

    If the name is currently in auction, the reply has different shape:

    /v3/names/auctions/:name

    Auction specific name resolution is available behind this endpoint:

    /v3/accounts/:account_id/names/pointees

    Returns names pointing to a particular pubkey. Can be scoped by gen using scope=gen:100-200 query parameter.

    /v3/names/:name/claims

    Returns the name claims, paginated.

    /v3/names/:name/transfers

    Returns the name transfers, paginated.

    /v3/names/:name/updates

    Returns the name updates, paginated.


    Contracts

    /v3/contracts

    Paginatable list of all non-preset contracts, filterable by scope.

    /v3/contracts/:id

    Get a single contract.

    /v3/contracts/logs

    A paginable contract log endpoint allows querying of the contract logs using several querying parameters, including:

    • contract_id - listing only logs emitted by given contract

    • event - listing only logs emitted by particular event constructor (base32hex encoded blake2b hash)

    • data - listing only logs which have data field matching the provided prefix

    The attributes returned on each object are the following:

    • args - a list of event constructor arguments as big integers. Contract bytecode doesn't contain metadata describing the types of the contract events. As a result, we can only report the binary blobs to the user, which can be either an integer (probably denoting an amount or counter), or public key. The integer can be converted to public key (256-bits) binary in Elixir (or Erlang) shell:

    • call_tx_hash - hash of contract call transaction which emitted the event log

    • contract_id - contract identifier

    Note for contract writers

    From the above, it is obvious that due to the lack of useful metadata in the contract bytecode, browsing contract logs isn't user friendly.

    However, logs are still useful for people writing the contracts since they have source code of the contract.

    With access to the contract's source code, the developer can:

    • identify the event log constructor from the event_hash field

    • with the constructor, the developer knows the types of args for a particular event log

    • integer arguments are then understandable literally, while hashes need one more step:

    Listing the last (to date) contract log in the chain:

    Listing contract logs in range between generations 200000 and 210000:

    Listing contract logs in generation 250109 only:

    Listing latest logs for given contract

    Listing first logs where data field points to aeternity.com: (The value of data parameter needs to be URL encoded, which is not visible in this example)

    Listing the last "TipReceived" event:

    /v3/contracts/calls

    A running contract can call other functions during execution. These calls are recorded and can be queried later.

    The query accepts following filters:

    • fname - The prefix of the name of the function

    • contract - The contract for the calls

    • ID field - Any field belonging to the contract call transaction

    Using contract id

    Using function prefix

    Using ID field

    Following ID fields are recognized: account_id, caller_id, channel_id, commitment_id, from_id, ga_id, initiator_id, name_id, oracle_id, owner_id, payer_id, recipient_id, responder_id, sender_id

    Contract_id field is inaccessible via this lookup, as when present in query, it filters only contracts with given contract id and doesn't look into internal transaction's fields.


    Internal transfers

    /v3/transfers

    During the operation of the node, several kinds of internal transfers happen which are not visible on general transaction ledger.

    Besides specifying of scope and direction as with other streaming endpoints (via forward/backward or gen), the query accepts following filters:

    • kind. At the moment, following kinds of transfers can be queried:

      • fee_spend_name (fee for placing bid to the name auction)

      • fee_refund_name (returned fee when the new name bid outbids the previous one in the name auction)

    Listing internal transfers in range

    Listing internal transfers of a specific kind

    Listing internal transfers related to specific account


    Oracles

    There are several endpoints for fetching information about the oracles.

    Oracles in Aeternity blockchain have a lifecycle formed by several types of transactions, similar to the Name objects.

    /v3/oracles

    There is only paginable endpoint for listing oracles, which can be filtered by scope (e.g. gen:100-200) or state (active or inactive).

    Inactive oracles

    Active oracles

    /v3/oracles/:id

    /v3/oracles/:id/queries

    Paginated list of an oracle's queries.

    /v3/oracles/:id/responses

    Paginated list of an oracle's responses to queries.


    Channels

    /v3/channels

    Returns active channels ordered by the txi of the last update.

    These can also be filtered by state=active or state=inactive.

    Besides the participants balances it includes some fields intrinsic to the channel such as:

    • the reserve deposited in the channel for paying fees and assuring refunds;

    • lock parameters, in case of individual actions; and

    • delegates allowed to represent participants

    /v3/channels/:id

    Returns the state of an active/inactive channel.

    Optionally a block_hash parameter might be used to query for the state on a specific block.

    In this example it retrieves the ChannelDepositTx as the last udpate for a block prior to the last update that was a ChannelCloseMutualTx.

    /v3/channels/:id/updates

    Returns a paginated list of updates done to a channel.

    AEX9 tokens

    AEx9 tokens standard is defined by AEX9 (https://github.com/aeternity/AEXs/blob/master/AEXS/aex-9.md).

    /v3/aex9

    Returns paginated list of AEx9 contracts. Can be sorted with the by query parameter by name (default), symbol or creation.

    These endpoints accepts an optiona parameter of prefix OR exact for listing tokens with the name or symbol, which are matching either by prefix, or exactly.

    /v3/aex9/:contract_id

    /v3/aex9/:contract_id/balances

    /v3/aex9/:contract_id/balances/:account_id

    /v3/aex9/:contract_id/transfers


    NFTs (AEX-141 contracts and tokens)

    AEX-141 NFT contracts might organize the access and storage of NFTs metadata in flexible ways. This behaviour is declared during contract creation with the metadata_type field. This and other meta_info fields like name and symbol can be accessed by /aex141 endpoint that displays information about NFT contracts.

    /v3/aex141

    Returns creation and stats information in default paginated way for all NFT collections.

    /v3/aex141/:contract_id

    Returns creation and stats information for a specific NFT collection.

    /v3/aex141/:contract_id/tokens

    Returns the tokens of a collection in paginated way.

    /v3/aex141/:contract_id/tokens/:token_id

    Returns the owner wallet address of a NFT.

    /v3/aex141/:contract_id/templates

    Returns the NFT templates of a collection in paginated way.

    /v3/aex141/:contract_id/templates/:template_id/tokens

    Returns the NFTs from a collection template in paginated way.

    /v3/accounts/:account_id/aex141/tokens

    Returns each NFT owned by a wallet in paginated way.

    /v3/aex141/:contract_id/transfers

    Returns all NFT transfers involving a NFT collection in paginated way.

    /v3/aex141/transfers

    Returns paginated NFT transfers where you can filter by an account being the sender, recpient or both.


    Statistics

    /v3/stats/delta

    To show a statistics for a given height, we can use "stats" endpoint:

    /v3/stats/total

    Aggregated (summarized) statistics are also available, showing the total sum of rewards and the token supply:

    These endpoints allow pagination, with typical forward/backward direction or scope denoted by gen/from-to.

    /v3/stats/miners

    Total reward given to each chain miner.

    /v3/stats/blocks

    Retrieve the total count of blocks over time, with an optional filter by block type (key or micro). By default, this will count all blocks.

    You can adjust the time granularity of the results using the interval_by query parameter, which supports day (default), week, or month.

    Additionally, filter results by specifying a date range with the min_start_date and/or max_start_date parameters. Dates should be provided in ISO 8601 format.

    /v3/stats/names

    Retrieve the count of names over time.

    Similar to block stats, interval_by, min_start_date and max_start_date can be used.

    /v3/stats/transactions

    Retrieve the count of transactions over time, with an optional filter by transaction type. By default, this will count all transactions.

    Similar to blocks stats, interval_by, min_start_date and max_start_date can be used.

    /v3/stats

    Global statistics.


    Activities

    Intended for being able to display all events in which a specific account is related to in any way.

    An activity event occurs when there's any change in the blockchain related to a specific account. It is not the same as the log events which occur when executing a contract.

    /v3/accounts/:id/activities

    Paginated list of events related to the :id account.

    Each activity contains 3 values:

    • height - The height in which the event occurred

    • type - The type of event.

    • payload - An object whose structure depends on the type of event.

    For transaction events the activity type will be <TxType>Event, and the payload will contain a single transaction object as displayed in the /v3/transactions endpoint.

    Transaction events can also be InternalContractCallEvent which represent transactions that happen internally during a contract call.

    Optionally the owned_only=true parameter might be used to return only activities initiated by the account.

    Additionally, activities can be filtered by any of these types using ?type=<type> query parameter:

    • transactions - Transactions containing the account in any of the transaction fields

    • aexn - AExN (aex9 and aex141) activities

    • aex9 - AEx9 activities

    Websocket interface

    The websocket interface, which listens by default on port 4001, gives asynchronous notifications when various events occur. Each event is notified twice: firstly when the Node has synced the block or transaction and after when AeMdw indexation is done. In order to differentiate, please check the "source" field on .

    Subscription Message format

    Supported subscription operations

    • Subscribe

    • Unsubscribe

    Supported payloads

    • KeyBlocks

    • MicroBlocks

    • Transactions

    • Object, which takes a further field, target - can be any æternity entity. So you may subscribe to any æternity object type, and be sent all transactions which reference the object. For instance, if you have an oracle ok_JcUaMCu9FzTwonCZkFE5BXsgxueagub9fVzywuQRDiCogTzse

    /websocket

    The V1 websocket interface accepts JSON - encoded commands to subscribe and unsubscribe, and answers these with the list of subscriptions. A session will look like this:

    Actual chain data is wrapped in a JSON structure identifying the subscription to which it relates.

    Publishing Message format

    When the source is "node" it means that the Node is synching the block or transaction (not yet indexed by AeMdw). If it's "mdw", it indicates that it's already available through AeMdw Api.

    /v3/websocket

    The V3 websocket interface behaves the same way as the V1 interface, but when the published message has source mdw it returns the rendered representation of the object as it would be rendered by the middleware (e.g. the returned object for the Transactions subscription will be the same object as returned by the /v3/transactions endpoint).

    Tests

    Unit tests

    Running unit tests will not sync the database. To run them:

    Integration tests

    The database has to be fully synced. Then, run the tests with:

    Devmode tests

    These tests allow you to create your own transactions using the devmode (plus the JS SDK). To add newer tests you need to:

    1. Add the transactions creation on node_sdk/index.js.

    2. Run the JavaScript file using docker compose -f docker-compose-dev.yml run node_sdk node index.js.

    3. Add new devmode tests under the test/devmode/ directory.

    CI

    Actions

    On push:

    • Commit linter for conventional commit messages

    • Elixir code formatting

    • Credo

    • Dialyzer

    On merge to master:

    • Release with notes based on git history

    Git hooks

    In order to anticipate some of these checks one might run mix git_hooks.install. This installs pre_commit and pre_push checks as defined by config :git_hooks in dev.tools.exs.

    If sure about the change, if it was for example in an integration test case and it was already tested and formatted, one can use git push --no-verify to bypass the hook.

    Auto-generated Documentation

    Every time an endpoint is changed, the swagger v2 file should be changed as well.

    contract_call, contract_create

  • ga_attach, ga_meta

  • name_claim, name_preclaim, name_revoke, name_transfer, name_update

  • oracle_extend, oracle_query, oracle_register, oracle_response

  • paying_for

  • spend

  • oracle

  • paying

  • spend

  • channel_force_progress - channel_id, from_id

  • channel_offchain - channel_id

  • channel_settle - channel_id, from_id

  • channel_slash - channel_id, from_id

  • channel_snapshot_solo - channel_id, from_id

  • channel_withdraw - channel_id, to_id

  • contract_call - caller_id, contract_id

  • contract_create - owner_id, contract_id

  • ga_attach - owner_id, contract_id

  • ga_meta - ga_id

  • name_claim - account_id

  • name_preclaim - account_id, commitment_id

  • name_revoke - account_id, name_id

  • name_transfer - account_id, name_id, recipient_id

  • name_update - account_id, name_id

  • oracle_extend - oracle_id

  • oracle_query - oracle_id, sender_id

  • oracle_register - account_id

  • oracle_response - oracle_id

  • paying_for - payer_id

  • spend - recipient_id, sender_id

  • contract_id - contract_call

  • entrypoint - contract_call

  • from_id - channel_close_mutual, channel_close_solo, channel_deposit, channel_force_progress, channel_settle, channel_slash, channel_snapshot_solo

  • ga_id - ga_meta

  • initiator_id - channel_create

  • name_id - name_revoke, name_transfer, name_update

  • oracle_id - oracle_extend, oracle_query, oracle_response

  • owner_id - contract_create, ga_attach

  • payer_id - paying_for

  • recipient_id - name_transfer, spend

  • responder_id - channel_create

  • sender_id - oracle_query, spend

  • to_id - channel_withdraw

  • function - the name of the function called

  • aexn-args- formats the args topics according to the event type

  • data - decoded (human readable) data field of event log (if any)

  • event_hash - base32hex encoded blake2b hash of the name of the event constructor The source of the contract in question has one of the event log constructors named "TipReceived". Its encoded hash can be retrieved as:

  • ext_caller_contract_id - caller contract id, potentially different to contract_id, if the contract which emitted the event was called from other contract

  • log_idx - contract call can emit many events. Log idx uniquely identifies the event log inside the contract call.

  • after extracting the binary of the argument, this binary should be then passed to:

    where the <id-type> can be one of: :account_pubkey, :contract_pubkey, :oracle_pubkey and others, the full list of known types is here (in Erlang syntax):

    https://github.com/aeternity/aeserialization/blob/master/src/aeser_api_encoder.erl#L16

    ,
    to_id
    .

    fee_lock_name (locked fee of the name auction winning)

  • reward_oracle (reward for the operator of the oracle (on transaction basis))

  • reward_block (reward for the miner (on block basis))

  • reward_dev (reward for funding of the development (on block basis))

  • accounts_minerva, accounts_fortuna and accounts_lima (added on hardforks including migrated ERC20 amounts)

    It it possible to provide just a prefix of the kind in interest, e.g.: "reward" will return all rewards, "fee" will return all fees, "accounts" will return credits after hardforks.

  • account - account which received rewards or that was charged fees or that received tokens after a hardfork migration.

  • aex141 - AEx141 activities
  • contract - Internal and external contract calls

  • transfers - Internal (both gen-based and tx-based) transfers

  • claims - Name claims related to the name hash

  • you may subscribe to this object and be notified of any events which relate to it - presumable you would be interested in queries, to which you would respond. Of course you can also subscribe to accounts, contracts, names, whatever you like.
    Run tests using ./scripts/test-devmode.sh.
    Unit tests
  • ExCoveralls

  • Database snapshot
    Node Configuration
    Volumes Configuration
    Genesis accounts
    Docker setup for local dev
    Tools for local development
    Hosted infrastructure
    HTTP v3 (latest) endpoints
    OpenAPI specs
    Pagination
    Additional endpoint options
    Transactions
    Blocks
    Naming System
    Contracts
    Internal transfers
    Oracles
    Channels
    AEX9 tokens
    NFTs
    Statistics
    Activities
    Websocket interface
    Tests
    Auto-generated Documentation
    æternity blockchain
    here
    Elixir 1.17
    Docker 27
    here
    here
    this
    Publishing Message format
    iex(aeternity@localhost)11> Base.hex_encode32(:aec_hash.blake2b_256_hash("TipReceived"))
    "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0===="
    :aeser_api_encoder.encode(<id-type>, extracted-binary)
    mkdir -p data/mnesia data/mdw.db
    chown -R 1000 data
    {
       "ak_2a1j2Mk9YSmC1gioUq4PWRm3bsv887MbuRVwyv4KaUGoR1eiKi": 10000000000000000000000000000000
    }
    iex --sname aeternity@localhost -S mix                                        # IEx shell
    elixir --sname aeternity@localhost -S mix phx.server                          # Start the server
    elixir --sname aeternity@localhost -S mix test                                # Unit tests
    INTEGRATION_TEST=1 elixir --sname aeternity@localhost -S mix test.integration # Integration tests
    mix format                                                                    # Run formatting tool
    mix credo                                                                     # Run `credo` tool
    mix dialyzer                                                                  # Run `dialyzer` tool
    GET /v3/key-blocks                           - key blocks with micro blocks and transaction counts
    GET /v3/key-blocks/:hash_or_kbi              - key block by hash or height
    GET /v3/key-blocks/:hash_or_kbi/micro-blocks - micro block belonging to key block
    GET /v3/micro-blocks/:hash                   - micro block with transaction count
    GET /v3/micro-blocks/:hash/transactions      - micro block transactions
    
    GET /v3/transactions                            - transactions in any direction
    GET /v3/transactions/:hash                      - transaction by hash
    GET /v3/transactions/count                      - total number of transactions (last transaction index + 1)
    
    GET /v3/accounts/:id/activities             - transactions, internal contract calls, AEX-N and internal transfers involving an account
    GET /v3/accounts/:account_id/aex9/balances  - aex9 account balances
    GET /v3/accounts/:account_id/names/pointees - AENS names that point to the account
    
    GET /v3/contracts                         - contracts
    GET /v3/contracts/:id                     - contract by id
    GET /v3/contracts/logs                    - contract logs
    GET /v3/contracts/calls                   - contract calls
    
    GET /v3/names                              - AENS names
    GET /v3/names/:id/auction                  - AENS name auction
    GET /v3/names/:id/pointers                 - AENS name pointer
    GET /v3/names/auctions                     - all AENS name auctions
    GET /v3/names/:id                          - AENS name state and transaction history
    GET /v3/names/:id/claims                   - AENS name claims history
    GET /v3/names/:id/updates                  - AENS name update history
    GET /v3/names/:id/transfers                - AENS name transfer history
    
    GET /v3/oracles                         - expired oracles ordered by expiration height, filtered by active/inactive state and scope
    GET /v3/oracles/:id                     - oracle information by hash
    GET /v3/oracles/:id/queries             - oracle queries
    GET /v3/oracles/:id/responses           - oracle responses
    
    GET /v3/channels                        - active channels ordered by activation height
    GET /v3/channels/:id                    - active or inactive channel
    GET /v3/channels/:id/updates            - displays all updates done to a channel
    
    GET /v3/transfers                        - internal transfers from the top of the chain
    
    GET /v3/aex9                                           - aex9 contracts
    GET /v3/aex9/:contract_id                              - aex9 contract tokens
    GET /v3/aex9/:contract_id/balances                     - aex9 contract balances
    GET /v3/aex9/:contract_id/balances/:account_id         - aex9 contract account balance
    GET /v3/aex9/transfers                                 - aex9 transfers that can be filtered by sender/recipient
    GET /v3/aex9/:contract_id/balances/:account_id/history - aex9 contract account balances history
    
    GET /v3/aex141                                         - nft contracts meta info and stats
    GET /v3/aex141/:contract_id                            - nft contract meta info and stats
    GET /v3/aex141/owned-nfts/:account_id                  - nfts owned by a wallet
    GET /v3/aex141/:contract_id/owner/:token_id            - the owner wallet address of a NFT
    GET /v3/aex141/:contract_id/owners                     - the owners wallets of NFTs from a collection
    GET /v3/aex141/:contract_id/templates                  - nft templates
    GET /v3/aex141/:contract_id/templates/:id/tokens       - nft supply from a template
    GET /v3/aex141/transfers                               - nft transfers that can be filtered by sender/recipient
    
    GET /v3/stats/delta                       - statistics for generations from tip of the chain
    GET /v3/stats/total                       - aggregated statistics for generations from tip of the chain
    GET /v3/stats/miners                       - total rewards for each miner
    
    GET /v3/stats/transactions                - statistics over time of transactions count
    GET /v3/stats/blocks                      - statistics over time of blocks count
    GET /v3/stats/names                       - statistics over time of names count
    GET /v3/stats                             - global statistics
    
    GET /v3/status                           - middleware status
    {
      "data": [...objects...],
      "next": continuation-URL or null,
      "prev": continuation-URL or null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2Rkmk15VeTVWTHt9bVBFcQRuvseKCkuHpm1RexsMcpAdZpFCLx",
          "block_height": 77216,
          "hash": "th_MutYY63TMfYQ7z4rWrQd8WGJqszz1h3FdAGHYLVYJBquHoG2V",
          "micro_index": 0,
          "micro_time": 1557275476873,
          "signatures": [
            "sg_SKC9yVm59qNh3HrpRdqfbkYnoH1ksypECnPxe67iuPadF3KN7HjR4D7qs4gYkeAhbgno2yUjHfZMcTxrF6CKFZQPaGfdq"
          ],
          "tx": {
            "amount": 1e+18,
            "fee": 16840000000000,
            "nonce": 7,
            "payload": "ba_Xfbg4g==",
            "recipient_id": "ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD",
            "sender_id": "ak_2cLJfLQPhkTiz7RCVQ9ii8mVPJu8gHLy6qpafmTcHYrFYWBHCG",
            "type": "SpendTx",
            "version": 1
          },
          "tx_index": 1776073
        }
      ],
      "next": "/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&cursor=1779354&limit=1",
      "prev": "/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&cursor=19813844&limit=1&rev=1"
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&cursor=1779354&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_SDfdhTd3zfTpAqHMUJsX8RjAm6QyrZYgtqNf3y6EdMMSppEgd",
          "block_height": 77865,
          "hash": "th_2RfB4NrPNyAr8gkm5vTQimVo6uBcZMQfmqdY8LZkuRJfhcs3HA",
          "micro_index": 0,
          "micro_time": 1557391780018,
          "signatures": [
            "sg_XjVTnUbvytX3pAbQQvwYFYXETCqDKzyen7kXqoEqRm5hr6m72k3RzKBHP4GWTHup51ZnxQuDf8R8Rxu5fUwAQGeQMHmh1"
          ],
          "tx": {
            "amount": 1e+18,
            "fee": 16840000000000,
            "nonce": 6,
            "payload": "ba_Xfbg4g==",
            "recipient_id": "ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD",
            "sender_id": "ak_2iK7D3t5xyN8GHxQktvBnfoC3tpq1eVMzTpABQY72FXRfg3HMW",
            "type": "SpendTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&cursor=1779356&limit=1",
      "prev": "/v3/transactions?direction=backward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&cursor=1776073&limit=1&rev=1"
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&type=channel_create&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2aw4KGSWLq7opXT796a5QZx8Hd7BDaGRSwEcyqzNQMii7MrGrv",
          "block_height": 1208,
          "hash": "th_25ofE3Ah8Fm3PV8oo5Trh5rMMiU4E8uqFfncu9EjJHvubumkij",
          "micro_index": 0,
          "micro_time": 1543584946527,
          "signatures": [
            "sg_2NjzKD4ZKNQiqjAYLVFfVL4ZMCXUhVUEXCmoAZkhAZxsJQmPfzWj3Dq6QnRiXmJDByCPc33qYdwTAaiXDHwpdjFuuxwCT",
            "sg_Wpm8j6ZhRzo6SLnaqWUb24KwFZ7YLws9zHiUKvWrf89cV2RAYGqftXBAzS6Pj7AVWKQLwSjL384yzG7hK4rHB8dn2d67g"
          ],
          "tx": {
            "channel_id": "ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD",
            "channel_reserve": 10,
            "delegate_ids": [],
            "fee": 20000,
            "initiator_amount": 50000,
            "initiator_id": "ak_ozzwBYeatmuN818LjDDDwRSiBSvrqt4WU7WvbGsZGVre72LTS",
            "lock_period": 3,
            "nonce": 1,
            "responder_amount": 50000,
            "responder_id": "ak_26xYuZJnxpjuBqkvXQ4EKb4Ludt8w3rGWREvEwm68qdtJLyLwq",
            "state_hash": "st_MHb9b2dXovoWyhDf12kVJPwXNLCWuSzpwPBvMFbNizRJttaZ",
            "type": "ChannelCreateTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&cursor=73270&limit=1&type=channel_create"
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&type_group=oracle&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2G7DgcE1f9QJQNkYnLyTYTq4vjR47G4qUQHkwkXpNiT2J6hm5T",
          "block_height": 4165,
          "hash": "th_iECkSToLNWJ77Fiehi39zxJwLjPfstsAtYFC8rbCsEStEy1xv",
          "micro_index": 0,
          "micro_time": 1544106799973,
          "signatures": [
            "sg_XoYmhU7J6XzJazUvo48ijUKRj5DweV8rBuwBwgdZUiUEeYLe1h4pdJ7jbBWGHC8M7diMA2AFrH1AL739XNChX4wrH58Ng"
          ],
          "tx": {
            "abi_version": 0,
            "account_id": "ak_g5vQK6beY3vsTJHH7KBusesyzq9WMdEYorF8VyvZURXTjLnxT",
            "fee": 20000,
            "nonce": 1,
            "oracle_id": "ok_g5vQK6beY3vsTJHH7KBusesyzq9WMdEYorF8VyvZURXTjLnxT",
            "oracle_ttl": {
              "type": "delta",
              "value": 1234
            },
            "query_fee": 20000,
            "query_format": "the query spec",
            "response_format": "the response spec",
            "type": "OracleRegisterTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&cursor=8892&limit=1&type_group=oracle",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&contract=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&limit=2" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_ZwPrtCMWMPF5e4RLoaY8cb6HUGadSKknpy5gp8nrDes3eSKyZ",
          "block_height": 218938,
          "hash": "th_6memqAr5S3UQp1pc4FWXT8xUotfdrdUFgBd8VPmjM2ZRuojTF",
          "micro_index": 2,
          "micro_time": 1582898946277,
          "signatures": [
            "sg_LiNE1DtiFkUH19WtJ1p9tX9Zy9fuGaW3bAop1mLCe5jJktQ3XiAu2Bop6JPBrkHyi1eQ2xCyPXQxZmiyqroMwaL7BrqWN"
          ],
          "tx": {
            "abi_version": 3,
            "amount": 0,
            "call_data": "cb_KxFE1kQfK58CoImYHijBOQaROWmeJkniQvuQjKtkbE5UZnXQ+sB9eLb1nwCgkRvEABX1lZmfsIGIeFuXiHMZfg6eGt4RXdqdu+P8EZ1cfiCj",
            "code": "cb_+QdxRgOgfRB0ofOTJwMaz73GwgUNX4rSsqh81yEyoDCgyFqUs63AuQdDuQXM/ir6YP4ENwEHNwAvGIgABwwE+wNBVElQX05PVF9FWElTVElORxoKBogrGggGABoKCoQoLAgIKwoMCiguDgAMKC4QAgwaChKKMQoUElUACwAUOA4CDAEAJwwIDwIcCwAUCi4QDAIODAIuJwwEKCwICC0KhIQtqoqKFBwaCkCGVQALACgsCAgrCEBE/DMGBgYCBgQDEWWl4A/+PR6JaAA3ADcHZ3cHZwc3AgcHZwd3Zwc3BkcAdwcHBwdnBzcERwAHBwdHAEcCDAKCDAKEDAKGDAKIDAKKDAKMDAKOJwwOAP5E1kQfADcCRwJHADcAGg6CLwAaDoQvABoOhi8AGg6ILwAaDoovABoGjAIaBo4AAQM//liqK7MANwF3JzcGRwB3BwcHBy8YggAHDAT7A0FVUkxfTk9UX0VYSVNUSU5HGgoGghoKCogyCAoMAxFkJuW0KxgGACcMBAQDEWh21t/+W1GPJgA3AXcHLxiCAAcMBPsDQVVSTF9OT1RfRVhJU1RJTkcaCgaCKxoIBgAaCgqEKyoMCggoLAIMAP5kJuW0AjcC9/f3KB4CAgIoLAgCIBAABwwEAQMDNDgCAwD+ZOFddAA3AUcCNwACAxFsZXWrDwJvgibPGgaOAAEDP/5lpeAPAjcBhwM3A0cAB3c3A0cAB3c3A0cAB3c3AAn9AAIEBkY2AAAARjYCAAJGNgQABGOuBJ8Bgbfh7SDBdTd1sh5gynCHKbCjz+owLcaWOKxkvaOqFD+8AAIBAz9GNgAAAEY2AgACRjYEAARjrgSfAYFroODuqDgz06d0bgFzLA3+WX8iEYX/NjmzrNC0Dn7DPgACAQM/RjYAAABGNgIAAkY2BAAEY64EnwGBV3MM/1lAjn9BBvAm1QmZfTQXiQoofqgl4BJQMzPBlBAAAgEDP/5nCp0GBDcCd0cANwAMAQIMAQALAAwCjgMA/BHCC+urNwJ3RwA3AAD+aHbW3wI3AjcCd/cn5wAn5wEzBAIHDAg2BAIMAQACAxFodtbfNQQCKBwCACgcAAACADkAAAEDA/5sZXWrAjcANwBVACAgjAcMBPsDOU9XTkVSX1JFUVVJUkVEAQM//pLx5vMANwJ3RwA3AxdHAAcMA38MAQIMAQAMAwAMAo4DAPwRJz2AQTcDd0cAFzcDF0cABwD+lMr4XwI3Avf39ygeAgICKCwGAiAQAAcMBAEDAzQ4AgMA/pWEerICNwF3BxoKAIIvGIIABwwIDAOvggABAD8PAgQIPgQEBhoKBoIxCggGLWqGhggALZqCggAIAQIIRjgEAAArGAAARPwjAAICAg8CBAg+BAQG/qSV6n0ANwFHADcAAgMRbGV1qw8Cb4Imz1MAZQEAAQM//rOIgD8ANwN3RwAXNwAMAQQMAQIMAQACAxHUfYQwDwJvgibPLxiCAAcMBvsDQVVSTF9OT1RfRVhJU1RJTkcaCgiCKxoKCAAaCgyEKyoODAooLhAADiguEgIOIzgSAAcMCvsDVU5PX1pFUk9fQU1PVU5UX1BBWU9VVGUJAhIMAQIMAhIMAQBE/DMGBgYEBgIDEWWl4A8PAm+CJs8UOBACDAMAJwwELSqEhAoBAz/+zeehTgA3AQcnNwRHAAcHBy8YiAAHDAT7A0FUSVBfTk9UX0VYSVNUSU5HGgoGijIIBgwDEZTK+F8MAQAnDAQEAxFodtbf/tR9hDACNwN3RwAXNwAMAQQMAQIMAQAMAwAMAo4DAPwRJz2AQTcDd0cAFzcDF0cABygMAAcMBvsDgU9SQUNMRV9TRVZJQ0VfQ0hFQ0tfQ0xBSU1fRkFJTEVEAQM//u3Sa0YENwJ3dzcADAEAAgMRlYR6sg8CABoKAoQs6gQCACsAACguBgAEKC4IAgQaCgqIMQoMClUADAECFDgGAlgADAIACwAnDAwPAhYLABQKKAgMAgYMAignDAQtKoSEAC2qiIgMFlUACwAMAQBE/DMGBgYABgQDEWWl4A+5AW4vExEq+mD+FXJldGlwET0eiWglZ2V0X3N0YXRlEUTWRB8RaW5pdBFYqiuzMXRpcHNfZm9yX3VybBFbUY8mRXVuY2xhaW1lZF9mb3JfdXJsEWQm5bQZLl4xMDU2EWThXXRVY2hhbmdlX29yYWNsZV9zZXJ2aWNlEWWl4A8tQ2hhaW4uZXZlbnQRZwqdBiVwcmVfY2xhaW0RaHbW31kuTGlzdEludGVybmFsLmZsYXRfbWFwEWxldatZLlRpcHBpbmcucmVxdWlyZV9vd25lchGS8ebzLWNoZWNrX2NsYWltEZTK+F8ZLl4xMDU1EZWEerJNLlRpcHBpbmcuZ2V0X3VybF9pZBGklep9PW1pZ3JhdGVfYmFsYW5jZRGziIA/FWNsYWltEc3noU45cmV0aXBzX2Zvcl90aXAR1H2EMJ0uVGlwcGluZy5yZXF1aXJlX2FsbG93ZWRfb3JhY2xlX3NlcnZpY2UR7dJrRg10aXCCLwCFNC4yLjAAQNBRMA==",
            "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
            "deposit": 0,
            "fee": 116060000000000,
            "gas": 1000000,
            "gas_price": 1000000000,
            "nonce": 2,
            "owner_id": "ak_26ubrEL8sBqYNp4kvKb1t4Cg7XsCciYq4HdznrvfUkW359gf17",
            "type": "ContractCreateTx",
            "version": 1,
            "vm_version": 5
          }
        },
        {
          "block_hash": "mh_233z34seMczJE7XtGLJN6ZrvJG9eQXG6fdTFymyzYyUyQbt2tY",
          "block_height": 218968,
          "hash": "th_2JLGkWhXbEQxMuEYTxazPurKiwGvo5R6vgqjSBw3R8z9F6b4rv",
          "micro_index": 1,
          "micro_time": 1582904578154,
          "signatures": [
            "sg_HKk9C1vCuHcZRj9zAdh2WvjvwVJwzNkXgPLsqy2SdR3L3hNkc1oMHjNnQxB558mdRWNPP711DMun3KEy9ZYyvo2QgR8B"
          ],
          "tx": {
            "abi_version": 3,
            "amount": 1e+16,
            "arguments": [
              {
                "type": "string",
                "value": "https://github.com/thepiwo"
              },
              {
                "type": "string",
                "value": "Cool projects!"
              }
            ],
            "call_data": "cb_KxHt0mtGK2lodHRwczovL2dpdGh1Yi5jb20vdGhlcGl3bzlDb29sIHByb2plY3RzIZ01af4=",
            "caller_id": "ak_YCwfWaW5ER6cRsG9Jg4KMyVU59bQkt45WvcnJJctQojCqBeG2",
            "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
            "fee": 182980000000000,
            "function": "tip",
            "gas": 1579000,
            "gas_price": 1000000000,
            "gas_used": 3600,
            "log": [
              {
                "address": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
                "data": "cb_aHR0cHM6Ly9naXRodWIuY29tL3RoZXBpd2+QKOcm",
                "topics": [
                  "83172428477288860679626635256348428097419935810558542860159024775388982427580",
                  "32049452134983951870486158652299990269658301415986031571975774292043131948665",
                  "10000000000000000"
                ]
              }
            ],
            "nonce": 80,
            "result": "ok",
            "return": {
              "type": "unit",
              "value": ""
            },
            "return_type": "ok",
            "type": "ContractCallTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&contract=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&cursor=8401663&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&oracle=ok_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2kSWEwFPPMXSjCx3r1nxi3vnpnXAYB7TEVZuEJsSkGjnsewTBF",
          "block_height": 34421,
          "hash": "th_MRDMpanm3UqgNtAtpEsM59LkyX3TL2wXgeXnx4T9Yn8w1f9L1",
          "micro_index": 0,
          "micro_time": 1549551115213,
          "signatures": [
            "sg_LdVk6F8PPMDPW9ZGkAX653GgaSpjRrfgRByKGAjvxUaBAqjgdG7t6NyLs5UPYBWk7xVEfXgyTNgyrjpvfqaFz7DA9L9ZV"
          ],
          "tx": {
            "abi_version": 0,
            "account_id": "ak_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR",
            "fee": 20000,
            "nonce": 18442,
            "oracle_id": "ok_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR",
            "oracle_ttl": {
              "type": "delta",
              "value": 1000
            },
            "query_fee": 20000,
            "query_format": "string",
            "response_format": "int",
            "ttl": 50000,
            "type": "OracleRegisterTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&cursor=600286&limit=1&oracle=ok_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&channel=ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD&limit=2" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2aw4KGSWLq7opXT796a5QZx8Hd7BDaGRSwEcyqzNQMii7MrGrv",
          "block_height": 1208,
          "hash": "th_25ofE3Ah8Fm3PV8oo5Trh5rMMiU4E8uqFfncu9EjJHvubumkij",
          "micro_index": 0,
          "micro_time": 1543584946527,
          "signatures": [
            "sg_2NjzKD4ZKNQiqjAYLVFfVL4ZMCXUhVUEXCmoAZkhAZxsJQmPfzWj3Dq6QnRiXmJDByCPc33qYdwTAaiXDHwpdjFuuxwCT",
            "sg_Wpm8j6ZhRzo6SLnaqWUb24KwFZ7YLws9zHiUKvWrf89cV2RAYGqftXBAzS6Pj7AVWKQLwSjL384yzG7hK4rHB8dn2d67g"
          ],
          "tx": {
            "channel_id": "ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD",
            "channel_reserve": 10,
            "delegate_ids": [],
            "fee": 20000,
            "initiator_amount": 50000,
            "initiator_id": "ak_ozzwBYeatmuN818LjDDDwRSiBSvrqt4WU7WvbGsZGVre72LTS",
            "lock_period": 3,
            "nonce": 1,
            "responder_amount": 50000,
            "responder_id": "ak_26xYuZJnxpjuBqkvXQ4EKb4Ludt8w3rGWREvEwm68qdtJLyLwq",
            "state_hash": "st_MHb9b2dXovoWyhDf12kVJPwXNLCWuSzpwPBvMFbNizRJttaZ",
            "type": "ChannelCreateTx",
            "version": 1
          }
        },
        {
          "block_hash": "mh_joVBtAVakCpGWqesP4S8HpDTs6tUuwq2hjpGHwN4aGP1shfFx",
          "block_height": 14258,
          "hash": "th_meBfq6EWuUXExBRkbi618RVkQ8nFMz7uo26HkxFXwko9NjF9L",
          "micro_index": 0,
          "micro_time": 1545910910104,
          "signatures": [
            "sg_GnbScdeBzkXhj9DR1GQcb2LFxHmuL1eNYrScRCPVp2XKt26BoinsrAbdMBWZimqrY36sF5PzAiA4Vqfx6yfGtRtMGXPuQ",
            "sg_VoH1jw5de6wtpzdDsZnA1ATgqV22Rkq2YN2SsphiwqCbY9nipjm3CcwkbKWhAkrud6MnY9biJHVDAzu5UjMf8c691fEcA"
          ],
          "tx": {
            "amount": 10,
            "channel_id": "ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD",
            "fee": 17240,
            "nonce": 16,
            "round": 5,
            "state_hash": "st_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACr8s/aY",
            "to_id": "ak_ozzwBYeatmuN818LjDDDwRSiBSvrqt4WU7WvbGsZGVre72LTS",
            "type": "ChannelWithdrawTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&channel=ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD&cursor=94617&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&name_transfer.recipient_id=ak_idkx6m3bgRr7WiKXuB8EBYBoRqVsaSc6qo4dsd23HKgj3qiCF&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2aLMAszzEf3ZS2Xkn8JRrzU4ogWBzxiDYYFqmUKz1r3XJ7nvEF",
          "block_height": 262368,
          "hash": "th_ssPMQvMPgRgUdbYJXzwxCBugz9J8fgP37MoVdqiBHR71Cm2nM",
          "micro_index": 80,
          "micro_time": 1590759423839,
          "signatures": [
            "sg_DBJnw22QJ7gcfhMMvYdkDqgf3LstHLivZjVdPSXz2LuUHedhQwfrpEEdwvebcqwxdNsrRv7FnzbG8f7oEex3muv7ZayZ5"
          ],
          "tx": {
            "account_id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
            "fee": 17380000000000,
            "name_id": "nm_2t5eU4gLBmMaw4xn3Xb6LZwoJjB5qh6YxT39jKyCq4dvVh8nwf",
            "nonce": 190,
            "recipient_id": "ak_idkx6m3bgRr7WiKXuB8EBYBoRqVsaSc6qo4dsd23HKgj3qiCF",
            "ttl": 262868,
            "type": "NameTransferTx",
            "version": 1
          },
          "tx_index": 11700056
        }
      ],
      "next": "/v3/transactions?direction=forward&cursor=11734834&limit=1&name_transfer.recipient_id=ak_idkx6m3bgRr7WiKXuB8EBYBoRqVsaSc6qo4dsd23HKgj3qiCF"
    }
    curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?from_id=ak_ozzwBYeatmuN818LjDDDwRSiBSvrqt4WU7WvbGsZGVre72LTS&limit=5" | jq '.data | .[] | [.hash, .tx.type]'
    [
      "th_s1C1VC1nwWR4WB8qqJ7o9VokTTPQkAmKQ4aEfQf2GnVa4GKqw",
      "ChannelForceProgressTx"
    ]
    [
      "th_2donST82cDa4trBqE4d2m7kPoTe56cvQVZ52aSoNG8V4UnV8vX",
      "ChannelSettleTx"
    ]
    [
      "th_2wevgEPtCdRMpPaoHRQjyaApXK9FbErnM3UtqN7KDmbxjEeiAQ",
      "ChannelSlashTx"
    ]
    [
      "th_YcFkm7qTgEe5zFhCB21td6f68u1WTH8qArZZwsNqhJCSzhJ3L",
      "ChannelSnapshotSoloTx"
    ]
    [
      "th_qT9SvwhKZaUeVJLvr4e24gBYCwXaszdMPgRAZismKK2oecFAi",
      "ChannelDepositTx"
    ]
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?account=ak_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR&account=ak_zUQikTiUMNxfKwuAfQVMPkaxdPsXP8uAxnfn6TkZKZCtmRcUD&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_vCizDmxFrwMFCjBFDWfe8husZ4i8d7K2hFKfmQHhau3DkK9Ka",
          "block_height": 68234,
          "hash": "th_2HvqS7RjoWvBFMGr6WsUsXRhDEcfs3DotZXFm5rRNg7TVZUmnu",
          "micro_index": 0,
          "micro_time": 1555651193447,
          "signatures": [
            "sg_Rimi7QJoHfuFTG79iuZ92GTrmzPcjBxRDe4DniXX9SveAQWcZx9D3FMHUhc7fzfSgJ8vcykGrGpdUXtM3gkFM1pMy4AVL"
          ],
          "tx": {
            "amount": 1,
            "fee": 30000000000000,
            "nonce": 19223,
            "payload": "ba_dGVzdJVNWkk=",
            "recipient_id": "ak_zUQikTiUMNxfKwuAfQVMPkaxdPsXP8uAxnfn6TkZKZCtmRcUD",
            "sender_id": "ak_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR",
            "ttl": 70000,
            "type": "SpendTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?account=ak_zUQikTiUMNxfKwuAfQVMPkaxdPsXP8uAxnfn6TkZKZCtmRcUD&cursor=17022424&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&sender_id=ak_26dopN3U2zgfJG4Ao4J4ZvLTf5mqr7WAgLAq6WxjxuSapZhQg5&recipient_id=ak_r7wvMxmhnJ3cMp75D8DUnxNiAvXs8qcdfbJ1gUWfH8Ufrx2A2&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_88NN1Y5rmofQ5SUkQNcuBnLMyQucdrCXXcqBduYjLygDmSuSz",
          "block_height": 172,
          "hash": "th_LnKAy1SDEwQjn9kvVmZ8woCExEX7g29UBvZthWnugKAF2ZBhf",
          "micro_index": 1,
          "micro_time": 1543404316091,
          "signatures": [
            "sg_7wbXjsJLYy3gxGpLsi62s9j7nd4Qm3uppPFsNXLw7WdqZE6b1mPyUqkiMvDTJMD3zQCYy2BNgzpdyLAZJuNmkKKhmFUL3"
          ],
          "tx": {
            "amount": 1000000,
            "fee": 20000,
            "nonce": 10,
            "payload": "ba_SGFucyBkb25hdGVzs/BHFA==",
            "recipient_id": "ak_r7wvMxmhnJ3cMp75D8DUnxNiAvXs8qcdfbJ1gUWfH8Ufrx2A2",
            "sender_id": "ak_26dopN3U2zgfJG4Ao4J4ZvLTf5mqr7WAgLAq6WxjxuSapZhQg5",
            "type": "SpendTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/transactions?direction=forward&cursor=41&limit=1&recipient_id=ak_r7wvMxmhnJ3cMp75D8DUnxNiAvXs8qcdfbJ1gUWfH8Ufrx2A2&sender_id=ak_26dopN3U2zgfJG4Ao4J4ZvLTf5mqr7WAgLAq6WxjxuSapZhQg5",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions?direction=forward&account=ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD&type_group=name" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_JRADbFAfMf4JJApALLc3JuJgmQtRsQ91WHQvyGZzGJiCuLBFV",
          "block_height": 141695,
          "hash": "th_vNPVyhuUTWkdvU9hTC6vRK52Hevt5Lbv3ZjVV67KoghE1Vake",
          "micro_index": 17,
          "micro_time": 1568931464420,
          "signatures": [
            "sg_C81dBwSTehaPDuz23PDAeZZAgTQYeTGcpYXabkTQiQa7YBzvwwK9us7dxSd6FsqZ2wpzmsM72QYwoUJzKtsY75BG8Eu9i"
          ],
          "tx": {
            "account_id": "ak_AiQGnvEgsbLQixVJABpTc9h7hXtP4Lt3sorCa9FbtvYfiBH6a",
            "fee": 17300000000000,
            "name_id": "nm_2fzt9CmGxe1GgKs42xM95h8nvgXqTECCKqjSZQinQUiwBooGid",
            "nonce": 6,
            "recipient_id": "ak_E64bTuWTVj9Hu5EQSgyTGZp27diFKohTQWw3AYnmgVSWCnfnD",
            "type": "NameTransferTx",
            "version": 1
          }
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions/th_zATv7B4RHS45GamShnWgjkvcrQfZUWQkZ8gk1RD4m2uWLJKnq" | jq '.'
    {
      "block_hash": "mh_2kE3N7GCaeAiowu1a7dopJygxQfxvRXYCNy7Pc657arjCa8PPe",
      "block_height": 257058,
      "hash": "th_zATv7B4RHS45GamShnWgjkvcrQfZUWQkZ8gk1RD4m2uWLJKnq",
      "micro_index": 19,
      "micro_time": 1589801584978,
      "signatures": [
        "sg_Z7bbM2a8tDZchtpAkQuMrw5S3cf3yvVizx5qb6hB58KJBBTqhCcpgq2adwNz9SneSQgzD6QQSToiKn3XosS7qybacLpiG"
      ],
      "tx": {
        "amount": 20000,
        "fee": 19300000000000,
        "nonce": 2129052,
        "payload": "ba_MjU3MDU4OmtoXzhVdnp6am9tZG9ZakdMNURic2hhN1RuMnYzYzNXWWNCVlg4cWFQV0JyZjcyVHhSeWQ6bWhfald1dnhrWTZReXBzb25RZVpwM1B2cHNLaG9ZMkp4cHIzOHhhaWR2aWozeVRGaTF4UDoxNTg5ODAxNTkxQa+0cQ==",
        "recipient_id": "ak_zvU8YQLagjcfng7Tg8yCdiZ1rpiWNp1PBn3vtUs44utSvbJVR",
        "sender_id": "ak_zvU8YQLagjcfng7Tg8yCdiZ1rpiWNp1PBn3vtUs44utSvbJVR",
        "ttl": 257068,
        "type": "SpendTx",
        "version": 1
      }
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions/count" | jq '.'
    11921825
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions/count?scope=gen:123-456" | jq '.'
    23
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions/count?id=ak_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR" | jq '.'
    19323
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transactions/count?tx_type=oracle_register" | jq '.'
    286
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/key-blocks?scope=gen:101125-101125" | jq '.'
    {
      "data": [
        {
          "beneficiary" : "ak_2MR38Zf355m6JtP13T3WEcUcSLVLCxjGvjk6zG95S2mfKohcSS",
          "hash" : "kh_2MK98WvTtAMzvNNJSi62iConXWshwDM49pfyQi2uVPXE73vv7p",
          "height" : 101125,
          "info" : "cb_AAAAAfy4hFE=",
          "micro_blocks_count" : 1,
          "miner" : "ak_2HToRDUsCuBqdGsFqCCE19chrRQ7hhYE5Ebd3LETfwnk3gGnzX",
          "nonce" : 9256408633249849368,
          "pow" : [5377241, ..., 514753955],
          "prev_hash" : "kh_tPiapdedaKhT8egWrtLWsvACbEzTbpECdWg9P8dTtK8P8w48s",
          "prev_key_hash" : "kh_tPiapdedaKhT8egWrtLWsvACbEzTbpECdWg9P8dTtK8P8w48s",
          "state_hash" : "bs_2SF46f1xU4uxiKKVmeT9jqFWJenftFzXTVse9GGLwtit78zHQP",
          "target" : 504458445,
          "time" : 1561595666398,
          "transactions_count" : 4,
          "version" : 3
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/key-blocks?scope=gen:100000-100100&limit=3" | jq '.'
    {
      "data": [
        {
          "beneficiary" : "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv",
          "hash" : "kh_foi6pMgz1zi17tYy5eBMQMzCLf7jaAYQTL9WtoJiqR5bk38hg",
          "height" : 100000,
          "info" : "cb_AAAAAfy4hFE=",
          "micro_blocks_count" : 1,
          "miner" : "ak_2K5fAjna26t2U2V6v2LwNBUZpT9puriPdvxifDmGRoqG1a7R3Z",
          "nonce" : 14620604494251230255,
          "pow" : [8664748, ..., 485310990],
          "prev_hash" : "mh_2EFE1CxvXM2dKtu4Jt4yLAbW8gS5MkpDtNmGKHP4bPXDvtubKJ",
          "prev_key_hash" : "kh_B18SQZmResYV5yqxbFUizKPqrtrjky3LESGUvRECDp9N2kNmA",
          "state_hash" : "bs_185cZMdvy6wJXjCZDwGnLJ4TCrU18yxGSVkbtQh4DyCm2yPaV",
          "target" : 504047608,
          "time" : 1561390154570,
          "transactions_count" : 1,
          "version" : 3
        },
        {
          "beneficiary" : "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv",
          "hash" : "kh_2gJqm1zmvpMGLMiViwwiHE2EhvdzWjm6KBVthRouHM71rCnUuN",
          "height" : 100001,
          "info" : "cb_AAAAAfy4hFE=",
          "micro_blocks_count" : 2,
          "miner" : "ak_2AT33FPB7DSvd3XU2nKPh4sUbBjb6jHWtKh6CF2b1eK2y3daA3",
          "nonce" : 8862664339569827477,
          "pow" : [7438320, ..., 519071892],
          "prev_hash" : "mh_zpiiJYsHZZ9ibKSF1fGLcossdgFjHNaN2Yu6cEF9KSNLqQLbS",
          "prev_key_hash" : "kh_foi6pMgz1zi17tYy5eBMQMzCLf7jaAYQTL9WtoJiqR5bk38hg",
          "state_hash" : "bs_Wqv4So3wfCV2eyJMnjfiGsrb1D7nrUk2r6K9ufgnX22J5wVPA",
          "target" : 504063592,
          "time" : 1561390309740,
          "transactions_count" : 2,
          "version" : 3
        },
        {
          "beneficiary" : "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv",
          "hash" : "kh_2BXy8tftXFVj859j4YpkTyf7Ld5AXrvPqUSbYwGoWZpKQ9VNVB",
          "height" : 100002,
          "info" : "cb_AAAAAfy4hFE=",
          "micro_blocks_count" : 1,
          "miner" : "ak_2VJtWGt45q8w9Aj7gYJPz9kZG3EU45xi6YZ4wgXSb25MeYGdfM",
          "nonce" : 5829762670850390403,
          "pow" : [1917903, ..., 530252456],
          "prev_hash" : "mh_NxwB3r43rT4ghZscfuXhHNKNouuVQmU1Lkrf4sgCTPYy3Szdr",
          "prev_key_hash" : "kh_2gJqm1zmvpMGLMiViwwiHE2EhvdzWjm6KBVthRouHM71rCnUuN",
          "state_hash" : "bs_2E75ChNX5EZo42xek6K64i5MZfQNxDUo5M9DwAufFRqQRqx3Z5",
          "target" : 504062474,
          "time" : 1561390340812,
          "transactions_count" : 1,
          "version" : 3
        }
      ],
      "next" : "/v3/key-blocks?cursor=100003&limit=3&scope=gen%3A100000-100100",
      "prev" : null
    }
    $ curl -s https://mainnet.aeternity.io/mdw/v3/key-blocks/kh_2oKCXoTcm7rSxxAHaEcoUe6JV7Xs9Nmk3TNXHSEQcs9NwE8o6W
    {
      "micro_blocks_count": 204,
      "transactions_count": 273,
      "beneficiary": "ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv",
      "hash": "kh_2oKCXoTcm7rSxxAHaEcoUe6JV7Xs9Nmk3TNXHSEQcs9NwE8o6W",
      "height": 653413,
      "info": "cb_AAACjBq0Xcc=",
      "miner": "ak_2XTwJ1uqopnb6swmNCA35AuzgZJ8cqJqT1jtGi1j3pKzrsnXGL",
      "nonce": 11146303448381,
      "pow": [
        470518102,
        470786769,
        472378123,
        477583630,
        477907327,
        488321757,
        491143869,
        493744235,
        505396477,
        518355451,
        531366816
      ],
      "prev_hash": "mh_StyRqEViVt5z4pvFu6LeJXjy3eh9He7w83UUPsp2gfxnHMrqb",
      "prev_key_hash": "kh_2mkrqWnKFBhEdX5B27pmvd1LN6FqQfHm2XzXo2uc5ZGAqkrwRf",
      "state_hash": "bs_2pgQNoRYU32wCv3ESvHg6RYpSgsXX9NjkKJ2TuaZnxW6qqVtsN",
      "target": 520136850,
      "time": 1662676277823,
      "version": 5
    }
    $ curl -s https://mainnet.aeternity.io/mdw/v3/key-blocks/123
    {
      "micro_blocks_count": 0,
      "transactions_count": 0,
      "beneficiary": "ak_TFm6MPeRXz4oiy5rQ9QRsFpaQb27GCc5ZEXCDhCFPYvYWxV5v",
      "hash": "kh_c1F1ZfcqhLMqPNoTzgNKAp3n18kPMCrWvuH9j2Dc2kdiUteRZ",
      "height": 123,
      "info": "cb_Xfbg4g==",
      "miner": "ak_2W4cmcpJQZ4JeBF1kPoe5UsEZCS4gzbCWtoDsVDr7EzF65bmkf",
      "nonce": 2384355247607917600,
      "pow": [
        28236516,
        37891637,
        39568937,
        41751636,
        53905843,
        77440491,
        77746610,
        80023552,
        85642112,
        89247851,
        105135109
      ],
      "prev_hash": "kh_MD6dBz1sk6n4P4HZUjzwfiLHSMxzmFk5ZVjcG5cF7PqBCgT9b",
      "prev_key_hash": "kh_MD6dBz1sk6n4P4HZUjzwfiLHSMxzmFk5ZVjcG5cF7PqBCgT9b",
      "state_hash": "bs_2pAUexcNWE9HFruXUugY28yfUifWDh449JK1dDgdeMix5uk8Q",
      "target": 521613269,
      "time": 1543395219643,
      "version": 1
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/key-blocks?limit=1" | jq '.'
    {
      "data": [
        {
          "micro_blocks_count": 180,
          "transactions_count": 244,
          "beneficiary": "ak_wM8yFU8eSETXU7VSN48HMDmevGoCMiuveQZgkPuRn1nTiRqyv",
          "hash": "kh_2w8M2XGQaEhrf5AQwKyibgskKshCeFNsmGCxjHUDbUMm8BdzaV",
          "height": 652730,
          "info": "cb_AAACjBq0Xcc=",
          "miner": "ak_2fh4U3GaZGV2PFy7x7UDPNZN9F4gi1sryKCP4VtJawjJbQVsGR",
          "nonce": 28361498886552,
          "pow": [
            8004426,
            25304189,
            41033042,
            48739301,
            55650278,
            69208239,
            78837065
          ],
          "prev_hash": "mh_2f4TgYysCB6x1N9KtUNbQDUjcDJkq4hNrCkMcLxutBb6ydsfa1",
          "prev_key_hash": "kh_Bfip7MNDMJGEe1PqCsPggUkuSQCAQFKAmWAM42jezSmUB3Zfm",
          "state_hash": "bs_kyyX1ujxAJm6orwxPghVJK8ZqxKMXuVUp5hUfnpjaJWnRgx3T",
          "target": 520137938,
          "time": 1662549337009,
          "version": 5
        }
      ],
      "next": "/v3/key-blocks?cursor=652729&limit=1",
      "prev": null
    }
    $ curl https://mainnet.aeternity.io/v3/key-blocks/kh_2HvzkfTvRjfwbim8YZ2q2ETKLhuYK125JGpisr1Cc9m2VSa5iC/micro-blocks?limit=1
    {
      "data": [
        {
          "micro_block_index": 39,
          "transactions_count": 0,
          "hash": "mh_HqJKqWdJ1vaPcr82zYNue99GXcKfjpYbmrEcZ7kmUHAzQoeZv",
          "height": 654915,
          "pof_hash": "no_fraud",
          "prev_hash": "mh_G2gtKvDAkoi3HZDe5TmWYzGX2pD2AL2DrFXACTch57QEWi1Bo",
          "prev_key_hash": "kh_2HvzkfTvRjfwbim8YZ2q2ETKLhuYK125JGpisr1Cc9m2VSa5iC",
          "signature": "sg_Eyv2nWKwMbxga4XDHH2oCtnSCWhtD87qUjvFLqKvzt9kq2yVPMkcHSv51kr9fmHQk6TGxBHjRjm74pVZtNuHpZkvybsXX",
          "state_hash": "bs_2WNN8aZ15a7pd68wWDZkTqpGUTPezUV6KTN2ra5m3v1x5vVJGC",
          "time": 1662950429203,
          "txs_hash": "bx_AK5hwnJdG3KAEHEvzs4gwjkRDZP5sw5sbtqgHsgJT2fp1PJka",
          "version": 5
        }
      ],
      "next": "/v3/key-blocks/kh_2HvzkfTvRjfwbim8YZ2q2ETKLhuYK125JGpisr1Cc9m2VSa5iC/micro-blocks?cursor=38&limit=1",
      "prev": null
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/micro-blocks/mh_HqJKqWdJ1vaPcr82zYNue99GXcKfjpYbmrEcZ7kmUHAzQoeZv
    {
      "micro_block_index": 39,
      "transactions_count": 0,
      "hash": "mh_HqJKqWdJ1vaPcr82zYNue99GXcKfjpYbmrEcZ7kmUHAzQoeZv",
      "height": 654915,
      "pof_hash": "no_fraud",
      "prev_hash": "mh_G2gtKvDAkoi3HZDe5TmWYzGX2pD2AL2DrFXACTch57QEWi1Bo",
      "prev_key_hash": "kh_2HvzkfTvRjfwbim8YZ2q2ETKLhuYK125JGpisr1Cc9m2VSa5iC",
      "signature": "sg_Eyv2nWKwMbxga4XDHH2oCtnSCWhtD87qUjvFLqKvzt9kq2yVPMkcHSv51kr9fmHQk6TGxBHjRjm74pVZtNuHpZkvybsXX",
      "state_hash": "bs_2WNN8aZ15a7pd68wWDZkTqpGUTPezUV6KTN2ra5m3v1x5vVJGC",
      "time": 1662950429203,
      "txs_hash": "bx_AK5hwnJdG3KAEHEvzs4gwjkRDZP5sw5sbtqgHsgJT2fp1PJka",
      "version": 5
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/micro-blocks/mh_3TzzPsMhgnJBYAtSJ6c4SdbQppZi64mxP61b1u1E8g3stDQwk/txs?limit=1
    {
      "data": [
        {
          "block_hash": "mh_3TzzPsMhgnJBYAtSJ6c4SdbQppZi64mxP61b1u1E8g3stDQwk",
          "block_height": 14085,
          "hash": "th_2Eo84A8gYkaNnRXkkEe9gPg5jcbKGdPVkZvK9XUSEQhDD6kmqm",
          "micro_index": 59,
          "micro_time": 1545877257605,
          "signatures": [
            "sg_E6tbrssPGL4a1mXyN5EW9d3UwRfYN9pSsBDtDEQVyQqTQjhQVBPKNJV6qyc43M5zY2tLE8VQa8Jb3q1XGYKJYaHM5Q3T4"
          ],
          "tx": {
            "amount": 43734300000000000000,
            "fee": 21000,
            "nonce": 19631,
            "payload": "ba_SGVsbG8sIE1pbmVyISAvWW91cnMgQmVlcG9vbC4vKXcQag==",
            "recipient_id": "ak_2gD9eHc6AaLSgUKne5vVLrsnG4acTCDE7KPetE4PqA8MYvz8gN",
            "sender_id": "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv",
            "type": "SpendTx",
            "version": 1
          }
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?limit=2" | jq '.'
    {
      "data": [
        {
          "active": true,
          "hash": "nm_qock4y2xnYdyy779vayFfu7YUBTwy9bTfoJeH4pM5EpRyJU3A",
          "active_from": 205194,
          "auction_timeout": 14880,
          "expire_height": 349080,
          "ownership": {
            "current": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN",
            "original": "ak_pMwUuWtqDoPxVtyAmWT45JvbCF2pGTmbCMB4U5yQHi37XF9is"
          },
          "pointers": {
            "account_pubkey": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN"
          },
          "revoke": null,
          "auction": null,
          "name": "jieyi.chain"
        },
        {
          "active": true,
          "hash": "nm_8vYbsvsrBow6jpxPHUtMLKG6EfTKqqwfpu425aJuHKafSxyR6",
          "active_from": 253179,
          "auction_timeout": 480,
          "expire_height": 349071,
          "ownership": {
            "current": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN",
            "original": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx"
          },
          "pointers": {
            "account_pubkey": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN"
          },
          "revoke": null,
          "auction": null,
          "name": "helloword.chain"
        }
      ],
      "next": "/v3/names?by=deactivation&cursor=703645-jiangjiajia.chain&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?state=inactive&by=deactivation&direction=forward&limit=2" | jq '.'
    {
      "data": [
        {
          "active": false,
          "hash": "nm_PstDX8VxoTutPJG8YrXkWEwAfBoC5ZmoW1j5RZSNNyXa5oJSB",
          "active_from": 6089,
          "auction_timeout": 0,
          "expire_height": 16090,
          "ownership": {
            "current": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7",
            "original": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7"
          },
          "pointers": {
            "account_pubkey": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7"
          },
          "revoke": null,
          "auction": null,
          "name": "philippsdk.test"
        },
        {
          "active": false,
          "hash": "nm_J9wKEZ1Deo4UAnNo5s5VTRccVCLdZexZBQJgA6YHYy67xDpqy",
          "active_from": 6094,
          "auction_timeout": 0,
          "expire_height": 16094,
          "ownership": {
            "current": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7",
            "original": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7"
          },
          "pointers": {
            "account_pubkey": "ak_c3LfYDjLqdNdWHUCV8NDv1BELhXqfKxhmKfzh4cBMpwj64CD7"
          },
          "revoke": null,
          "auction": null,
          "name": "philippsdk2.test"
        }
      ],
      "next": "/v3/names?state=inactive&cursor=16117-philippsdk1.test&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?state=active&by=name&limit=2" | jq '.'
    {
      "data": [
        {
          "active": true,
          "hash": "nm_23NKMgfB5igtdWHkY5BPMg75PykVrBTBpPAsE6Y1mYV3kZ8Nbd",
          "active_from": 162213,
          "auction_timeout": 0,
          "expire_height": 309542,
          "ownership": {
            "current": "ak_2tACpi3fVoP5kGo7aXw4riDNwifU2UR3AxxKzTs7FiCPi4iBa8",
            "original": "ak_2tACpi3fVoP5kGo7aXw4riDNwifU2UR3AxxKzTs7FiCPi4iBa8"
          },
          "pointers": {
            "account_pubkey": "ak_2tACpi3fVoP5kGo7aXw4riDNwifU2UR3AxxKzTs7FiCPi4iBa8"
          },
          "revoke": null,
          "auction": null,
          "name": "0000000000000.chain"
        },
        {
          "active": true,
          "hash": "nm_2q5bUSTcibKsuRfGnXSFC5JkUSUxiy9UbMuQ2uJn2xiYNZdcbL",
          "active_from": 183423,
          "auction_timeout": 480,
          "expire_height": 336933,
          "ownership": {
            "current": "ak_id5HJww6GzFBuFeVGX1NNM66fuzuyfvnCQgZmRxzdSnW8WRcv",
            "original": "ak_id5HJww6GzFBuFeVGX1NNM66fuzuyfvnCQgZmRxzdSnW8WRcv"
          },
          "pointers": {
            "account_pubkey": "ak_VLkEyJBmvaf6XnqLdknjj7ZMN58G5x1eJhNUkLxPFGmg9JAaJ"
          },
          "revoke": null,
          "auction": null,
          "name": "0123456789.chain"
        }
      ],
      "next": "/v3/names?state=active&cursor=zz.chain&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?owned_by=ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN&by=name" | jq '.'
    {
      "data": [
        {
          "active": false,
          "name": "yedianzhiwang.chain",
          "hash": "nm_2akgyVeSqDeynUVTHnHzengLarQyQqC9sHigsrBKnaCtmd3Ca5",
          "name_fee": 1771100000000000000,
          "revoke": null,
          "expire_height": 364002,
          "auction_timeout": 0,
          "auction": null,
          "ownership": {
            "current": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN",
            "original": "ak_2pqYSBpEkykFy11KFZXxDJaB8KugXBi2JxraqZXpTaXzreYb95"
          },
          "active_from": 163855,
          "approximate_expire_time": 1609161570008,
          "approximate_activation_time": 1572935113556
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?state=active&by=activation&direction=forward&limit=2" | jq '.'
    {
      "data": [
        {
          "active": true,
          "auction": null,
          "hash": "nm_2FvtAFr3gPAQtNutEnjcPDQSqbhxDHBg9j8LE5WESPCJjzFmuU",
          "active_from": 161313,
          "auction_timeout": 0,
          "expire_height": 653635,
          "ownership": {
            "current": "ak_5z1fmzTKR1GA1P7qiLDCC1s3V7AK2RRpNbXqUhfHQbUeg7mmV",
            "original": "ak_5z1fmzTKR1GA1P7qiLDCC1s3V7AK2RRpNbXqUhfHQbUeg7mmV"
          },
          "pointers": {
            "account_pubkey": "ak_2QGAAqDXK7g8zCbck7zm25TGAW1hRuVCET2SRCCFCMSMjrVCrF"
          },
          "revoke": null,
          "name": "batchpayments.chain"
        },
        {
          "active": true,
          "auction": null,
          "hash": "nm_E5JeB8xLS9UR5qN65kDuAhRCHDno5B9pLwoXCm5DEKVpmWrUN",
          "active_from": 161349,
          "auction_timeout": 0,
          "expire_height": 653635,
          "ownership": {
            "current": "ak_5z1fmzTKR1GA1P7qiLDCC1s3V7AK2RRpNbXqUhfHQbUeg7mmV",
            "original": "ak_5z1fmzTKR1GA1P7qiLDCC1s3V7AK2RRpNbXqUhfHQbUeg7mmV"
          },
          "pointers": {
            "account_pubkey": "ak_2QGAAqDXK7g8zCbck7zm25TGAW1hRuVCET2SRCCFCMSMjrVCrF"
          },
          "revoke": null,
          "name": "internetofmoney.chain"
        }
      ],
      "next": "/v3/names?by=activation&cursor=161350-internetofvalue.chain&direction=forward&limit=2&state=active",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names?prefix=aaa&by=name&limit=2" | jq '.'
    {
      "data": [
        {
          "active": false,
          "name": "aaaz.test",
          "hash": "nm_28ZLaroYYUQ1B5MDa7FiKz2F7mSvrtPXSEfavbqXbg2y1ia28j",
          "revoke": null,
          "name_fee": 134626900000000000000,
          "auction_timeout": 0,
          "pointers": {},
          "auction": null,
          "expire_height": 130718,
          "active_from": 80718,
          "approximate_activation_time": 1557907284835,
          "approximate_expire_time": 1566948271337,
          "ownership": {
            "current": "ak_pANDBzM259a9UgZFeiCJyWjXSeRhqrBQ6UCBBeXfbCQyP33Tf",
            "original": "ak_pANDBzM259a9UgZFeiCJyWjXSeRhqrBQ6UCBBeXfbCQyP33Tf"
          }
        },
        {
          "active": false,
          "name": "aaay.test",
          "hash": "nm_2CtkYRVTtqnK6rf9Tc7AyyiHtcTFaustEzRLArAMiWUzXdAhTT",
          "revoke": null,
          "name_fee": 134626900000000000000,
          "auction_timeout": 0,
          "pointers": {},
          "auction": null,
          "expire_height": 130714,
          "active_from": 80714,
          "approximate_activation_time": 1557906623769,
          "approximate_expire_time": 1566948022162,
          "ownership": {
            "current": "ak_pANDBzM259a9UgZFeiCJyWjXSeRhqrBQ6UCBBeXfbCQyP33Tf",
            "original": "ak_pANDBzM259a9UgZFeiCJyWjXSeRhqrBQ6UCBBeXfbCQyP33Tf"
          }
        }
      ],
      "next": "/v3/names?by=name&cursor=aaaq.test&prefix=aaa",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/auctions?limit=2" | jq '.'
    {
      "data": [
        {
          "name": "meta.chain",
          "name_fee": 134626900000000000000,
          "auction_end": 968903,
          "last_bid": {
            "block_hash": "mh_2F3vhNXJ1eXaQiAz6RQHzAUW5dEUTSEvxaBAHDn8ziHjrd9FJK",
            "block_height": 939143,
            "encoded_tx": "tx_+JYLAfhCuECFZmpTCOnm3v0zZ3g2BVIZApsjxGt4Q4MWck+gEw0j09Jq61XEgQWafn3fP2oesqcsy6wYGpGWT6eFW/iE7IoCuE74TCACoQH7BL4bl7Y/NrliWEMKWaxk9besmKUYp6PkFk7ZZeieHYIyZ4ptZXRhLmNoYWluhwUXe6y8hW+JB0xS1EQgCUAAhg8PrOrgAADImXsf",
            "hash": "th_2KpsBbibCN4EwtKNtLLAZzRw3AJ7xMEQw5sfbNZjQKCdP5pc5V",
            "micro_index": 0,
            "micro_time": 1714619449351,
            "signatures": [
              "sg_JTFJFCMh84NB9rJiHgzVcCgXsSt5i6njT4E55vLDRVoeXKuB4ETqzt1BB6TtAUrbGoGMYd4iXM7xuwPXXgVoWCPPZu8SS"
            ],
            "tx": {
              "account_id": "ak_2uYw22W3KGCCduExjzkBDNUxWt3Akdehm66CFAXDKRt9aoUofX",
              "fee": 16560000000000,
              "name": "meta.chain",
              "name_fee": 134626900000000000000,
              "name_id": "nm_2ab7LiFhV5uAzXq6EHmMsPm2cHoKaLdFMnwoTrkVaHSUAAZmx5",
              "name_salt": 1433194830005615,
              "nonce": 12903,
              "ttl": 1148903,
              "type": "NameClaimTx",
              "version": 2
            }
          },
          "approximate_expire_time": 1719979602317,
          "activation_time": 1714619449351
        },
        {
          "name": "tank.chain",
          "name_fee": 134626900000000000000,
          "auction_end": 965088,
          "last_bid": {
            "block_hash": "mh_bV9Kq1tCMpRWgTAWy6C6vvQy5r2RjganqjFhQcPoRZmwNxZtN",
            "block_height": 935328,
            "encoded_tx": "tx_+JQLAfhCuEA+wsY1qqQhRraS487OtyxOqltUkG8KrnrVoMeGj1Db5XRf/cFdyJ3MhMfE5bgoBx57i9zAKC/iMdQsPzzNf3QFuEz4SiACoQFDfNR5+5vHGV9m03tIkBWvRBxUxZg57c17DFoKdfI/bleKdGFuay5jaGFpbocLZSf1Zg0fiQdMUtREIAlAAIYPBly7UAAAdKgDMw==",
            "hash": "th_2fpQo1jm3VwHkn4VcDxFxaMnNLWc2PD8KA35WZwGDDSYKxJDkx",
            "micro_index": 0,
            "micro_time": 1713926446496,
            "signatures": [
              "sg_9DEUyZZfXQDR7t1QbGod9GztGTeFGCiAuNHzqZaXng6kY9Xbn1hNqbFWVugChgQySzLsNfxhcHRrP7qtjPoCAjaJM57pf"
            ],
            "tx": {
              "account_id": "ak_Wit5Lxv9v3QNYiGSTidCM7Ssuagd7cs6fsBnuwZmULLAWBZd2",
              "fee": 16520000000000,
              "name": "tank.chain",
              "name_fee": 134626900000000000000,
              "name_id": "nm_CCgyYJEUuyZtfZrAZvFK8tv2k9a9zhKkByxhwHcrc64mVw7EB",
              "name_salt": 3207447039053087,
              "nonce": 87,
              "ttl": 1145088,
              "type": "NameClaimTx",
              "version": 2
            }
          },
          "approximate_expire_time": 1719292902317,
          "activation_time": 1713926446496
        }
      ],
      "next": "/v3/names/auctions?cursor=548763-svs.chain&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/auctions?by=name&direction=forward&limit=100" | jq '.data [] .name'
    "0.chain"
    "5.chain"
    "6.chain"
    "8.chain"
    "AEStudio.chain"
    "BTC.chain"
    "Facebook.chain"
    "Song.chain"
    "ant.chain"
    "b.chain"
    "d.chain"
    "help.chain"
    "k.chain"
    "l.chain"
    "m.chain"
    "meet.chain"
    "o.chain"
    "s.chain"
    "y.chain"
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/bear.test" | jq '.'
    {
      "active": false,
      "name": "bear.test",
      "hash": "nm_2aGpF2uJp1wDpuHoNDhhSztpoQr43dAjzZ5SyvfD2RSKTVmL6X",
      "name_fee": 134626900000000000000,
      "revoke": null,
      "expire_height": 135638,
      "auction_timeout": 0,
      "auction": null,
      "ownership": {
        "current": "ak_2CXSVZqVaGuZsmcRs3CN6wb2b9GKtf7Arwej7ahbeAQ1S8qkmM",
        "original": "ak_2CXSVZqVaGuZsmcRs3CN6wb2b9GKtf7Arwej7ahbeAQ1S8qkmM"
      },
      "active_from": 85624,
      "approximate_expire_time": 1567835676059,
      "approximate_activation_time": 1558792599799
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/nm_MwcgT7ybkVYnKFV6bPqhwYq2mquekhZ2iDNTunJS2Rpz3Njuj" | jq '.'
    {
      "active": false,
      "name": "wwwbeaconoidcom.chain",
      "hash": "nm_MwcgT7ybkVYnKFV6bPqhwYq2mquekhZ2iDNTunJS2Rpz3Njuj",
      "name_fee": 676500000000000000,
      "revoke": null,
      "expire_height": 329558,
      "auction_timeout": 0,
      "auction": null,
      "ownership": {
      "current": "ak_2HNsyfhFYgByVq8rzn7q4hRbijsa8LP1VN192zZwGm1JRYnB5C",
      "original": "ak_2HNsyfhFYgByVq8rzn7q4hRbijsa8LP1VN192zZwGm1JRYnB5C"
      },
      "active_from": 279555,
      "approximate_expire_time": 1602925509746,
      "approximate_activation_time": 1593861576848
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/help" | jq '.'
    {
      "active": false,
      "name": "yedianzhiwang.chain",
      "hash": "nm_2akgyVeSqDeynUVTHnHzengLarQyQqC9sHigsrBKnaCtmd3Ca5",
      "name_fee": 1771100000000000000,
      "revoke": null,
      "expire_height": 364002,
      "auction_timeout": 0,
      "auction": {
        "name": "yedianzhiwang.chain",
        "name_fee": 134626900000000000000,
        "auction_end": 965088,
        "last_bid": {
          "block_hash": "mh_bV9Kq1tCMpRWgTAWy6C6vvQy5r2RjganqjFhQcPoRZmwNxZtN",
          "block_height": 935328,
          "encoded_tx": "tx_+JQLAfhCuEA+wsY1qqQhRraS487OtyxOqltUkG8KrnrVoMeGj1Db5XRf/cFdyJ3MhMfE5bgoBx57i9zAKC/iMdQsPzzNf3QFuEz4SiACoQFDfNR5+5vHGV9m03tIkBWvRBxUxZg57c17DFoKdfI/bleKdGFuay5jaGFpbocLZSf1Zg0fiQdMUtREIAlAAIYPBly7UAAAdKgDMw==",
          "hash": "th_2fpQo1jm3VwHkn4VcDxFxaMnNLWc2PD8KA35WZwGDDSYKxJDkx",
          "micro_index": 0,
          "micro_time": 1713926446496,
          "signatures": [
          "sg_9DEUyZZfXQDR7t1QbGod9GztGTeFGCiAuNHzqZaXng6kY9Xbn1hNqbFWVugChgQySzLsNfxhcHRrP7qtjPoCAjaJM57pf"
          ],
          "tx": {
            "account_id": "ak_Wit5Lxv9v3QNYiGSTidCM7Ssuagd7cs6fsBnuwZmULLAWBZd2",
            "fee": 16520000000000,
            "name": "tank.chain",
            "name_fee": 134626900000000000000,
            "name_id": "nm_CCgyYJEUuyZtfZrAZvFK8tv2k9a9zhKkByxhwHcrc64mVw7EB",
            "name_salt": 3207447039053087,
            "nonce": 87,
            "ttl": 1145088,
            "type": "NameClaimTx",
            "version": 2
          }
        },
        "approximate_expire_time": 1719295566979,
        "activation_time": 1713926446496
      },
      "ownership": {
        "current": "ak_25BWMx4An9mmQJNPSwJisiENek3bAGadze31Eetj4K4JJC8VQN",
        "original": "ak_2pqYSBpEkykFy11KFZXxDJaB8KugXBi2JxraqZXpTaXzreYb95"
      },
      "active_from": 163855,
      "approximate_expire_time": 1609161570008,
      "approximate_activation_time": 1572935113556
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/auctions/meta.chain" | jq '.'
    {
      "name": "meta.chain",
      "name_fee": 134626900000000000000,
      "auction_end": 968903,
      "last_bid": {
        "block_hash": "mh_2F3vhNXJ1eXaQiAz6RQHzAUW5dEUTSEvxaBAHDn8ziHjrd9FJK",
        "block_height": 939143,
        "encoded_tx": "tx_+JYLAfhCuECFZmpTCOnm3v0zZ3g2BVIZApsjxGt4Q4MWck+gEw0j09Jq61XEgQWafn3fP2oesqcsy6wYGpGWT6eFW/iE7IoCuE74TCACoQH7BL4bl7Y/NrliWEMKWaxk9besmKUYp6PkFk7ZZeieHYIyZ4ptZXRhLmNoYWluhwUXe6y8hW+JB0xS1EQgCUAAhg8PrOrgAADImXsf",
        "hash": "th_2KpsBbibCN4EwtKNtLLAZzRw3AJ7xMEQw5sfbNZjQKCdP5pc5V",
        "micro_index": 0,
        "micro_time": 1714619449351,
        "signatures": [
          "sg_JTFJFCMh84NB9rJiHgzVcCgXsSt5i6njT4E55vLDRVoeXKuB4ETqzt1BB6TtAUrbGoGMYd4iXM7xuwPXXgVoWCPPZu8SS"
        ],
        "tx": {
          "account_id": "ak_2uYw22W3KGCCduExjzkBDNUxWt3Akdehm66CFAXDKRt9aoUofX",
          "fee": 16560000000000,
          "name": "meta.chain",
          "name_fee": 134626900000000000000,
          "name_id": "nm_2ab7LiFhV5uAzXq6EHmMsPm2cHoKaLdFMnwoTrkVaHSUAAZmx5",
          "name_salt": 1433194830005615,
          "nonce": 12903,
          "ttl": 1148903,
          "type": "NameClaimTx",
          "version": 2
        }
      },
      "approximate_expire_time": 1719978527794,
      "activation_time": 1714619449351
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/accounts/ak_2HNsyfhFYgByVq8rzn7q4hRbijsa8LP1VN192zZwGm1JRYnB5C/names/pointees?limit=3" | jq '.'
    {
      "data": [
        {
          "name": "star.chain",
          "key": "account_pubkey",
          "tx": {
            "account_id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
            "client_ttl": 10500,
            "fee": 17860000000000,
            "name_id": "nm_dRChkcZn62toYnPZVjgpi5UsnyMZdHH3zw9ah2JR9ESFga5qK",
            "name_ttl": 50000,
            "nonce": 245,
            "pointers": [
              {
                "id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
                "key": "account_pubkey"
              }
            ],
            "ttl": 272285
          },
          "block_hash": "mh_2ksi3YAh6oYviVooxn93F6vMrYoGhBuX4LgZnBUHszYJSPx5eT",
          "source_tx_type": "NameUpdateTx",
          "source_tx_hash": "th_YfXgjU5LPonGzZRSNedHtzqZLtSLbuorbBV9T2iCPQVcATRNM",
          "block_time": 1592458627198,
          "block_height": 271786
        },
        {
          "name": "store.chain",
          "key": "account_pubkey",
          "tx": {
            "account_id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
            "client_ttl": 10500,
            "fee": 17860000000000,
            "name_id": "nm_2PMNtzqTk38rEMmoVAuFNSJtWQgdtREDWDau497ofQW4XvRydC",
            "name_ttl": 50000,
            "nonce": 244,
            "pointers": [
              {
                "id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
                "key": "account_pubkey"
              }
            ],
            "ttl": 272285
          },
          "block_hash": "mh_jKTG4ThGE2dFyoKDBi2AUgkHrBi8LQEF5NuD2WDuX5jJmpT8n",
          "source_tx_type": "NameUpdateTx",
          "source_tx_hash": "th_2ccvwv8sd4f7UgjCETvmG8wEx5ZSa7wnYzuU3yUyVSJkjhz3Lq",
          "block_time": 1592458574738,
          "block_height": 271785
        },
        {
          "name": "aepps.chain",
          "key": "account_pubkey",
          "tx": {
            "account_id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
            "client_ttl": 10500,
            "fee": 17860000000000,
            "name_id": "nm_zJVQvLaC3DPVKTdrYXvrB8YpQpQFqN6drxUmGbyvTQQWjAcAf",
            "name_ttl": 50000,
            "nonce": 241,
            "pointers": [
              {
                "id": "ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx",
                "key": "account_pubkey"
              }
            ],
            "ttl": 271240
          },
          "block_hash": "mh_SG6qWMrJEtbjfFiUJLeR7KaU5q3GNMMrMCLM1MYEQcafLF3jU",
          "source_tx_type": "NameUpdateTx",
          "source_tx_hash": "th_25nTyhVyLWRwgnkh3VJZnBcNvWpQgEDq1azv3RFyRJXs5eqauV",
          "block_time": 1592269558743,
          "block_height": 270740
        }
      ],
      "next": "/v3/accounts/ak_QyFYYpgJ1vUGk1Lnk8d79WJEVcAtcfuNHqquuP2ADfxsL6yKx/names/pointees?cursor=276059-0-12703951-0-YWNjb3VudF9wdWJrZXk&limit=3",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/vlsl.test/claims" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2Nr1oj3Z3D9sYnEDrNk4SXjboT3otCXQafsNukRcRDg25URKrR",
          "height": 45784,
          "tx": {
            "account_id": "ak_2T42t9vpy56kKfZuX74SHuYGsETi1YegJ1KjBbieBwJswt1QVN",
            "fee": 21000000000000,
            "name": "vlsl.test",
            "name_salt": 123,
            "nonce": 67,
            "ttl": 45882,
            "type": "NameClaimTx",
            "version": 2
          }
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/test.test/transfers" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2wWv1cwnC2purbtZqXiNcZDpX9SAmEUc5YaMKZmSR9p1pEm9rE",
          "height": 42320,
          "tx": {
            "account_id": "ak_24jcHLTZQfsou7NvomRJ1hKEnjyNqbYSq2Az7DmyrAyUHPq8uR",
            "fee": 30000,
            "name_id": "nm_en1mSKcVPb9gY8UGxPfABw3JouEGZ4ZvdfcBWetmn6czUuVG1",
            "nonce": 18550,
            "recipient_id": "ak_2WZoa13VKHCamt2zL9Wid8ovmyvTEUzqBjDNGDNwuqwUQJZG4t",
            "ttl": 42420,
            "type": "NameTransferTx",
            "version": 1
          }
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/names/ssup.test/updates?limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_qZM3VVCHynY1AG4Pgwcdobg42oGAxhY7c1LrUzqvgJSFLLbPU",
          "height": 45706,
          "tx": {
            "account_id": "ak_2CXSVZqVaGuZsmcRs3CN6wb2b9GKtf7Arwej7ahbeAQ1S8qkmM",
            "client_ttl": 36000,
            "fee": 20000000000000,
            "name_id": "nm_2tokSd7X5zeYzAr5icomaVLBYC3TGeCypsPjZALcQcxYZb4YdP",
            "name_ttl": 50000,
            "nonce": 3544,
            "pointers": [
              {
                "id": "ak_M6MNwGLtMQ4j3m8pzQz9uF38nMfjCCVaiQ8fvTAU6DEsCocD5",
                "key": "account_pubkey"
              }
            ],
            "ttl": 60000,
            "type": "NameUpdateTx",
            "version": 1
          }
        }
      ],
      "next": "/v3/names/ssup.test/updates?cursor=45706-20-1132300&limit=1",
      "prev": null
    }
    curl -s "https://mainnet.aeternity.io/mdw/v3/contracts?limit=1" | jq '.'
    {
      "data" : [
        {
          "block_hash" : "mh_2sEDNcQaZwpU4qUZGPX3zV7BruQvzQ4qnYpo4VWaPU6sQfjDqJ",
          "contract" : "ct_D4ZxQD9wXRXYkT7EQd5SiGmySJziEGJSGyDBqH9SwYMsnH4JX",
          "create_tx" : {
            "abi_version" : 3,
            "amount" : 0,
            "call_data" : "cb_KxFE1kQfGwphxkNE",
            "code" : "cb_+GlGA6ANexG+yJOtFvI0ogpw4uOHJDVScNPobxeyUDr10xHM08C4PKH+RNZEHwA3AQc3ABoGggABAz/+iKBvXwA3AQcHFiQAggCWLwIRRNZEHxFpbml0EYigb18RY2FsY4IvAIU3LjEuMAAZ1+t2",
            "deposit" : 0,
            "fee" : 78540000000000,
            "gas" : 76,
            "gas_price" : 1000000000,
            "nonce" : 27,
            "owner_id" : "ak_2oGsfHFUww8cv7Tsc73FJcKWLFmn25Mk1rF68aTxwhwREecrs8",
            "ttl" : 0,
            "vm_version" : 7
          },
          "source_tx_hash" : "th_ZyorKqF8kUac4KFcRcEVeHXsnQ6vfMZei98gekvBwuSdjtEuZ",
          "source_tx_type" : "ContractCreateTx"
        }
      ],
      "next" : "/v3/contracts?cursor=40835756-0&limit=1",
      "prev" : null
    }
    $ curl -s "http://mainnet.aeternity.io/mdw/v3/contracts/ct_D4ZxQD9wXRXYkT7EQd5SiGmySJziEGJSGyDBqH9SwYMsnH4JX" | jq '.'
    {
      "block_hash" : "mh_2sEDNcQaZwpU4qUZGPX3zV7BruQvzQ4qnYpo4VWaPU6sQfjDqJ",
      "contract" : "ct_D4ZxQD9wXRXYkT7EQd5SiGmySJziEGJSGyDBqH9SwYMsnH4JX",
      "create_tx" : {
        "abi_version" : 3,
        "amount" : 0,
        "call_data" : "cb_KxFE1kQfGwphxkNE",
        "code" : "cb_+GlGA6ANexG+yJOtFvI0ogpw4uOHJDVScNPobxeyUDr10xHM08C4PKH+RNZEHwA3AQc3ABoGggABAz/+iKBvXwA3AQcHFiQAggCWLwIRRNZEHxFpbml0EYigb18RY2FsY4IvAIU3LjEuMAAZ1+t2",
        "deposit" : 0,
        "fee" : 78540000000000,
        "gas" : 76,
        "gas_price" : 1000000000,
        "nonce" : 27,
        "owner_id" : "ak_2oGsfHFUww8cv7Tsc73FJcKWLFmn25Mk1rF68aTxwhwREecrs8",
        "ttl" : 0,
        "vm_version" : 7
      },
      "source_tx_hash" : "th_ZyorKqF8kUac4KFcRcEVeHXsnQ6vfMZei98gekvBwuSdjtEuZ",
      "source_tx_type" : "ContractCreateTx"
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?direction=forward&contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&limit=1" | jq '.'
    {
      "data": [
        {
          "args": [
            "32049452134983951870486158652299990269658301415986031571975774292043131948665",
            "10000000000000000"
          ],
          "call_tx_hash": "th_2JLGkWhXbEQxMuEYTxazPurKiwGvo5R6vgqjSBw3R8z9F6b4rv",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "https://github.com/thepiwo",
          "event_hash": "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0====",
          "ext_caller_contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?direction=forward&contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&limit=1"
    }
    iex(aeternity@localhost)3> <<32049452134983951870486158652299990269658301415986031571975774292043131948665 :: 256>>
    <<70, 219, 88, 217, 218, 57, 227, 219, 63, 200, 168, 207, 16, 238, 173, 185,
      185, 214, 3, 207, 227, 124, 221, 54, 36, 147, 13, 144, 171, 6, 142, 121>>
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?limit=1" | jq '.'
    {
      "data": [
        {
          "args": [
            "80808227038564992079558295896388926841596253273977977325246416786468530750284",
            "23245441236723951035912846601319239080044515685575576534240736154129181748855",
            "966628800000000000"
          ],
          "call_tx_hash": "th_2vDNSLGyBdBNPmyfWtfHEAH2PdJh7t39G3a6JtM4ByfYD1LT1V",
          "contract_id": "ct_2MgX2e9mdM3epVpmxLQim7SAMF2xTbid4jtyVi4WiLF3Q8ZTRZ",
          "data": "",
          "event_hash": "48U3JOKTVTI6FVMTK2BLHM8NG72JEBG93VS6MENPSC8E71IM5FNG====",
          "ext_caller_contract_id": "ct_2M4mVQCDVxu6mvUrEue1xMafLsoA1bgsfC3uT95F3r1xysaCvE",
          "log_idx": 2
        }
      ],
      "next": "/v3/contracts/logs?cursor=68PJACHK74O3E91J60QJADHG6OR28HA96P258MAL6KRJAKQ7A0RLEDAL8D65CKIN95C52I23AH7KOKAA8GRJ8HQN9TC5KD2D957KGGIJAT350M2H7KUJQF9460I0&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?scope=gen:200000-210000&limit=1" | jq '.'
    {
      "data": [
        {
          "args": [
            "48550576960427288418928503238185419255781131458428297160617859112449977313818",
            "1000000000000000000"
          ],
          "call_tx_hash": "th_2BjrnHaRHo196AHtpMHV4QUiJqDi6UjfsA5pbPgTGhKpQuB67N",
          "contract_id": "ct_cT9mSpx9989Js39ag45fih2daephb7YsicsvNdUdEB156gT5C",
          "data": "https://github.com/aeternity",
          "event_hash": "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0====",
          "ext_caller_contract_id": "ct_cT9mSpx9989Js39ag45fih2daephb7YsicsvNdUdEB156gT5C",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?cursor=6CS34DHK6KQI8D1G60O38DPP4H2KIDI4AHCLAD9N6L9KEK1NASQLAGQCAP95EIAOA5446L2F9H8KKH1N6H3LEJQOB8Q4QIAF91156LQ6A1C52F9T7KUI8C14&limit=1&scope=gen%3A200000-210000",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?scope=gen:250109&limit=1" | jq '.'
    {
      "data": [
        {
          "args": [
            "113825637927817399496888947973485901133216730124575464244310341957325543404011",
            "100000000000000000"
          ],
          "call_tx_hash": "th_22pciXRFnEieCSMEbcEPEfHdxvJobJt2UoCtXXiQ3pnDn6kvaz",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "https://twitter.com/LeonBlockchain",
          "event_hash": "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0====",
          "ext_caller_contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?cursor=6CS34DHK6KQI8D1G60O38DPP4H2KIDI4AHCLAD9N6L9KEK1NASQLAGQCAP95EIAOA5446L2F9H8KKH1N6H3LEJQOB8Q4QIAF91156LQ6A1C52F9T7KUI8C14&limit=1&scope=gen%3A250109",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&limit=2" | jq '.'
    {
      "data": [
        {
          "args": [
            "87569133758291964643644139664803946495433064832095920406619813370506210782355",
            "120000000000000000"
          ],
          "call_tx_hash": "th_2rQFbvkR2rxvBQLWt4WPUPiSViES8aKDBVDraF4mogdZsVTJSQ",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "https://www.youtube.com/watch?v=iLQzaLr1enE",
          "event_hash": "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0====",
          "ext_caller_contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "log_idx": 0
        },
        {
          "args": [
            "19315768272296812419334917756530784329195878521494173087129733615253420217233",
            "52300000000000000000"
          ],
          "call_tx_hash": "th_JgxLwr7WszXNT5tU1ngc6fJJyxTywcLjWxXy8sqrpX7r7byCQ",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "https://superhero.com/",
          "event_hash": "ATPGPVQP8277UG86U0JDA2CPFKQ1F28A51VAG9F029836CU1IG80====",
          "ext_caller_contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&cursor=70PJICHN6OR28CPG6GR3GDHK6OI5AH2MACRKOM9LB58KKD9L9DD3AMIKA92KGM269LCKAL9NA12K4DA69HCKGCQC88PKIDHN6TCLAKA2915LKK9T7KUJQ91G4G&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?direction=forward&data=aeternity.com&limit=2" | jq '.'
    {
      "data": [
        {
          "args": [
            "69318356919715896655612698359975736845612647472784537635207689589288608801665"
          ],
          "call_tx_hash": "th_29wEBiUVommkJJqtWxczsdTViBSHsCxsQMtyYZb3hju4xW6eFS",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "aeternity.com",
          "event_hash": "K3LIVBOTOG9TTAPTPJH47N5CO4KVF41T5BO7RB1R8UVVOKG17APG====",
          "ext_caller_contract_id": "ct_7wqP18AHzyoqymwGaqQp8G2UpzBCggYiq7CZdJiB71VUsLpR4",
          "log_idx": 0
        },
        {
          "args": [
            "69318356919715896655612698359975736845612647472784537635207689589288608801665"
          ],
          "call_tx_hash": "th_nvrmo5YmrWUW9pr2ohiPWB6FHgok9owi5xbLMpV2pHYvECxTD",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "aeternity.com",
          "event_hash": "K3LIVBOTOG9TTAPTPJH47N5CO4KVF41T5BO7RB1R8UVVOKG17APG====",
          "ext_caller_contract_id": "ct_7wqP18AHzyoqymwGaqQp8G2UpzBCggYiq7CZdJiB71VUsLpR4",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?cursor=70PJICHN6OR28C9K6SQ3IC1L74I5EDQH6OP4IHQ29TAJ6M2C9L8JCJA48P444GIQ99BK6KHK6SP54KA6B124KJAF8P6KQKPM6944MKAL90R3CG9T7KUJQ91G4HGMAT35E9N6IT3P5PHMUR8&data=aeternity.com&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/logs?event=TipReceived&limit=1" | jq '.'
    {
      "data": [
        {
          "args": [
            "87569133758291964643644139664803946495433064832095920406619813370506210782355",
            "120000000000000000"
          ],
          "call_tx_hash": "th_2rQFbvkR2rxvBQLWt4WPUPiSViES8aKDBVDraF4mogdZsVTJSQ",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "data": "https://www.youtube.com/watch?v=iLQzaLr1enE",
          "event_hash": "MVGUQ861EKRNBCGUC35711P9M2HSVQHG5N39CE5CCIUQ7AGK7UU0====",
          "ext_caller_contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "log_idx": 0
        }
      ],
      "next": "/v3/contracts/logs?cursor=70PJICHN6OR28CPG64R3ADHN6CI5EDQH6OP4IHQ29TAJ6M2C9L8JCJA48P444GIQ99BK6KHK6SP54KA6B124KJAF8P6KQKPM6944MKAL90R3CG9T7KUJQ91G4G&event=TipReceived&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/calls?contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_25eLkLkkMDRg5Sau1ezeNteAXxzAnfECqeN318hTFLifozJkpt",
          "call_tx_hash": "th_gTNykxuM2MJ4D2Y7L5EoU7wKprmM6rLmAKe2yaBrjbNudMeSq",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "function": "Call.amount",
          "height": 403795,
          "internal_tx": {
            "amount": 100000000000000,
            "fee": 0,
            "nonce": 0,
            "payload": "ba_Q2FsbC5hbW91bnTau3mT",
            "recipient_id": "ak_7wqP18AHzyoqymwGaqQp8G2UpzBCggYiq7CZdJiB71VUsLpR4",
            "sender_id": "ak_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
            "type": "SpendTx",
            "version": 1
          },
          "local_idx": 5,
          "micro_index": 9
        }
      ],
      "next": "/v3/contracts/calls?contract_id=ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z&cursor=6CO3ACPK6GRJI91J4GS36E9I6SR3C9144GMJ2C1G&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/calls?direction=forward&function=Oracle&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2XAPbotBm5qgkWn165g3J7eRsfV9r5tEwSEqS3rggR6b9fRbW",
          "call_tx_hash": "th_4q3cLesnXqSSH3HmecGMSUuZZNKsue8rGMACtCRmFpZtpAXPH",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "function": "Oracle.query",
          "height": 219107,
          "internal_tx": {
            "fee": 0,
            "nonce": 0,
            "oracle_id": "ok_2ChQprgcW1od3URuRWnRtm1sBLGgoGZCDBwkyXD1U7UYtKUYys",
            "query": "ak_y87WkN4C4QevzjTuEYHg6XLqiWx3rjfYDFLBmZiqiro5mkRag;https://github.com/thepiwo",
            "query_fee": 20000000000000,
            "query_ttl": {
              "type": "delta",
              "value": 20
            },
            "response_ttl": {
              "type": "delta",
              "value": 20
            },
            "sender_id": "ak_23bfFKQ1vuLeMxyJuCrMHiaGg5wc7bAobKNuDadf8tVZUisKWs",
            "type": "OracleQueryTx",
            "version": 1
          },
          "local_idx": 0,
          "micro_index": 0
        }
      ],
      "next": "/v3/contracts/calls?cursor=70Q30D1N70OI8C945KOJ0C144H53AMI78DCJ6JADALC4GGPL9H34UIHKA4I2QC9G60&direction=forward&function=Oracle&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/contracts/calls?recipient_id=ak_23bfFKQ1vuLeMxyJuCrMHiaGg5wc7bAobKNuDadf8tVZUisKWs&limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2Mp1FfJyEaQUYbBKywWb6kWGm1KoTEyc4SZgt7oA7orz9BpSLD",
          "call_tx_hash": "th_XnXh22b9XsXGPEE9ZJwm4E9FuMhv47Z2ogQo6Lgt4npEwVF9W",
          "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
          "function": "Call.amount",
          "height": 224666,
          "internal_tx": {
            "amount": 80000000000000,
            "fee": 0,
            "nonce": 0,
            "payload": "ba_Q2FsbC5hbW91bnTau3mT",
            "recipient_id": "ak_23bfFKQ1vuLeMxyJuCrMHiaGg5wc7bAobKNuDadf8tVZUisKWs",
            "sender_id": "ak_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
            "type": "SpendTx",
            "version": 1
          },
          "local_idx": 4,
          "micro_index": 11
        }
      ],
      "next": "/v3/contracts/calls?cursor=70S34C1K68S28D145KOJ0C14A93KQGHK9D3K4I258H546JQC99A5IL25AHCL6GPN9T4KIMIB6D2KSKI88P4LKL2M6923AJA16T65ILPJ698I891I&limit=1&recipient_id=ak_23bfFKQ1vuLeMxyJuCrMHiaGg5wc7bAobKNuDadf8tVZUisKWs",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transfers?scope=gen:50002-70000&limit=3" | jq '.'
    {
      "data": [
        {
          "kind": "reward_block",
          "account_id": "ak_542o93BKHiANzqNaFj6UurrJuDuxU61zCGr9LJCwtTUg34kWt",
          "height": 50002,
          "amount": 218400000000000,
          "ref_tx_type": null,
          "ref_tx_hash": null,
          "ref_block_hash": null
        },
        {
          "kind": "reward_block",
          "account_id": "ak_nv5B93FPzRHrGNmMdTDfGdd5xGZvep3MVSpJqzcQmMp59bBCv",
          "height": 50002,
          "amount": 407000327600000000000,
          "ref_tx_type": null,
          "ref_tx_hash": null,
          "ref_block_hash": null
        },
        {
          "kind": "fee_lock_name",
          "account_id": "ak_7myFYvagcqh8AtWEuHL4zKDGfJj5bmacNZS8RoUh5qmam1a3J",
          "height": 50002,
          "amount": 3,
          "ref_tx_type": "mh_2C2KBh8e82yR1TrwrbarNmoNrL1KQG3i29ykooKSTMa7kFJtjF",
          "ref_tx_hash": "th_zUk7eWXjqyUK49WU3ZkLinrRRhMHPRSG22CSb4NbqZjmn7xdm",
          "ref_block_hash": "NameClaimTx"
        }
      ],
      "next": "/v3/transfers?cursor=6KO30C1I5GOJAC9M60S32B1G4HJ6APAVDHNM6QQVDPGMQP948DB54L2FAH356HIN6T84CGHK6GQ4UJ2O6P94ODAM9P248DI69553ECQN899J6KQ4A1CJ6DHN8D7L0GHNA58I8C9L64R30E1H4GO0&limit=3&scope=gen%3A50002-70000",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transfers?direction=forward&kind=reward_dev&limit=2" | jq '.'
    {
      "data": [
        {
          "kind": "reward_dev",
          "account_id": "ak_2KAcA2Pp1nrR8Wkt3FtCkReGzAi8vJ9Snxa4PcmrthVx8AhPe8",
          "height": 90981,
          "amount": 37496010998100000000,
          "ref_tx_type": null,
          "ref_tx_hash": null,
          "ref_block_hash": null
        },
        {
          "kind": "reward_dev",
          "account_id": "ak_2KAcA2Pp1nrR8Wkt3FtCkReGzAi8vJ9Snxa4PcmrthVx8AhPe8",
          "height": 90982,
          "amount": 37496003679840000000,
          "ref_tx_type": null,
          "ref_tx_hash": null,
          "ref_block_hash": null
        }
      ],
      "next": "/v3/transfers?cursor=74O3IE1J5GO2OC94E9INEOBICHFM8PBM4HB58MAP85B4OLAE88PLIDQI9H542L219T158DI9A9658HI96DD4EJ25A4R3CHIF99BJCD1L8D2LKD2EAT2K291G4GOG&direction=forward&kind=reward_dev&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/transfers?account=ak_7myFYvagcqh8AtWEuHL4zKDGfJj5bmacNZS8RoUh5qmam1a3J&limit=1" | jq '.'
    {
      "data": [
        {
          "kind": "fee_lock_name",
          "account_id": "ak_7myFYvagcqh8AtWEuHL4zKDGfJj5bmacNZS8RoUh5qmam1a3J",
          "height": 51366,
          "amount": 3,
          "ref_tx_type": "mh_2BMVuVLTbt5rsYn8k1gjmKcSQyPwhCEtydtdSVh6TFZYZt99Z7",
          "ref_tx_hash": "th_25CKbSP17N454zjtWdZBmJC4HSyk7USFJfQieyLufXwTKMcwna",
          "ref_block_hash": "NameClaimTx"
        }
      ],
      "next": "/v3/transfers?account=ak_7myFYvagcqh8AtWEuHL4zKDGfJj5bmacNZS8RoUh5qmam1a3J&cursor=6KOJ4CHH5GOJCDHG70P3GB1G4HJ6APAVDHNM6QQVDPGMQP9488QL4HHJA57K6CIPACR5EIA79T6KKJ9I6L648HQI6LD48LQ4B93KQDPIAD1KIHAIALCK4HPLAL8J8DAKA10I8C9M6OO3GCHO4GO0&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles?direction=forward&limit=1" | jq '.'
    {
      "data": [
        {
          "active": false,
          "active_from": 4608,
          "expire_height": 5851,
          "format": {
            "query": "the query spec",
            "response": "the response spec"
          },
          "oracle": "ok_2TASQ4QZv584D2ZP7cZxT6sk1L1UyqbWumnWM4g1azGi1qqcR5",
          "query_fee": 20000,
          "register": {
            "block_hash": "mh_uQMxaJ6ajKnMsW2M3QqgH1FchXGNbZriRceVggoTnUEGdgSHq",
            "block_height": 4608,
            "hash": "th_tboa3XizqaAW3FUx4SxzT2xmuXDYRarQqjZiZ384u4oVDn1EN",
            "micro_index": 0,
            "micro_time": 1544185806672,
            "signatures": [
              "sg_A7MGMsQxY9VTCxvBnuStmNsDSADf9H7t57c79hWotFC69e1xpcV78QXJfKoMFSgn1s7RErNksFyKcrihwYifCELnEQFQ3"
            ],
            "tx": {
              "abi_version": 0,
              "account_id": "ak_2TASQ4QZv584D2ZP7cZxT6sk1L1UyqbWumnWM4g1azGi1qqcR5",
              "fee": 20000,
              "nonce": 1,
              "oracle_id": "ok_2TASQ4QZv584D2ZP7cZxT6sk1L1UyqbWumnWM4g1azGi1qqcR5",
              "oracle_ttl": {
                "type": "delta",
                "value": 1234
              },
              "query_fee": 20000,
              "query_format": "the query spec",
              "response_format": "the response spec",
              "type": "OracleRegisterTx",
              "version": 1
            }
          }
        }
      ],
      "next": "/v3/oracles?cursor=6894-ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM&direction=forward&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles?state=inactive&limit=1" | jq '.'
    {
      "data": [
        {
          "active": false,
          "active_from": 307850,
          "expire_height": 308350,
          "format": {
            "query": "string",
            "response": "string"
          },
          "oracle": "ok_sezvMRsriPfWdphKmv293hEiyeyUYSoqkWqW7AcAuW9jdkCnT",
          "query_fee": 20000000000000,
          "register": {
            "block_hash": "mh_uQMxaJ6ajKnMsW2M3QqgH1FchXGNbZriRceVggoTnUEGdgSHq",
            "block_height": 4608,
            "hash": "th_tboa3XizqaAW3FUx4SxzT2xmuXDYRarQqjZiZ384u4oVDn1EN",
            "micro_index": 0,
            "micro_time": 1544185806672,
            "signatures": [
              "sg_A7MGMsQxY9VTCxvBnuStmNsDSADf9H7t57c79hWotFC69e1xpcV78QXJfKoMFSgn1s7RErNksFyKcrihwYifCELnEQFQ3"
            ],
            "tx": {
              "abi_version": 0,
              "account_id": "ak_2TASQ4QZv584D2ZP7cZxT6sk1L1UyqbWumnWM4g1azGi1qqcR5",
              "fee": 20000,
              "nonce": 1,
              "oracle_id": "ok_2TASQ4QZv584D2ZP7cZxT6sk1L1UyqbWumnWM4g1azGi1qqcR5",
              "oracle_ttl": {
                "type": "delta",
                "value": 1234
              },
              "query_fee": 20000,
              "query_format": "the query spec",
              "response_format": "the response spec",
              "type": "OracleRegisterTx",
              "version": 1
            }
          }
        }
      ],
      "next": "/v3/oracles?state=inactive&cursor=507223-ok_26QSujxMBhg67YhbgvjQvsFfGdBrK9ddG4rENEGUq2EdsyfMTC&direction=backward&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles?state=active&limit=1" | jq '.'
    {
      "data": [
        {
          "active": true,
          "active_from": 289005,
          "expire_height": 10289005,
          "extends": [],
          "format": {
            "query": "query",
            "response": "response"
          },
          "oracle": "ok_qJZPXvWPC7G9kFVEqNjj9NAmwMsQcpRu6E3SSCvCQuwfqpMtN",
          "query_fee": 0,
          "register": {
            "block_hash": "mh_2f1gyBmtMMb8Sd3kbSu95cADRMwsYE8171KXP4W8wa2osRp4tZ",
            "block_height": 289005,
            "hash": "th_K5aPLdEN4H6QduiFtqdkv61gUCvaQpDjX3z9pHKNopD8F65LJ",
            "micro_index": 20,
            "micro_time": 1595571086808,
            "signatures": [
              "sg_CW3T2W6Ryi2kcDcSTeuwvL8xGhKYUDnGHygBCPLrF2aqfWA1RiybKqRRafrctK4c9vvL9DS9kCYzWkWSmD8mN9g6yhQPG"
            ],
            "tx": {
              "abi_version": 0,
              "account_id": "ak_qJZPXvWPC7G9kFVEqNjj9NAmwMsQcpRu6E3SSCvCQuwfqpMtN",
              "fee": 1842945000000000,
              "nonce": 1,
              "oracle_id": "ok_qJZPXvWPC7G9kFVEqNjj9NAmwMsQcpRu6E3SSCvCQuwfqpMtN",
              "oracle_ttl": {
                "type": "delta",
                "value": 10000000
              },
              "query_fee": 0,
              "query_format": "query",
              "response_format": "response",
              "ttl": 289505,
              "type": "OracleRegisterTx",
              "version": 1
            },
            "tx_index": 13749762
          }
        }
      ],
      "next": "/v3/oracles?state=active&cursor=1289003-ok_f9vDQvr1cFAQAesYA16vjvBX9TFeWUB4Gb7WJkwfYSkL1CpDx&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles/ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM" | jq '.'
    {
      "active": false,
      "active_from": 4660,
      "expire_height": 6894,
      "approximate_expire_time": 1544587118827,
      "register_time": 1544194831238,
      "register_tx_hash": "th_2SLFNYk5s5u5tRD4Bqx6pSc1mysZMsCr3szbx55nKgVBQSiZv2",
      "format": {
        "query": "string",
        "response": "string"
      },
      "oracle": "ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
      "query_fee": 20000,
      "register": 11023
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles/ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM/queries" | jq '.'
    {
      "data": [
        {
          "response": {
            "height": 4662,
            "block_hash": "mh_N2Lg6sLvnHP3eGNp4NB15CiUP3N4TbG5jTjY69HaECs33Z5MS",
            "query_id": "oq_fKwkWDh1Ze4iWGaMBjGCu69LKNkzYwndrcnPwLatVDdWe3MF9",
            "block_time": 1544195139953,
            "source_tx_hash": "th_8Se3Gxt1SYUL7jBAxB33KXDSmp4nh282JqF16CVUmb7wBCvoy",
            "source_tx_type": "OracleRespondTx",
            "fee": 20000,
            "nonce": 198,
            "oracle_id": "ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
            "response": "T3JhY2xlcyBpbiBBZXRlcm5pdHkgYXJlIHdvcmtpbmcu",
            "response_ttl": {
              "type": "delta",
              "value": 1000
            },
            "ttl": 0
          },
          "height": 4662,
          "block_hash": "mh_vMjtRSPkkkZFhdWcB7Qs2eCWx7deLShL3sW8ANmjijTS5Kmrt",
          "query_id": "oq_fKwkWDh1Ze4iWGaMBjGCu69LKNkzYwndrcnPwLatVDdWe3MF9",
          "block_time": 1544195030464,
          "source_tx_hash": "th_VNYE1rRfjPD66hjgGUBzaqwdGm4PPmzULZAcqnLcWMvrSWehz",
          "source_tx_type": "OracleQueryTx",
          "fee": 20000,
          "nonce": 197,
          "oracle_id": "ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
          "query": "QXJlIG9yYWNsZXMgaW4gYWV0ZXJuaXR5IHdvcmtpbmc/",
          "query_fee": 20000,
          "query_ttl": {
            "type": "delta",
            "value": 1000
          },
          "response_ttl": {
            "type": "delta",
            "value": 1000
          },
          "sender_id": "ak_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
          "ttl": 0
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/oracles/ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM/responses?limit=1" | jq '.'
    {
      "data": [
        {
          "height": 4662,
          "block_hash": "mh_N2Lg6sLvnHP3eGNp4NB15CiUP3N4TbG5jTjY69HaECs33Z5MS",
          "query": {
            "height": 4662,
            "block_hash": "mh_vMjtRSPkkkZFhdWcB7Qs2eCWx7deLShL3sW8ANmjijTS5Kmrt",
            "query_id": "oq_fKwkWDh1Ze4iWGaMBjGCu69LKNkzYwndrcnPwLatVDdWe3MF9",
            "block_time": 1544195030464,
            "source_tx_hash": "th_VNYE1rRfjPD66hjgGUBzaqwdGm4PPmzULZAcqnLcWMvrSWehz",
            "source_tx_type": "OracleQueryTx",
            "fee": 20000,
            "nonce": 197,
            "oracle_id": "ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
            "query": "QXJlIG9yYWNsZXMgaW4gYWV0ZXJuaXR5IHdvcmtpbmc/",
            "query_fee": 20000,
            "query_ttl": {
              "type": "delta",
              "value": 1000
            },
            "response_ttl": {
              "type": "delta",
              "value": 1000
            },
            "sender_id": "ak_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
            "ttl": 0
          },
          "query_id": "oq_fKwkWDh1Ze4iWGaMBjGCu69LKNkzYwndrcnPwLatVDdWe3MF9",
          "block_time": 1544195139953,
          "source_tx_hash": "th_8Se3Gxt1SYUL7jBAxB33KXDSmp4nh282JqF16CVUmb7wBCvoy",
          "source_tx_type": "OracleRespondTx",
          "fee": 20000,
          "nonce": 198,
          "oracle_id": "ok_R7cQfVN15F5ek1wBSYaMRjW2XbMRKx7VDQQmbtwxspjZQvmPM",
          "response": "T3JhY2xlcyBpbiBBZXRlcm5pdHkgYXJlIHdvcmtpbmcu",
          "response_ttl": {
            "type": "delta",
            "value": 1000
          },
          "ttl": 0
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/channels?direction=forward&limit=1" | jq '.'
    {
      "data": [
        {
          "active": true,
          "amount": 100090,
          "channel": "ch_22usvXSjYaDPdhecyhub7tZnYpHeCEZdscEEyhb2M4rHb58RyD",
          "initiator": "ak_ozzwBYeatmuN818LjDDDwRSiBSvrqt4WU7WvbGsZGVre72LTS",
          "last_updated_height": 14258,
          "last_updated_tx_hash": "th_2Ph5XF3VBUNstN5kkVic56NY55xq8vckM3h2TQ5sRVSLGq1kvE",
          "last_updated_tx_type": "ChannelDepositTx",
          "responder": "ak_26xYuZJnxpjuBqkvXQ4EKb4Ludt8w3rGWREvEwm68qdtJLyLwq",
          "state_hash": "st_AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACy1gTH9",
          "updates_count": 3,
          "channel_reserve": 10,
          "delegate_ids": [],
          "initiator_amount": 50000,
          "lock_period": 3,
          "locked_until": 0,
          "responder_amount": 50000,
          "round": 6,
          "solo_round": 0
        }
      ],
      "next": "/v3/channels?cursor=9155-ch_2tceSwiqxgBcPirX3VYgW3sXgQdJeHjrNWHhLWyfZL7pT4gZF4&direction=forward&limit=1",
      "prev": null
    }
    $ curl -s "https://testnet.aeternity.io/mdw/v3/channels/ch_2ZBf9AJ3wr25YzdZb1sQrDALEQ1ZDKwwUhtVXoZiNKbheuesqs?block_hash=mh_245PQCb1gWrJRxUjAmEAv5qSXLQGnksCgHyw9PTHRNGA6PfeD" | jq '.'
    {
      "active": true,
      "amount": 1e+19,
      "channel": "ch_2ZBf9AJ3wr25YzdZb1sQrDALEQ1ZDKwwUhtVXoZiNKbheuesqs",
      "initiator": "ak_VQbiKWLmFXzamGXeTahL9efE8jMprjM9ZpG2BXyWYmPy3ck9Q",
      "last_updated_height": 104024,
      "last_updated_tx_hash": "th_2SQMPNd8jdY5nm8YFpitUti8z9qqBfPuzdodQU9FFzpuMxuLYw",
      "last_updated_tx_type": "ChannelDepositTx",
      "responder": "ak_27c4YpfUuW4s9T6RBNpASNuDRiXSWQ93uZ5WxaUXfx1Lqibv33",
      "state_hash": "st_7oYjZ20LNQTH1ICHzQvgmgAKcYgqFP5hiv8ATvu+5y6a4j9h",
      "updates_count": 3,
      "channel_reserve": 1e+18,
      "delegate_ids": [],
      "initiator_amount": 2e+18,
      "lock_period": 10,
      "locked_until": 0,
      "responder_amount": 2e+18,
      "round": 8,
      "solo_round": 0
    }
    $ curl -s "https://testnet.aeternity.io/mdw/v3/channels/ch_2ZBf9AJ3wr25YzdZb1sQrDALEQ1ZDKwwUhtVXoZiNKbheuesqs/updates?limit=1" | jq '.'
    {
      "data": [
        {
          "block_hash": "mh_2QuuJR9TC7Pnq2o8myDgEQWnRxbCtYwenLLGrk1Xr1VmjF5ozt",
          "source_tx_hash": "th_2YHpkkn9ojgKF8amcJiaLCPR46JZg9He6T73MRHdM21Nj2QSWn",
          "source_tx_type": "ChannelCreateTx",
          "tx" => {
            "channel": "ch_2ZBf9AJ3wr25YzdZb1sQrDALEQ1ZDKwwUhtVXoZiNKbheuesqs",
            "tx_type": "ChannelCreateTx",
            "channel_reserve": 1,
            "delegate_ids": [],
            "fee": 17500000000000,
            "initiator_amount": 20000000000000,
            "initiator_id": "ak_vx8HkCzRHrqpCAyQ7TFBtfTqBimkcTFcJC1amez5vtCzdu2oN",
            "lock_period": 1,
            "nonce": 7,
            "responder_amount": 1,
            "responder_id": "ak_2dxvgsogiBDWXvZSzTghv5MoXLfkFGiEynDC5Cn8k2M2s325Ki",
            "state_hash": "st_fav83CO2VqFQTOayQE3Z3Xhj1NTbFHNcve7KWjemmES0s7tK",
            "ttl": 0
          }
        }
      ],
      "next": "/v3/channels/ch_2ZBf9AJ3wr25YzdZb1sQrDALEQ1ZDKwwUhtVXoZiNKbheuesqs/updates?cursor=9155-0&limit=1",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/aex9?by=symbol" | jq '.'
    {
      "data": [
        {
        "decimals": 18,
        "name": "yy",
        "extensions": [],
        "symbol": "yy",
        "contract_id": "ct_ukZe6BBpuSWxT8hxd87z11vdgRnwKnedEWqJ7SyQucbX1C1pc",
        "contract_tx_hash": "th_236RbbgokHipFbG5Eu9yZSSgzrBQhkRrkFdhXM7ipsmorbkqgy",
        "event_supply": 1e+26,
        "holders": 1,
        "initial_supply": 1e+26
        },
        {
        "decimals": 18,
        "name": "xx",
        "extensions": [],
        "symbol": "xx",
        "contract_id": "ct_vJWj5Z9KPBSE52ZvbZ9cffRhEEX6K6DjRwAZcZ9bArDmrZDuS",
        "contract_tx_hash": "th_2B6DM7SLqRkcTRBejLR4fohBpa4k3nR164uUja3k8SKKYvbwdJ",
        "event_supply": 2e+25,
        "holders": 4,
        "initial_supply": 2e+25
        }
      ],
      "next": "/v3/aex9?by=symbol&cursor=g2gDdwRhZXg5bQAAAAN4b2ttAAAAIHUgUMyJxcMnebj7f5xFL1tWPOn3pfdez%2FvPSy04W1ws",
      "prev": null
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/aex9/ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9
    {
      "decimals": 18,
      "name": "🚀",
      "extensions": [
        "allowances",
        "mintable",
        "burnable",
        "swappable"
      ],
      "symbol": "🚀",
      "contract_id": "ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9",
      "contract_tx_hash": "th_rbFNrRDpn6finytCEmHAExtBnRxt14yckvuCWRmXxsRpypHxt",
      "event_supply": 99000000000000000000,
      "holders": 2,
      "initial_supply": 99000000000000000000
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/aex9/ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9/balances
    {
      "data": [
        {
          "height": 359828,
          "amount": 24000000000000000000,
          "contract_id": "ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9",
          "block_hash": "mh_22uNd2u5ogsFCua2kU3fSag758fTcwJ4kKJwvHpRVedeKwFRHc",
          "account_id": "ak_2KnhztVzfKMBUogdSsCACKVotb6uxjqDLLcLsTk8MdW3266YTL",
          "last_tx_hash": "th_2d2Qnx632buohPC6jmu9jwm5m4vbbegcAiwwZevoJJLeru2MVZ",
          "last_log_idx": 0
        },
        {
          "height": 359828,
          "amount": 75000000000000000000,
          "contract_id": "ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9",
          "block_hash": "mh_22uNd2u5ogsFCua2kU3fSag758fTcwJ4kKJwvHpRVedeKwFRHc",
          "account_id": "ak_YCwfWaW5ER6cRsG9Jg4KMyVU59bQkt45WvcnJJctQojCqBeG2",
          "last_tx_hash": "th_2d2Qnx632buohPC6jmu9jwm5m4vbbegcAiwwZevoJJLeru2MVZ",
          "last_log_idx": 0
        }
      ],
      "next": null,
      "prev": null
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/aex9/ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9/balances/ak_2KnhztVzfKMBUogdSsCACKVotb6uxjqDLLcLsTk8MdW3266YTL
    {
      "contract": "ct_TEt8raHSNKZWHNN8TaCvV2VKDuSGPcxAZhNJcq62M8Gwp6zM9",
      "account": "ak_2KnhztVzfKMBUogdSsCACKVotb6uxjqDLLcLsTk8MdW3266YTL",
      "amount": 24000000000000000000
    }
    $ TODO
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141?direction=forward&limit=1' | jq '.'
    {
      "data": [
        {
          "base_url": null,
          "contract_id": "ct_2KsfvrPHwdZb9CkwvgCkzg4o4k7cH7oyfQq4CNPNCHEZ4RTCf",
          "contract_txi": 30958504,
          "extensions": [
            "mintable"
          ],
          "metadata_type": "map",
          "name": "Apes stepping into the Metaverse",
          "nft_owners": 1,
          "nfts_amount": 8,
          "symbol": "ASITM"
        }
      ],
      "next": "/v3/aex141?cursor=g2gDZAAGYWV4MTQxbQAAACBBcGVzIHN0ZXBwaW5nIGludG8gdGhlIE1ldGF2ZXJzZW0AAAAgD29qcQzT%2FM%2BHEg1uw31I%2BYRUpktYP%2FZ09Dapkl2szkA%3D&direction=forward&limit=1",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8' | jq .
    {
      "base_url": null,
      "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
      "contract_txi": 30958726,
      "extensions": [
        "mintable"
      ],
      "metadata_type": "map",
      "name": "Apes stepping into the Metaverse",
      "nft_owners": 1,
      "nfts_amount": 8,
      "symbol": "ASITM"
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8/tokens?direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "owner_id": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "token_id": 1
        },
        {
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "owner_id": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "token_id": 2
        }
      ],
      "next": "/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8/tokens?cursor=g2gCbQAAACD5nNNdNGQ3YrwVYeXgdeB%2FFd1jOgwZs1p74F2dVz6zC2ED&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8/tokens/2' | jq .
    {
      "contract_id" : "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
      "metadata" : {
        "map" : {
          "description" : "Heaven or metaverse? We don't care!",
          "immutable_attributes" : "[object Object]",
          "media_type" : "IMAGE",
          "media_url" : "ipfs://Qmef7Xrh1YTgQqXbr86o3TrFoya9ZLk1RVdXMga1JjEjnm",
          "mutable_attributes" : "[object Object]",
          "name" : "The path to heaven"
        }
      },
      "owner" : "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
      "token_id" : 2
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_2oq4kSd4j1VkkbupueXLdHwYEJdY8Ntzvp1FFkMB1gYyXkYPcV/templates?direction=forward&limit=2' | jq .
    
    {
      "data": [
        {
          "contract_id": "ct_2oq4kSd4j1VkkbupueXLdHwYEJdY8Ntzvp1FFkMB1gYyXkYPcV",
          "edition": null,
          "log_idx": 0,
          "template_id": 1,
          "tx_hash": "th_KsfMGhkVf2n5RLY5qh1Bo8HppudiQREq7LMKAYuauLSuYKg4s"
        },
        {
          "contract_id": "ct_2oq4kSd4j1VkkbupueXLdHwYEJdY8Ntzvp1FFkMB1gYyXkYPcV",
          "edition": null,
          "log_idx": 0,
          "template_id": 2,
          "tx_hash": "th_Vrk8UGyUpgnvVPK3TknudxPx3Jd3mSCUPnfqcuKbjWZSZivjQ"
        }
      ],
      "next": "/v3/aex141/ct_2oq4kSd4j1VkkbupueXLdHwYEJdY8Ntzvp1FFkMB1gYyXkYPcV/templates?cursor=g2gCbQAAACDuBsFrXLJEIAr8CpUxUAJxriYxXg%2BRMhW900GbowEFwWED&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_ouWFCU2Qg6v7dgFpjRc3jAfcaRhb9iByPRBDjXSJoA8fRrQ4j/templates/8/tokens?direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "log_idx": 0,
          "owner_id": "ak_8Ujt76QfpT1DyYsNZKGPGtMZ2C2MFf7CcnpQvJWNsX6szZkYN",
          "token_id": 29,
          "tx_hash": "th_ZzPmumNtkYCfrGpVGtQP6em9hgkWQqstddB5ynagrJJa7ua9c"
        },
        {
          "log_idx": 0,
          "owner_id": "ak_8Ujt76QfpT1DyYsNZKGPGtMZ2C2MFf7CcnpQvJWNsX6szZkYN",
          "token_id": 30,
          "tx_hash": "th_2UAUi3oYgcYsJ8EGvxR4vurygt7qhYq7tVRNx4g2sZ3quVpym7"
        }
      ],
      "next": "/v3/aex141/ct_ouWFCU2Qg6v7dgFpjRc3jAfcaRhb9iByPRBDjXSJoA8fRrQ4j/templates/8/tokens?cursor=g2gDbQAAACBqgQyEWHrcaKnZMsVhZvJdUfhMZjSF4KpvuLx%2FpHpCcmEIYR8%3D&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/accounts/ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW/tokens?direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "contract_id": "ct_2KsfvrPHwdZb9CkwvgCkzg4o4k7cH7oyfQq4CNPNCHEZ4RTCf",
          "owner_id": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "token_id": 1
        },
        {
          "contract_id": "ct_2KsfvrPHwdZb9CkwvgCkzg4o4k7cH7oyfQq4CNPNCHEZ4RTCf",
          "owner_id": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "token_id": 2
        }
      ],
      "next": "/v3/accounts/ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW/aex141/tokens?cursor=g2gDbQAAACA1VnHPFWKr80aBDnG3tjrWGYMqQpxUJK6dhDlBrJXgEG0AAAAgAwJumVbCVqhk2XF8UnTR8fiNve0Gh9zLEEoZoC55qRdhAw%3D%3D&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8/transfers?direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "block_height": 651434,
          "call_txi": 30958727,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 5,
          "micro_time": 1661491608237,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 1,
          "tx_hash": "th_2d5iaRa2DkgJb6ABSt5ea6TcM1FVB2EW6dx7FRU9XMWi1J4n9e"
        },
        {
          "block_height": 651434,
          "call_txi": 30958729,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 6,
          "micro_time": 1661491611260,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 2,
          "tx_hash": "th_BPiUgq2aqm7rTmhb68DW2vEhReWda3mioxeFBjPfxGtLnkAtg"
        }
      ],
      "next": "/v3/aex141/ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8/transfers?cursor=g2gGYgHYZIZtAAAAIPmc0100ZDdivBVh5eB14H8V3WM6DBmzWnvgXZ1XPrMLYgHYZIttAAAAIDVWcc8VYqvzRoEOcbe2OtYZgypCnFQkrp2EOUGsleAQYQNhAA%3D%3D&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/transfers?from=ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8&direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "block_height": 651434,
          "call_txi": 30958727,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 5,
          "micro_time": 1661491608237,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 1,
          "tx_hash": "th_2d5iaRa2DkgJb6ABSt5ea6TcM1FVB2EW6dx7FRU9XMWi1J4n9e"
        },
        {
          "block_height": 651434,
          "call_txi": 30958729,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 6,
          "micro_time": 1661491611260,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 2,
          "tx_hash": "th_BPiUgq2aqm7rTmhb68DW2vEhReWda3mioxeFBjPfxGtLnkAtg"
        }
      ],
      "next": "/v3/aex141/transfers?from=ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8&cursor=g2gGYgHYZIZtAAAAIPmc0100ZDdivBVh5eB14H8V3WM6DBmzWnvgXZ1XPrMLYgHYZIttAAAAIDVWcc8VYqvzRoEOcbe2OtYZgypCnFQkrp2EOUGsleAQYQNhAA%3D%3D&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s 'https://testnet.aeternity.io/mdw/v3/aex141/transfers?to=ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW&contract_id=ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8&direction=forward&limit=2' | jq .
    {
      "data": [
        {
          "block_height": 651434,
          "call_txi": 30958727,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 5,
          "micro_time": 1661491608237,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 1,
          "tx_hash": "th_2d5iaRa2DkgJb6ABSt5ea6TcM1FVB2EW6dx7FRU9XMWi1J4n9e"
        },
        {
          "block_height": 651434,
          "call_txi": 30958729,
          "contract_id": "ct_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "log_idx": 0,
          "micro_index": 6,
          "micro_time": 1661491611260,
          "recipient": "ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW",
          "sender": "ak_2tw26RwgNADrpuCnrQWKPBH87bPxuRbLR1KLccS9ZJTUMMj4z8",
          "token_id": 2,
          "tx_hash": "th_BPiUgq2aqm7rTmhb68DW2vEhReWda3mioxeFBjPfxGtLnkAtg"
        }
      ],
      "next": "/v3/aex141/transfers?to=ak_QVSUoGrJ31CVxWpvgvwQ7PUPFgnvWQouUgsDBVoGjuT7hjQYW&cursor=g2gGYgHYZIZtAAAAIDVWcc8VYqvzRoEOcbe2OtYZgypCnFQkrp2EOUGsleAQYgHYZIttAAAAIPmc0100ZDdivBVh5eB14H8V3WM6DBmzWnvgXZ1XPrMLYQNhAA%3D%3D&direction=forward&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/delta?limit=1" | jq '.'
    {
      "data": [
        {
          "auctions_started": 0,
          "block_reward": 0,
          "burned_in_auctions": 0,
          "channels_closed": 0,
          "channels_opened": 0,
          "contracts_created": 0,
          "dev_reward": 0,
          "height": 1,
          "last_tx_hash": "th_2FHxDzpQMRTiRfpYRV3eCcsheHr1sjf9waxk7z6JDTVcgqZRXR",
          "locked_in_auctions": 0,
          "locked_in_channels": 0,
          "names_activated": 0,
          "names_expired": 0,
          "names_revoked": 0,
          "oracles_expired": 0,
          "oracles_registered": 0
        }
      ],
      "next": "/v3/stats/delta?limit=1&cursor=419208"
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/total?scope=gen:421454-0&limit=1" | jq '.'
    {
      "data": [
        {
          "active_auctions": 0,
          "active_names": 0,
          "active_oracles": 0,
          "burned_in_auctions": 0,
          "contracts": 0,
          "height": 421454,
          "inactive_names": 0,
          "inactive_oracles": 0,
          "last_tx_hash": "th_2FHxDzpQMRTiRfpYRV3eCcsheHr1sjf9waxk7z6JDTVcgqZRXR",
          "locked_in_auctions": 0,
          "locked_in_channels": 0,
          "open_channels": 0,
          "sum_block_reward": 0,
          "sum_dev_reward": 0,
          "total_token_supply": 8.945137682239798e+25
        }
      ],
      "next": "/v3/stats/total?scope=gen:421454-0&limit=1&cursor=42152"
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/miners?limit=1" | jq '.'
    {
      "data": [
        {
          "miner": "ak_2wkBCLxwjfcT3DHoisV7tGVQK8uni8XQwWZ6RUKD9DDwYSz8XN",
          "total_reward": 76626041292504000000
        }
      ],
      "next": "/v3/stats/miners?cursor=ak_2wk52gAYRWAMi7gWP7A1oMvHEP9kpmp471VJFpvVzWMHnRc47a",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/blocks?limit=2" | jq '.'
    {
      "data": [
        {
          "count": 38150,
          "end_date": "2023-07-22",
          "start_date": "2023-07-21"
        },
        {
          "count": 117685,
          "end_date": "2023-07-21",
          "start_date": "2023-07-20"
        }
      ],
      "next": "/v3/stats/blocks?cursor=19557&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/names?limit=2" | jq '.'
    {
      "data": [
        {
          "count": 38150,
          "end_date": "2023-07-22",
          "start_date": "2023-07-21"
        },
        {
          "count": 117685,
          "end_date": "2023-07-21",
          "start_date": "2023-07-20"
        }
      ],
      "next": "/v3/stats/names?cursor=19557&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats/transactions?limit=2" | jq '.'
    {
      "data": [
        {
          "count": 38150,
          "end_date": "2023-07-22",
          "start_date": "2023-07-21"
        },
        {
          "count": 117685,
          "end_date": "2023-07-21",
          "start_date": "2023-07-20"
        }
      ],
      "next": "/v3/stats/transactions?cursor=19557&limit=2",
      "prev": null
    }
    $ curl -s "https://mainnet.aeternity.io/mdw/v3/stats" | jq '.'
    {
      "miners_count": 228,
      "fees_trend": -0.86,
      "last_24hs_average_transaction_fees": 25816293013087.883,
      "last_24hs_transactions": 9606,
      "max_transactions_per_second": 147.26,
      "max_transactions_per_second_block_hash": "kh_27UooKSFP8qYaymFiUvhrMfAsCUeTon48s52gfdmF8iruoi6cS",
      "transactions_trend": -0.12
    }
    $ curl https://mainnet.aeternity.io/mdw/v3/accounts/ak_2nVdbZTBVTbAet8j2hQhLmfNm1N2WKoAGyL7abTAHF1wGMPjzx/activities
    {
      "data": [
        {
          "height": 85694,
          "type": "NameUpdateTxEvent",
          "payload": {
            "block_hash": "mh_2tL4tRRnH6WLzzYca7T7vQUbdUCRZEeq58S5giwAtnbkjjb3Vj",
            "block_height": 85694,
            "hash": "th_2pvhiLSonrEsmJiUf9Q3E3Lkt9ki5MpHGJ9qQsCVt8ACNWpVVc",
            "micro_index": 30,
            "micro_time": 1558804725247,
            "signatures": [
              "sg_P7UFr4iySfJpidyitDqVTF86uhnuYjQVJ46c96jC4nYZys5mBDQVbsV4CLxYpCqKU55SySmkcSg3Xg4dcYk4aFJGm3VjF"
            ],
            "tx": {
              "account_id": "ak_2nVdbZTBVTbAet8j2hQhLmfNm1N2WKoAGyL7abTAHF1wGMPjzx",
              "client_ttl": 84600,
              "fee": 30000000000000,
              "name": "umpz.test",
              "name_id": "nm_t13Kcjan1mRu2sFjdMgeeASSSL8QoxmVhTrFCmji1j1DZ4jhb",
              "name_ttl": 50000,
              "nonce": 151,
              "pointers": [
                {
                  "id": "ak_2nVdbZTBVTbAet8j2hQhLmfNm1N2WKoAGyL7abTAHF1wGMPjzx",
                  "key": "account_pubkey"
                }
              ],
              "type": "NameUpdateTx",
              "version": 1
            }
          }
        },
        {
          "payload": {
            "block_hash": "mh_2iWGwtQYYueZ8wLGTBjQ79jYfLnQKNgVcHc1GWuPqMG46UPnHY",
            "block_height": 502033,
            "hash": "th_29qxc2oEajHPVoGNS6LBe2TbKk2kyECXXR4KtbGHMhfpwdoNzD",
            "micro_index": 0,
            "micro_time": 1634367215608,
            "signatures": [
              "sg_DXk5jcdoCgGVHJUqjL2Mnu3tPxFD2mGrPga5TgVH97DZC1oq7aDZKEHgrpBqf24A4v2oBFX3zHQzXC1wj9X4ZqdzsqJqj"
            ],
            "tx": {
              "amount": 20000,
              "fee": 19320000000000,
              "nonce": 5967045,
              "payload": "ba_NTAyMDMxOmtoXzJraWtpTms0cnJnV2lNZlBLSmszU2FCdnM5TVVqdHZtNEpLeTdoVnA3Z2k5eW1uaXF1Om1oX01TZ2dxenJINlpXOW9xbmM3eXZDR1dBdGlGRGpaWGFrQWZSVndmeWtteGdWdEd3aVY6MTYzNDM2NzIxMCoV6Eo=",
              "recipient_id": "ak_2QkttUgEyPixKzqXkJ4LX7ugbRjwCDWPBT4p4M2r8brjxUxUYd",
              "sender_id": "ak_2QkttUgEyPixKzqXkJ4LX7ugbRjwCDWPBT4p4M2r8brjxUxUYd",
              "ttl": 502041,
              "type": "SpendTx",
              "version": 1
            }
          },
          "type": "SpendTxEvent",
          "height": 502033
        },
        {
          "height": 659373,
          "payload": {
            "block_hash": "mh_MXVb7wmE1tqeA2xSPhTTksLy7DE5PvR8nsu5haC2fTGpgxxhR",
            "call_tx_hash": "th_Ugtejdn7SkJHXkC3VSdCm2SnXGgPxHgUphBneMqgR3gniZzDN",
            "contract_id": "ct_2AfnEfCSZCTEkxL5Yoi4Yfq6fF7YapHRaFKDJK3THMXMBspp5z",
            "contract_tx_hash": "th_6memqAr5S3UQp1pc4FWXT8xUotfdrdUFgBd8VPmjM2ZRuojTF",
            "function": "Oracle.query",
            "height": 659373,
            "internal_tx": {
              "fee": 0,
              "nonce": 0,
              "oracle_id": "ok_AFbLSrppnBFgbKPo4GykK5XEwdq15oXgosgcdL7ud6Vo2YPsH",
              "query": "YWtfcjNxRWNzWWd5Z2JjYVoxZlhQRFB0YThnZU5FUkV0OHZZaVVKNWtxQnNRNDhXVmp4NztodHRwczovL20ud2VpYm8uY24vNzc1NDY0Njg4Ny80ODE2MjEwNDI2ODYxMjg5",
              "query_fee": 20000000000000,
              "query_id": "oq_pcJy4ufijeP56LwCaJ47GcRNvJvW5nEUedR4BNeMzSobXXqMx",
              "query_ttl": {
                "type": "delta",
                "value": 20
              },
              "response_ttl": {
                "type": "delta",
                "value": 20
              },
              "sender_id": "ak_7wqP18AHzyoqymwGaqQp8G2UpzBCggYiq7CZdJiB71VUsLpR4",
              "type": "OracleQueryTx",
              "version": 1
            },
            "local_idx": 3,
            "micro_index": 0
          },
          "type": "InternalContractCallEvent"
        },
        {
          "height": 653289,
          "payload": {
            "from": "ak_11111111111111111111111111111111273Yts",
            "log_index": 0,
            "to": "ak_uTWegpfN6UjA4yz8X4ZVRi9xKEYeXHJDRZcRryTsRHAFoBpLa",
            "tx_hash": "th_2FciwUNyT7WRGee35KnNMhuoLFSCyiquVLFP3kATjwrFJh4Cfh",
            "value": 1
          },
          "type": "Aex141TransferEvent"
        }
      ],
      "next": "/v3/accounts/ak_2nVdbZTBVTbAet8j2hQhLmfNm1N2WKoAGyL7abTAHF1wGMPjzx/activities?cursor=84328-2002003-0",
      "prev": null
    }
    {
      "op": <subscription operation>,
      "payload": "<message payload>",
    }
    wscat -c wss://mainnet.aeternity.io/mdw/websocket
    
    connected (press CTRL+C to quit)
    > {"op":"Subscribe", "payload": "KeyBlocks"}
    < ["KeyBlocks"]
    > {"op":"Ping"}
    < {"subscriptions":["KeyBlocks"],"payload":"Pong"}
    > {"op":"Subscribe", "payload": "MicroBlocks"}
    < ["KeyBlocks","MicroBlocks"]
    > {"op":"Unsubscribe", "payload": "MicroBlocks"}
    < ["KeyBlocks"]
    > {"op":"Subscribe", "payload": "Transactions"}
    < ["KeyBlocks","Transactions"]
    > {"op":"Unsubscribe", "payload": "Transactions"}
    < ["KeyBlocks"]
    > {"op":"Subscribe", "payload": "Object", "target":"ak_KHfXhF2J6VBt3sUgFygdbpEkWi6AKBkr9jNKUCHbpwwagzHUs"}
    < ["KeyBlocks","ak_KHfXhF2J6VBt3sUgFygdbpEkWi6AKBkr9jNKUCHbpwwagzHUs"]
    < {"subscription":"KeyBlocks","payload":{"version":4,"time":1588935852368,"target":505727522,"state_hash":"bs_6PKt6GXM9Nu3As4XYr3kjmMiuJoTzkHUPDAwm21GBtjbpfWyL","prev_key_hash":"kh_2Dtcpq9ZdB7AJK1aeEwQtoSncDhFejSdzgTTwuNyscFzJrnsnJ","prev_hash":"mh_2H9cAZHHbyMzPwd4vjQHZpxXsrggG54VCryh6k1BTk511At8Bs","pow":[895666,52781556,66367943,73040389,83465124,91957344,137512183,139025150,145635838,147496688,174889700,196453040,223464154,236816295,249867489,251365348,253234990,284153380,309504789,316268731,337440038,348735058,352371122,367534696,378716232,396258628,400918205,407082251,424187867,427465210,430070369,430312387,432729464,438115994,440444207,442136189,473766117,478006149,482575574,489211700,498083855,518253098],"nonce":567855076671752,"miner":"ak_2Go59eRMNcdiq5uUvVAKjSRoxtREtJe6QvNdcAAPh9GiE5ekQi","info":"cb_AAACHMKhM24=","height":252274,"hash":"kh_FProa64FL423f3xok2fKTfbsuEP2QtdUM4idN7GidQ279zgZ1","beneficiary":"ak_2kHmiJN1RzQL6zXZVuoTuFaVLTCeH3BKyDMZKmixCV3QSWs3dd"}}
    < {"subscription":"Object","payload":{"tx":{"version":1,"type":"SpendTx","ttl":252284,"sender_id":"ak_KHfXhF2J6VBt3sUgFygdbpEkWi6AKBkr9jNKUCHbpwwagzHUs","recipient_id":"ak_KHfXhF2J6VBt3sUgFygdbpEkWi6AKBkr9jNKUCHbpwwagzHUs","payload":"ba_MjUyMjc0OmtoX0ZQcm9hNjRGTDQyM2YzeG9rMmZLVGZic3VFUDJRdGRVTTRpZE43R2lkUTI3OXpnWjE6bWhfMmJTcFlDRVRzZ3hMZDd3eEx2Rkw5Wlp5V1ZqaEtNQXF6aGc3eVB6ZUNraThySFVTbzI6MTU4ODkzNTkwMjSozR4=","nonce":2044360,"fee":19320000000000,"amount":20000},"signatures":["sg_Kdh2uaoaiDEHoehDZsRHk7LvqUm5kPqyKR3RD71utjkkh5DTqoJeNWqYv4gRePL9FyBcU7oeL8nsT39zQg4ydCmiKUuhN"],"hash":"th_rGmoP9FCJMQMJKmwDE8gCk7i63vX33St3UiqGQsRGG1twHD7R","block_height":252274,"block_hash":"mh_2gYb8Pv1yLpdsPjxkzq8g9zzBVy42ZLDRvWH6aKYXhb8QjxdvU"}}
    {
      "payload": "<sync info payload>",
      "source": "node" | "mdw",
      "subscription": "KeyBlocks" | "MicroBlocks" | "Transactions" | "Object"
    }
    elixir --sname aeternity@localhost -S mix test
    elixir --sname aeternity@localhost -S mix test.integration

    Changelog

    All notable changes to this project will be documented in this file. See standard-version for commit guidelines.

    14.1.0 (2025-04-29)

    Features

    • account: add sync versions of AccountMnemonicFactory methods ()

    • account: detect MetaMask over EIP-6963 ()

    • account: experimental support of Ledger app v1.0.0 ()

    • account: init AccountMnemonicFactory by seed ()

    • account: add unsafeSign, deprecate sign ()

    • add ensureEncoded, isEncoded; deprecate isAddressValid ()

    • add hashMessage, deprecate messageToHash ()

    • add verifyMessageSignature, deprecate verifyMessage ()

    • add verifySignature, deprecate verify ()

    • aens: add getAuctionState to Name ()

    • aens: add id getter to Name ()

    • aens: add isName, deprecate isNameValid ()

    • aens: allow to pass salt between Name while claiming ()

    • node: add Hyperchain endpoints ()

    • node: ignore consensus protocol version if ignoreVersion set ()

    • node: warn if incompatible version when ignoreVersion set ()

    • oracle: add getQueries to OracleBase ()

    • contract: show function name along its hash if missed in bytecode ()

    Bug Fixes

    • account: implicitly connect to Aeternity snap, clean up flow ()

    • aens: computeAuctionEndBlock returns value according to Ceres ()

    • aens: handle highestBid as BigInt in auction details ()

    (2024-10-20)

    ⚠ BREAKING CHANGES

    Please check out the and a to convert to convert secret keys.

    • CommonJS bundles have cjs extension instead js

    • aepp: AeSdkWallet requires onAskToSelectNetwork constructor option

    • tx-builder: ChannelClientReconnectTx removed

    Features

    • account: add ensureReady method to AccountLedgerFactory ()

    • account: add AccountMetamaskFactory ()

    • account: add AccountMnemonicFactory ()

    Bug Fixes

    • account: improve Account:publicKey type ()

    • aens: validate minus chars in name as node does ()

    • aepp: don't require subscription to request addresses ()

    • channel: channelId

    Commits with breaking changes

    • account: make signTypedData, signDelegation abstract ()

    • account: remove generateKeyPair ()

    • account: remove generateKeyPairFromSecret (

    (2024-07-17)

    Bug Fixes

    • account: improve Account:publicKey type ()

    • aens: validate minus chars in name as node does ()

    • aepp: don't require subscription to request addresses ()

    • channel: channelId

    (2024-04-22)

    Bug Fixes

    • contract: detect if ACI doesn't match called contract ()

    • ttl validation error in dev mode by reducing polling intervals ()

    (2024-04-19)

    Bug Fixes

    • node: mark as compatible with 7.0.0 ()

    (2024-04-08)

    ⚠ Ceres and aehopsia@8 compatibility not stable, since they are not officially released yet

    Features

    • accept multiple encodings in isAddressValid, add TS asserts ()

    • add getContext method to AeSdk ()

    • aens: support update with raw pointers ()

    Bug Fixes

    • aens: make extendTtl argument optional ()

    • aens: reduce default client ttl to one hour ()

    • chain: poll till ttl if defined to ensure tx can't be mined ()

    (2023-09-20)

    Bug Fixes

    • use proper vm version in Ceres ()

    • aepp,wallet: connect to web-extension if opened over file:/// ()

    • aepp: use complete type of WalletInfo object ()

    • contract: don't mark contract as deployed if tx failed ()

    (2023-07-28)

    Bug Fixes

    • use Number instead of unary plus for BigInt ()

    (2023-07-28)

    Features

    • account: add methods to generate delegation signatures ()

    • aepp,wallet: support delegation signatures ()

    Bug Fixes

    • account: add implementation of signTypedData in AccountBase ()

    • wallet: don't ask to confirm unsubscription ()

    • wallet: don't require to be subscribed to request addresses ()

    (2023-07-07)

    Features

    • account: support signing typed data ()

    • aens: add ensureName helper to check names ()

    • aens: support unicode names claim ()

    Bug Fixes

    • onAccount option in AeSdkMethods ()

    • aens: more accurate name check in isNameValid ()

    • aepp: call onDetected always with newWallet ()

    (2023-04-24)

    Bug Fixes

    • contract: return type of call/deploy on chain ()

    • export of prefixedAmount helper ()

    (2023-04-06)

    ⚠ BREAKING CHANGES

    Please check out , and release notes for the .

    • aepp: All wallet provided nodes have the same name Specified in name option of connectToWallet.

    • aepp: Select option removed from connectToWallet If you are using connectNode then the current node would always be the same as wallet provides.

    Features

    • aepp: call onNetworkChange after connection ()

    • export Encoded type ()

    Bug Fixes

    • aepp: use the same name for all nodes provided by wallet ()

    • chain: reduce /2 number of blocks to wait before throwing timeout ()

    • contract: add missed sourceCodePath cases ()

    (2023-03-01)

    ⚠ BREAKING CHANGES

    Wallet

    • onSign, onMessageSign callbacks were removed on the wallet side

    Contract

    • ACI format used the same as returned by aesophia_cli

    • createAensDelegationSignature, createOracleDelegationSignature replaced with createDelegationSignature

    • params argument in $deploy and $call

    Transaction builder

    • StateTrees fields decoded as objects mapping key to decoded entry instead of internals

    • The content of Tag.*Mtree entries decoded and moved to payload field

    • TX_SCHEMA, TxParamsCommon, TxSchema, TxTypeSchemas not exported anymore

    • AeSdk.buildTx accepts tag

    Compiler

    • Methods of CompilerHttp moved to api property

    • Compiler export renamed to CompilerHttp

    • removed compilerUrl, setCompilerUrl

    Account

    • createGeneralizedAccount accepts sourceCode in options

    • createMetaTx removed

    • AccountRpc constructor accepts arguments one by one

    Node

    • url property of Node removed

    Oracle

    • QUERY_FEE is not exported anymore

    • Oracles created without queryFee by default

    • AeSdk:extendOracleTtl, AeSdk:respondToQuery doesn't accept oracleId

    • onQuery callback of pollForQueries

    Chain

    • send inlined into sendTransaction

    AENS

    • height removed from the output of aensPreclaim

    Channel

    • Channel:state returns unpacked entries

    • All channel events emitted in snakeCase

    • Channel:poi returns unpacked TreesPoi

    Other

    • onAccount doesn't accept keypair

    • bigNumberToByteArray removed

    • str2buf function removed

    Features

    • account: accept async function in authData of AccountGeneralized ()

    • account: override fee, gasPrice of GaMetaTx in authData ()

    • chain:

    Bug Fixes

    • aepp: don't require connection to wallet to make a static call ()

    • channel: increase pong timeout 3 times (to 15 seconds) ()

    • channel: return type of state ()

    (2023-01-13)

    (2022-12-08)

    (2022-08-24)

    Bug Fixes

    • deps: update calldata to 1.3.0 ()

    (2022-08-09)

    Bug Fixes

    • deps: depend on specific version of @azure/core-client to fix ()

    (2022-07-28)

    Bug Fixes

    • export and implementation of calculateMinFee ()

    (2022-07-28)

    Features

    • export Encoding enum ()

    Bug Fixes

    • ability to use sdk without nodes ()

    • aepp,wallet: avoid invalid message errors using third-party tools ()

    • AeSdkBase: don't mutate the options argument ()

    • awaitHeight: allow to wait for arbitrary number of blocks ()

    (2022-06-17)

    ⚠ BREAKING CHANGES

    General

    • Universal, RpcAepp, RpcWallet stamps replaced with AeSdk, AeSdkAepp, AeSdkWallet classes

    • all combined exports are inlined (require('@aeternity/aepp-sdk').generateKeyPair())

    Node and Compiler

    • Node, Compiler (previously ContractCompilerHttp) are classes instead of a stamps

    • Node, Compiler doesn't check version on the first request instead of init

    • getNetworkId

    Transaction builder

    • removed methods to generate a transaction of specific type

    • removed ability to generate transaction on the node side

    • nonce, ttl, gas decoded and accepted as numbers instead of strings

    AENS

    • computeBidFee accepts startFee, increment as options

    • NAME_BID_TIMEOUTS not exposed anymore

    • computeAuctionEndBlock accepts and returns height as number

    Oracle

    • extendOracleTtl accepts oracle ttl in oracleTtlType and oracleTtlValue fields

    • decode method of getQueryObject removed

    Contract

    • createAensDelegationSignature accepts contractId, name, options

    • createOracleDelegationSignature accepts contractId, queryId as a property of options

    Chain

    • removed balance, tx, getTxInfo methods

    Other

    • getAccountNonce removed

    • AeSdk doesn't accept array of accounts

    • destroyInstance method removed

    Aepp Wallet communication

    • BrowserRuntimeConnection, BrowserWindowMessageConnection are classes

    • ContentScriptBridge, WalletDetector rewrited to plain functions (connectionProxy, walletDetector)

    • RpcClient: removed origin property

    Aepp

    • connectToWallet accepts wallet connection as the first argument

    • disconnectWallet runs in sync and sendDisconnect arg removed

    • sendConnectRequest removed

    Wallet

    • BrowserRuntimeConnection requires port parameter

    • requires id, type in params

    • getBrowserAPI helper removed

    Features

    • aepp: support external accounts in onAccount ()

    • ga: implement buildAuthTxHash function ()

    • NodeInvocationError: store tx-encoded transaction ()

    Bug Fixes

    • aepp: use networkId in rpc tx signing ()

    • importing in mjs ()

    • messageToHash: support messages longer than 252 chars ()

    • wallet: revert to returning complete tx data instead of just hash in rpc wallet signing ()

    Refactoring with breaking changes

    • generate compiler api in TypeScript using autorest ()

    • generate node api in TypeScript ()

    • compiler: init in sync, check version on making request ()

    • aci: accept onAccount as AccountBase ()

    (2022-04-07)

    Bug Fixes

    • contract: do not check payable if contract call is init ()

    • importing in mjs ()

    • oracle: do not include address for oracle respond signature ()

    (2022-03-18)

    Request batching: SDK now supports

    Custom error types: Introduced

    Naming convention: Instances of the SDK in the examples and tests are now called as aeSdk.

    ⚠ BREAKING CHANGES

    • return empty array instead of throwing UnsignedTxError

    • rpc: remove forceValidation flag

    • hd-wallet: expect that bip39 used externally

    • hd-wallet: remove default export

    Features

    • aci: use dry-run to estimate gas and get rich errors ()

    • calculate default polling intervals depending on node settings ()

    • chain: combine multiple dry-run requests at one ()

    • contract events: ability to resolve multiple definitions of event ()

    Bug Fixes

    • aens helpers: improve naming, add additional validations ()

    • babel: compatibility with create-react-app ()

    • babel: depend on buffer package in es build ()

    • babel: don't rewrite import of rlp package for @vue/[email protected] (

    (2021-12-07)

    ⚠ BREAKING CHANGES

    • crypto: remove unused asymmetric encode/decode functions

    • aens: don't limit pointer keys

    • specify browserlist to better choice of features to transpile

    • aci: don't require source code

    Features

    • aci: don't require source code ()

    • aens: don't limit pointer keys ()

    • aens: enable commitmentHash preclaim in tests ()

    • decode using calldata package ()

    Bug Fixes

    • commitlint issue ()

    • compiler errors: construct error message by server response ()

    • don't accept ak_ addresses as hash, bytes and signature ()

    • events: don't require function name for events decoding ()

    (2021-11-24)

    ⚠ BREAKING CHANGES

    • specify browserlist to better choice of features to transpile

    • aci: don't require source code

    • make contractDeploy a wrapper, remove unused code

    • inline getConsensusProtocolVersion function

    Features

    • aci: don't require source code ()

    • decode using calldata package ()

    • encode using calldata package ()

    • poll-interval: reduce poll interval to be a more sensible default ()

    Bug Fixes

    • compiler errors: construct error message by server response ()

    • events: fix event decoding order and address prefix ()

    • events: fix test for incorrect address return type ()

    • node errors: construct error message by server response (

    (2021-10-04)

    Refactoring

    • Remove channel from universal stamp ()

    (2021-09-30)

    ⚠ BREAKING CHANGES

    • drop following AENS delegation signature methods over the new common createAensDelegationSignature implementation which accepts an object as param ()

      • delegateNamePreclaimSignature

      • delegateNameClaimSignature

    Features

    • payForTransaction method ()

      • don't check is GA if innerTx ()

      • don't sent to blockchain if innerTx ()

    Maintenance

    • change default gas limit to 25000 ()

    Bug Fixes

    • AENS: name length minimum bid fee ()

    • delegate-signature: stop using the default account in the context of signing ()

    • mustAccountStamp: process accounts only if supplied ()

    • swagger https issue ()

    (2021-06-21)

    Bug Fixes

    • swagger file of aeternity's compiler ()

    • swagger file of aeternity's latest compiler ()

    (2021-06-17)

    ⚠ BREAKING CHANGES

    • crypto: remove outdated generateSaveWallet function

    • crypto: remove unused prepareTx, encodeTx, decodeTx functions

    • crypto: remove unused hexStringToByte function

    • crypto: rename messageToBinary to messageToHash adding hashing

    Bug Fixes

    • export aepp-wallet-communication ()

    • ponyfill Buffer in browser ()

    • ponyfill process in browser ()

    (2021-05-31)

    Bug Fixes

    • poi-tx schema: use proper type name ()

    • wait-for-tx-confirm: validate transaction height after awaitHeight ()

    Features

    • support [email protected] and above ()

    (2021-05-18)

    Bug Fixes

    • avoid instanceof between possible not/polyfilled objects ()

    (2021-05-12)

    Bug Fixes

    • revert conversion of case in calls to compiler ()

    Maintenance

    • avoid ts definitions based on broken JsDoc ()

    (2021-05-6)

    Important changes

    • Iris compatibility (compatible with nodes >= 5.2.0 < 7.0.0)

    • initial TypeScript support (not enough type definitions yet)

    • documentation is generated using MkDocs on Travis

    BREAKING CHANGES

    • Drop old aepp-wallet RPC interface ()

    • refactor: don't retrieve account from process.env ()

    • refactor(crypto): don't reexport RLP methods ()

    • refactoring: remove legacy contractDecodeDataAPI compiler method ()

    Features

    • swagger: allow to provide external specification ()

    • swagger: make compatible with OpenAPI 3 ()

    • switch to v3 endpoints on Iris ()

    • traverse-keys: add keysOfValuesToIgnore option as a workaround ()

    Docs

    • contract: fix default backend value ()

    • wallet-iframe: fix disconnect button ()

    • examples-browser: rearrange files and docs ()

    • use relative links between docs pages ()

    Code Refactoring

    • use BigNumber constructor instead of custom wrapper ()

    • avoid extra object nesting ()

    • compiler: use swagger file ()

    • semver-satisfies: remove extra splitting by dash ()

    Bug Fixes

    • traverse-keys: add missed null check ()

    • swagger: add workaround to get transaction details of GAAttachTx ()

    • top-block: use getTopHeader on Iris, mark deprecated ()

    • nonce-verification: add missed space (

    Maintenance

    • Use ts-standard instead of standard ()

    • tsconfig: Set target version to es5 ()

    • Fix eslint errors manually ()

    • require node below 7.0.0 ()

    Performance

    • Optimize height queries ()

    Tests

    • simplify GA tests ()

    • oracle: avoid explicit waiting for 1 second ()

    • passing of forceCompatibility flag ()

    • contract: remove extra backend option ()

    (2020-08-18)

    Features

    • transferFunds: Accept onAccount option ()

    • bigNumberToByteArray: Avoid unexpected behaviour by throwing exception ()

    • example: Add disconnect button on wallet side ()

    Code Refactoring

    • Use external version of json-bigint ()

    • Make tests configuration more flexible ()

    • test-else: Exclude aens tests and speedup jobs ()

    • Avoid unnecessary eslint-disable ()

    Docs

    • Fix typo in Readme.md ()

    (2020-07-22)

    Features

    • wallet-detector: allow to connect wallet to aepp between iframes ()

    (2020-06-18)

    Features

    • Account: Build signature from transaction hash () ()

    • ACI: External contract integration () ()

    Refactor

    • Deps: Clean up repository ()

    • Env: Simplify Travis and docker-compose ()

    • Env: Remove unused packages ()

    (2020-06-10)

    Bug Fixes

    • AEX-2: Handler always as Promise () ()

    Refactor

    • AEX-2: Add debug option for getHandler. Hide unknown message logs () ()

    • Contract Add AENS name resolver for Contract API

    (2020-05-30)

    Bug Fixes

    • AEX-2: Fix isExtensionContext check () ()

    (2020-05-29)

    Bug Fixes

    • AEX-2: Fix getBrowserAPI helper for cross-browser compatibility () ()

    Features

    • ACI: Event decoding () ()

    (2020-05-25)

    Improvements

    • AEX_2: Handle network switch and update state on both sides. Adjust networkId check for signing request. Add node switcher for example apps ()

    (2020-05-20)

    Bug Fixes

    • example: Regenerate lock () ()

    Features

    • ACI: expose events decoding through Contract ACI stamp () ()

    • AEX_2: Allow to connect without node () ()

    • AEX_2: Connect to extension from iframe () ()

    • Build:

    (2020-03-25)

    Fix

    • build Remove resolving of minimist using npx

    (2020-03-24)

    Docs

    • Guide: Adjust guide for RPC Wallet/Aepp usage

    Code Refactoring

    • RPC: Refactor rpc-related stuff ()

    • Build: Include amountFormatter and SCHEMA in bundle()

    • Examples Update examples apps

    Features

    • TX: Introduce new stamp TxObject() This stamp give more flexibility on transaction serialization/deserialization process

    • Keystore: Allow to store secret as hex or buffer ()

    • AEX-2: Add permission layer for account management ()

    (2020-02-27)

    Bug Fixes

    • TxBuilder: Fix fee calculation for Oracles () ()

    • AEX-2: Broken wallet detection ()

    (2020-02-25)

    Refactor

    • AEX: Simplify message id processing (). Pass AEEP origin to Wallet callback ()

    • Node: Move getNetworkId to helpers ()

    • ACI: Minor ACI validation improvement. Move decoding of events to builder. Add ability to decode events without ACI

    Features

    • ACI: Implement Contract Events for ACI()

    • Contract: Helpers for Oracle and AENS signature delegation()

    • AmountFormatter: Rework amount formatter. Change formatter units naming. Add more units () ()

    • TxBuilder:

    (2020-01-31)

    Bug Fixes

    • AEX-2: Fix firefox compatibility issue () ()

    Features

    • Chain: add new method waitFOrTxConfirm. Add new option { confirm: 3 } to all of high lvl SDK API. Add tests. Adjust docs () ()

    • Compiler: Add new compiler methods API () ()

    • network: Throw error when can not get networkId () ()

    Docs

    • Guide

    • Guide: Add , and guides

    BREAKING CHANGES

    Please check out

    This release include all changes from , ,

    (2020-01-22)

    Features

    • aens: implement aensExtendTtl function. Refactor aensUpdate () (), closes

      aensUpdate now accept array of pointersaensUpdate have new option extendPointers=false which retrieve pointers from the node and merge with provided

    • Build: update node to 5.4.0 and compiler to 4.2.0

    BREAKING CHANGES

    • AENS: Change AENS methods arguments

      Now all of AENS module methods accept name as a first argument instead of nameId

    (2020-01-10)

    Bug Fixes

    • codecov: Adjust codecov badge. Move @babel/runtime to dev-deps () ()

    • AEX-2: Fix getBrowserAPI function for firefox ()

    Features

    • Account: Add ability to pass keypair or MemoryAccount as nAccount` option () ()

    • Test: Increase code coverage () ()

    • Chain: Extend transaction verification error ()

    Documentation

    • Guide: Add guide for Contract ACI usage ()

    (2019-12-18)

    Bug Fixes

    • Contract/Chain: Using { waitMined: false } with Contract high lvl API () ()

    • HdWallet: Fix derive function () ()

    • Compiler: Filter compiler options

    Code Refactoring

    • Cross-Node: Remove cross-node compatibility code () ()

    • Chain: Handle time until tx is not added to mempool ()

    • Git: Update issue template()

    • Flavors: Remove deprecated code (

    Features

    • Wallet<->AEPP: Add new Wallet<->Aepp communication API

      Add two new stamps RpcWallet and RpcAepp Example of usage you can find heere: and

    • Wallet: Use postMessage for communication with extension wall… () ()

    BREAKING CHANGES

    • Tx: By default sdk make a transaction verification

    • Node: Change node compatibility range to node >= 5.0.0 && node < 6.0.0

    • Compiler: Drop compiler version to version >= 4.0.0 && version < 5.0.0

    (2019-12-11)

    Bug Fixes

    • Channel: 5.2.0 compatibility ()

    (2019-11-12)

    Bug Fixes

    • Composition: Chain composition ()

    (2019-11-12)

    Bug Fixes

    • ACI: Disable bytecode check for source and code on-chain. This changes will be included in next major release () ()

    Features

    • KeyStore: Remove argon2 package, use libsodium for both browser and node () ()

    (2019-11-11)

    Bug Fixes

    • AENS: auction end block calculation () ()

    • AENS: Fix produceNameId function(Make name lowercase). Enable … () ()

    • state channels: wait for connection to be established before sending generic message () ()

    Features

    • ACI: Add validation for contractAddress () ()

    • AENS: Add nameFee validation to TxValidator () ()

    • AENS: Increase default nameTtl () ()

    • Contract:

    (2019-10-31)

    Bug Fixes

    • name claim: Revert ignoring waitMined from user passed options (#727)

    (2019-10-29)

    Bug Fixes

    • aens: added lower case transformation for aens names () (), closes

    (2019-10-16)

    Code Refactoring

    • SPEND: Add additional validation for recipient () ()

    Features

    • State Channels: make state channels compatible with node v5.0.0… () (), closes

    • AENS: Change tld for Lima from aet to chain () ()

    • AENS: Implement name bid

    BREAKING CHANGES

    • AENS: Change tld for Lima from .aet to .chain

    (2019-10-04)

    Bug Fixes

    • rpc: fix resolution rpc ops () ()

    Code Refactoring

    • ACI: rework Sophia Option type representation () ()

    Features

    • AENS: Add ability to spend by name () ()

    • AENS: Add ability to claim contract, oracle, SC () ()

    • GA: enbale GA () ()

    • Lima: Lima compatibility (

    BREAKING CHANGES

    • aci: Change Sophia option type representation in ACI

    (2019-09-10)

    Bug Fixes

    • package: update serialize-javascript to version 2.0.0 () ()

    Features

    • Contract/ACI Add payable feature

    • Compiler: Compiler 4.0.0 compatibility () ()

    • Contract/ACI: Add ability to use contract with external namespaces(include "someLib") () ()

    (2019-09-11)

    Features

    • Oracle: Add methods for polling queries

    • Chain: Add getBalance method () ()

    • state channels: add reconnect method () ()

    (2019-08-28)

    Bug Fixes

    • Compiler: Fix forceCompatibility option ()

    Features

    • Lima: add preliminary support for lima

    • ACI/Contract: Implement static-call for deploy transaction for ACI methods/Contract low lvl API () ()

    Notes

    GA support has been disabled until further notice due to node compatibility issuesThis version support aeternity node up to 5.0.0-rc.1

    (2019-08-22)

    Refactor

    • Example Add node info to AEPP ()

    Bug Fixes

    • GA Fix GA account composition ()

    (2019-08-20)

    Bug Fixes

    • Crypto: Fix keypair verification () ()

    • RPC: Remove NodePool stamp from AE composition () ()

    • state channels: add missing argument in onOnChainTx callback () ()

    Features

    • MemoryAccount: Add validation of keypair () ()

    • state channels: handle BigNumbers with json-bigint () ()

    • state channels: send generic messages immediately () ()

    • Generalize Account

    (2019-08-09)

    Bug Fixes

    • Package: update commander to version 3.0.0 () ()

    • Contract: Fix dry-run without account ()

    Features

    • Contract: add ability to use call-static/dry-run without keyPair () ()

    • AE: Add ability to make operation on specific account using onAccount option.

    • JSON:: Add serialization to JSON for bigNumbers

    (2019-08-05)

    Bug Fixes

    • State Channels: Fix onChainTx event params () ()

    • State Channels: Fix websocket url () ()

    • Swagger: Pass query params in case of get request ()

    Code Refactoring

    • State Channel: Do not include white space for outgoing websocket messages ()

    Features

    • ACI: Implement sophia variant type () ()

    • Contract: add ability to use call-static/dry-run without keyPair () ()

    • NodePool: Implement NodePool stamp () ()

    Docs

    • ACI Add some additional clarification to getContractInstance

    (2019-07-15)

    Bug Fixes

    • package: update libsodium-wrappers-sumo to version 0.7.5 () ()

    • rpc-server: Fix type 'object' check () ()

    Code Refactoring

    • swagger: Speedup initialisation

    • AENS: Remove unused param from claim method

    • AENS: Fix exception if not waiting for mining(claim)

    • Test: Add test for contract namespaces

    Features

    • Node: Add 4.0.0 node compatibility

    • Compiler: Add compatibility with compiler 3.2.0

    • Channel: Implement GA awareness of State Channels

    (2019-06-22)

    Bug Fixes

    • Node: Do not throw error if internalUrl not provided. Instead use url () ()

    • TXBuilder: Fix payload serialization if you try to unpack and pack tx. () ()

    • TxValidator: Fix validation of state channel open transaction () ()

    Features

    • ACI: Refactor ACI module. Split to separated files. () ()

    • Selector: If default account address not provided use the first

    • ACI: Handle ACI without init function

    Docs

    • Usage:: Add instructions about how to include directly the SDK in a html page

    (2019-06-13)

    Bug Fixes

    • RPC: Add contract contractDecodeCallResultAPI to RPC () ()

    • README: Fix flavor link ()

    Code Refactoring

    • Compiler: Fix compiler compatibility mechanism () ()

    • Utils: Move json-bigint implementation to utils () ()

    Build

    • webpack: Add another bundle(dist/aepp-sdk.browser-script.js) for using in <script> tag ()

    (2019-06-12)

    Bug Fixes

    • Ae: Fix exception when it used without Contract stamp

    Code Refactoring

    • SCM: Update compatibility range for node: 3.0.1 - 4 and compiler 3.1.0 - 4 () ()

    • Test: Simplify client creation

    Features

    • Docs chore(Docs): new docs ()

    • Compiler: Add getCompilerVersion to compiler stamp

    • ACI: Make compatible with compiler 3.1.0 () (), closes

    BREAKING CHANGES

    • DOCS Restructure and rework sdk documentation

    • SCM: This change will make the release not compatible with older version of the node and compiler

    • ACI: Change Contract low lvl API:

      • change contractDecodeData

    (2019-06-05)

    Bug Fixes

    • Deps: Update axios lib to 0.19.0 due to security issue ()

    (2019-05-22)

    Bug Fixes

    • State Channels: Remove automatic pinging to fix browser compatibility () ()

    Features

    • Transaction Builder: Improve min fee calculation(Reduce the fee) ()

    • AXIOS: Add ability to intercept error from axios ()

      Added additional param to sdk initialization axiosConfig

      Example: Universal({ axiosConfig: { config: { // axios config object }, errorHandler: (err) => throw err }})

    (2019-05-17)

    Bug Fixes

    • AEP exampe: Fix contract in AEPP example () fix(AEP exampe): Fix contract in AEPP example

    Features

    • Consensus: Add function to get consensus version. () ()

    • State Channels: Make state channels compatible with aeternity 3.0.0 () ()

    • Transaction Builder: Add serializations for transactions introd… () ()

    BREAKING CHANGES

    • NODE Change compatibility from 2.3.0 to 3.0.0

    (2019-05-16)

    Bug Fixes

    • Joi: Add JOI browser comparability

    (2019-05-16)

    Bug Fixes

    • ACI: Add ability to pass zero address as number. () ()

    • ACI: Fix address type transformation when decoding data () ()

    • Contract: Add error handling(decoding) in low lvl contract API () ()

    Features

    • KEYSTORE: Add browser compatibility

    • TX: Handle VM/ABI fields serialization and validation basaed on tx type and node version

    • ACI: Add contract, address, record types argument/result transformation () ()

    BREAKING CHANGES

    • State Channels: Endpoint param is removed and no longer defaults to "/channel". This means that "/channel" (or other path) must be appendend to url para

    (2019-04-24)

    Bug Fixes

    • ACI: Fix address type transformation when decoding data () ()

    Features

    • ACI: Add contract, address, record types argument/result transformation () ()

    • ACI: Update due to compiler API changes () ()

    • Aepp: Add Compiler to Aepp rpc methods. Update example app () ()

    (2019-04-17)

    Bug Fixes

    • ACI: Fix address type transformation when decoding data () ()

    Features

    • TX_BUILDER: Channel tx serializations

    • TxValidator: Add minGasPrice validation to contract transactions

    • ACI: Update due to compiler API changes () ()

    • Aepp: Add Compiler to Aepp rpc methods. Update example app () (

    BREAKING CHANGES

    • ACI Remove 2.0.0 compiler compatibility

    (2019-04-17)

    Features

    • ACI: Add transform decoded data for 'address' type

    • AEPP: Add Compiler to Aepp rpc methods. Update example app

    • Channel: Add call contract static support

    • Channel: Add get contract state support

    Bug Fixes

    • HTTP: Handle no response in http stamp error handler

    • Crypto: Fix crypto formatAddress

    • Crypto: Move ADDRESS_FORMAT to crypto

    BREAKING CHANGES

    • Channels:

      • channel.state() now returns offchain state instead of last co-signed offchain transaction

      • channel.update(...).state has been renamed to signedTx

    (2019-04-17)

    Features

    • Chore: Install and configure commitizen

    • Crypto: Add formatAddress function to Crypto

    • Contract: Add Contract Compiler API stamp to es/contract (now using instead contract node API)

    Bug Fixes

    • Contract: decode node error coming from contract call and callStatic

    • Chain: Throw native error instead of object in chain chain.sendTransaction

    • Crypto: fix arguments parsing in Crypto.sing

    BREAKING CHANGES

    • Contract: Remove ContractNodeAPI stamp

    • Contract: Change Contract stamp API

    (2019-03-04)

    Features

    • Contract: Change default gasPrice from 1e6 to `1e9z

    • AEPP: Fix AEPP example app

    • Build: Force image pull before builds

    (2019-02-22)

    Features

    • Oracle: Oracle fee calculation

    • Tx: getAccountNonce function to tx stamp

    • TX_BUILDER: Change FEE_BYTE_SIZE from 1 to 8 bytes in fee

    (2019-02-22)

    Features

    • Node: Minerva comparability

    • Utils: Mnemonic wallet implementation es/utils/hd-wallet

    • Oracle: Change Channel legacy API to JSON RPC

    BREAKING CHANGES

    • Node: Change supported node version range to 1.4.0 <= version < 3.0.0

    • This release contain changes from: , , ,

    (2019-02-21)

    Features

    • Channel: channel withdraw and deposit methods

    • TX_BUILDER: Change default gasPrice in Contract stamp and Tx stamp to 1e9

    (2019-02-21)

    Feature

    • TX_BUILDER: Add deserialization schema for Channel transactions(channelCreate, channelCloseMutual, channelDeposit, channelWithdraw, channelSettle)

    • Chain: Add rawTx

    (2019-02-21)

    Bug Fixes

    • Chore: Fix linter errors

    (2019-02-21)

    Features

    • Node: Minerva comparability

    • Utils: Add Mnemonic wallet implementation es/utils/hd-wallet

    BREAKING CHANGES

    • Node: Change supported node version range to 1.4.0 <= version < 3.0.0

    (2019-02-21)

    Features

    • TX_BUILDER: Add unpackedTx, txType and signature to validate transaction function

    • Contract: Add top param to contract static call(dry-run)

    Bug Fixes

    • Rpc: RpcServer: Avoid storing of window in instance properties

    • Chain: Disable balance formatting by default

    • Chain: Move verification of transaction

    BREAKING CHANGES

    • TX: Remove old transaction builder es/tx/js.js (Please use es/tx/builder instead)

    • Chore: Rename es/epoch.js to es/node.js

    • Chore: Rename Oracle

    (2019-02-01)

    Features

    • Ae: Add destroyInstance function to Ae stamp which remove all listeners for RPC event's

    • Docs: Add docs for TransactionValidator and TxBuilder stamp's

    • Build: Add TxBuilderHelper

    Changed

    • Docs: Adjust doc's for Contract and Aens stamp's

    • Chore: Fix decoding of address from contract call

    (2019-01-29)

    Features

    • Build: Remove KeyStore from bundle due to build issue(for now you can export it only using tree-shaking import * as Keystore from '@aeternity/aepp-sdk/utils/keystore')

    (2019-01-29)

    Features

    • Channel: Add support for State Channels

    • TX_BUILDER: New transaction builder going through schema(build, unpack)

    • TX_VALIDATOR: Add new stamp TransactionValidator which can verify your transaction

    • Chore:

    Notes and known Issues

    • Old transaction builder es/tx/js.js will be removed in next major release.

    (2018-12-21)

    Features

    • Chain: amount formatter

    • Chain: amount format balance client.balance('AK_PUBLICKEY', { format: true })

    • Aepp: Oracle and Contracts API to Aepp stamp

    • Chore: Use

    Bug Fixes

    • Chr: Fix Import RLP package (thanks @davidyuk)

    • Rpc: Fix for NetworkId propagation and override

    • Tx: TxJS is not a stamp anymore, and instead: it exports helper functions

    BREAKING CHANGES

    • Tx: TxJs stamp (not a stamp anymore)

    • Chain: balance now answer a formatted string composed of AMOUNT + ' ' + unit (eg. 10 exa for 10 AE)

    Notes and known Issues

    • Chore: 10 exa should be 10 ae

    • Chain: format shouldn't be a flag, but a request for unit eg. { format: ae }

    (2018-12-15)

    Feature

    • Chore: isAddressValid check

    • Tx: Tx Fee formulas

    Bug Fixes

    • Rpc: Fixed networkId propagation (and overriding on init of Flavors)

    • Crypto: Fixed encodeBase58Check by feeding Buffered input

    BREAKING CHANGES

    • Chore: Compatibility with Node >= 1.0.0 and <= 1.1.0

    (2018-12-11)

    Features

    • Rpc: Added a command to remove images after CI testing

    Bug Fixes

    • Rpc: Fix Testing

    • Rpc: Fixed Oracle error for Wallet flavor

    (2018-12-11)

    Features

    • Oracle: Oracles functionality and flavor

    • Aepp: Simple example of aepp-in-aepp (see /examples folder)

    Bug Fixes

    • Tx: Fixed issue with big numbers and TX

    (2018-11-30)

    Features

    • Node: ability to support Node range(s) using semver package (see https://www.npmjs.com/package/semver#ranges)

    BREAKING CHANGES

    • Node: Support for Node >= 1.0.0 and < 2.0.0

    (2018-11-30)

    Features

    • Contract: Contract native Transactions

    Bug Fixes

    • BigNumber: Rolled back to bignumbers.js for easier fix with axios.get/post

    BREAKING CHANGES

    • Node: Support for Node < 1.0.0

    • Build: New NETWORK_ID (also used in docker/sdk.env for CI tests)

    • Protocol: Encoding of transaction (and other objects)

    Notes and known Issues

    • Channel: State Channels have been excluded for problems with CI, will be included in next release

    (2018-11-30)

    Notes and known Issues

    • Chore: See [0.25.0-0.1.0]

    (2018-11-30)

    Features

    • Utils Parsing of fee using bignum.js

    • Account Add networkId as param to Account flavor(default: ae_mainnet)

    BREAKING CHANGES

    • CLI and moved to separate repos and packages

    • Node Support for < 0.25.0

    (2018-11-30)

    Features

    • Contract Contract type checked call (Ability to call contract using contract address)

    • Contract Use ES methods instead of Ramda, where possible

    Bug Fixes

    • Contract Fixed keystore by adding a salt param for derivedKey function

    Breaking Changes

    • Contract Support for < 0.25.0

    • Contract Aens use domain .test instead of .aet (see )

    • Contract Use NETWORK_ID for signing (see )

    (2018-10-30)

    Features

    • Rpc RPC Client improvements

    • Rpc onContract Guard

    • CLI born

    • CLI Host

    BREAKING CHANGES

    • Chore The Cli flavor is now Universal

    • Chore the keypair keys changed from { pub, priv } to { publicKey, secretKey } for consistency with other systems using them (eg. AirGap and )

    Notes and known Issues

    • Chore CLI and AE PROJECT CLI will move to a separate package

    (2018-10-23)

    Features

    • Node Full support of

    • CLI Develop decode base58 address command in crypto module

    • CLI Add nonce param to all tx command's

    BREAKING CHANGES

    • Node Support for < 0.24.0

    • Keystore ethereum keystore usage will be removed in the next release

    • CLI CLI will move to a separate package

    (2018-10-02)

    Features

    • CLI Add CLI implementation

    • Crypto nameId function for commitment hash calculations

    • Node API endpoints to meet new Node specifications

    • Tx Add Nonce calculation on SDK side

    Bug Fixes

    • Crypto Fixes commitment hash calculations in naming system, to be Hash(nameId(name) + name_salt) instead of Hash(Hash(name + name_salt)).

    BREAKING CHANGES

    • Node Support for < 0.22.0

    (2018-07-31)

    Features

    • Docs Lots of new documentation (prose and API)

    • Docs Fancy badges to README

    • Build Transitive dev dependencies for standard-loader not covered by pnpm

    • Build CI Dockerfile to include pnpm

    (2018-07-24)

    Features

    • Node Support for Node 0.18.0 (changed endpoints)

    • RPC Wallet/Aepp RPC support

    • Contract Contract call result decoding support

    • Docs Per-module API documentation (Markdown based on JSDoc)

    Bug Fixes

    • Crypto Symmetric key encryption/decryption

    BREAKING CHANGES

    • Node Support for < 0.18.0 (changed endpoints)

    (2018-06-12)

    Features

    • Node Legacy Swagger file loading

    • Node Compatibility with < 0.15.0

    Bug Fixes

    • Contract Contract unit state initialization

    • Node Missing required parameter for name transfers (workaround for)

    (2018-06-11)

    Features

    • API New, opinionated top-level API

    • API Rest of legacy API now uses new API as well

    • API Generated API now encapsulated in api object

    • API Automatic case conversion for remote parameter names

    Bug Fixes

    • API [GH-49]: Handle existing path components correctly

    BREAKING CHANGES

    • API Remove Oracle API (for the time being)

    • API Remove Legacy API and tests

    • API Remove Compatibility with older versions of Node which provide the transaction hash the old way

    (2018-05-24)

    Features

    • Node Switch to curve ed25519 (from secp256k1) to align with Node protocol changes

    • Node Generate basic API directly from Swagger files, also validate input data

    • Build Compiled library now self-contained with all dependencies

    • Build Use Webpack 4 based cross-platform (Node/Web) compilation

    BREAKING CHANGES

    • Node Defunct scripts; will be brought back later

    Bug Fixes

    • Chore More consistent code examples

    aens: make getState's options override instance options (2e0d672)

  • aens: mark started_at as required in auction details (fba1012)

  • chain: set correct poll interval on hyperchain (0454c62)

  • contract: type checking of contract call return value (4c8926b)

  • middleware: generate api based on 1.97.1 (359c17a)

  • node,middleware: more strict enum handling (d3c5f0f)

  • tx-builder: replace OracleResponseTx with OracleRespondTx (19ec9b3)

  • wallet: don't require debug flag in BrowserRuntimeConnection (997db99)

  • node: Node returns time in KeyBlock and MicroBlockHeader as Date
  • middleware: require 1.81.0

  • sdk requires [email protected] or newer

  • sdk types requires [email protected] or newer

  • account: Save HD wallets methods removed

  • account: sign, signMessage removed

  • account: isValidKeypair removed

  • account: getAddressFromPriv removed

  • account: generateKeyPair removed

  • account: generateKeyPairFromSecret removed

  • recover, dump removed (AEX-3 keystore implementation)

  • node,compiler,middleware: $host is readonly in generated APIs

  • account: MemoryAccount accepts secret key as sk_-prefixed string

  • account: generateKeyPair returns secretKey encoded as sk_-prefixed string

  • aepp: RpcBroadcastError not exported anymore

  • NAME_BID_MAX_LENGTH not exported anymore

  • contract: encodeFateValue, decodeFateValue not exported anymore

  • Iris is not supported

  • middleware: sdk requires [email protected] and above

  • node: sdk requires aeternity node 7.1.0 and above

  • account: AccountBase inheritors required to implement signTypedData, signDelegation

  • signDelegationToContract removed

  • signNameDelegationToContract removed

  • signAllNamesDelegationToContract removed

  • signOracleQueryDelegationToContract removed

  • wallet,aepp: delegations used in Iris removed from aepp-wallet connection

  • createDelegationSignature removed

  • compiler: CompilerCli uses aesophia@8 by default

  • compiler: CompilerCli8 removed

  • compiler: CompilerCli and CompilerHttp requires aesophia@8

  • aens: aens* methods removed

  • tx-builder: NAME_*TTL, CLIENT_TTL not exported anymore

  • oracle: pollQueries don't return responded queries by default

  • oracle: pollForQueries method removed

  • oracle: extendOracleTtl method removed

  • oracle: respondToQuery method removed

  • oracle: getOracleObject method removed

  • oracle: registerOracle method removed

  • oracle: getQueryObject removed

  • oracle: postQueryToOracle, pollForQueryResponse methods removed

  • tx-builder: ORACLE_TTL, QUERY_TTL, RESPONSE_TTL not exported anymore

  • tx-builder: buildTx/unpackTx works only with transactions

  • tx-builder: Tag include only transactions

  • tx-builder: buildTx doesn't accept prefix anymore

  • contract: AeSdk:initializeContract removed

  • account: encode secret key as sk_-prefixed string (b94e198)
  • account: expose secretKey in MemoryAccount (d4320e6)

  • aepp: add api to ask wallet to select network (9871c91)

  • aepp: extract class to connect to wallet from AeSdkAepp (c3570ac)

  • middleware: add requestByPath method (ee5ac0c)

  • middleware: allow navigate to next/prev pages (b89cf5b)

  • middleware: mark as stable api (e25b06d)

  • middleware: prefixed types provided by OpenApi instead of strings (0b16a32)

  • middleware: return time as Date instance (e48ffd1)

  • middleware: switch to v3 api (b0015c0)

  • node: return time as Date instance (e0e33ea)

  • oracle: add includeResponded option to Oracle:pollQueries (78a07ab)

  • oracle: add Oracle:handleQueries method (03c77c0)

  • type, more accurate types (
    )
  • channel: accept host only if initiator (a7d4dde)

  • channel: reestablish flow (1f4a0c1)

  • channel: remove statePassword unsupported on node side (5cec07b)

  • channel: remove unsupported ways to reopen channel by a transaction (f3746a1)

  • middleware: accurate coin amounts (00a4f3e)

  • middleware: word casing in activity types (f1fbb29)

  • node,compiler,middleware: mark $host as readonly (9e47d5c)

  • node: avoid complex types by code replacements instead generics (4f531b1)

  • oracle: emit unhandled rejection instead printing error (3a57665)

  • tx-builder: count amount in execution cost when spend to yourself (5153649)

  • tx-builder: remove unused ChannelClientReconnectTx (e6e954a)

  • wallet: generate random string instead using external uuid dep (f8640d4)

  • wallet: origin if opened over file:// (cordova) (d529f30)

  • )
  • account: remove getAddressFromPriv (9446639)

  • account: remove isValidKeypair (512385a)

  • account: remove sign, signMessage (30077bc)

  • account: remove save HD wallet functions (10e7c89)

  • aens: replace aens methods with Name class (956daac)

  • aepp: remove RpcBroadcastError (1f0b3bb)

  • compiler: drop aesophia@7 support (df0e050)

  • contract: don't depend on Contract in AeSdk (00b4f86)

  • contract: remove encodeFateValue, decodeFateValue (c521597)

  • drop Iris support (61554b3)

  • drop [email protected] support (4008d12)

  • middleware: require 1.77.5 (08783fd)

  • middleware: require 1.81.0 (3243768)

  • node: require 7.1.0 (0dd3b49)

  • oracle: add Oracle class (54ee614)

  • oracle: add OracleClient class (0293fe4)

  • oracle: replace getQueryObject with OracleBase (bcab498)

  • remove createDelegationSignature (651b6ec)

  • remove NAME_BID_MAX_LENGTH (83797a4)

  • remove signAllNamesDelegationToContract (60a729d)

  • remove signDelegationToContract (cd495a6)

  • remove signNameDelegationToContract (9ab8f41)

  • remove signOracleQueryDelegationToContract (f948492)

  • remove keystore implementation (5e64ec9)

  • rename legacy bundles to cjs (46cd27b)

  • require [email protected] or newer (84d868c)

  • tx-builder: extract entries into separate builder (d5fde18)

  • tx-builder: remove deprecated constant exports (2ecf0f4)

  • tx-builder: remove deprecated constant exports (2342aa6)

  • update @types/node, drop TS below 4.8 (9d36e6c)

  • wallet,aepp: remove delegationToContract.sign method (c4d62b0)

  • type, more accurate types (
    )
  • channel: accept host only if initiator (cfdfd72)

  • channel: remove statePassword unsupported on node side (74db9bb)

  • don't allow upgrades @azure/core-rest-pipeline (03058d4)

  • don't allow upgrades @ledgerhq/hw-transport to 6.31.0 (1ef43e6)

  • wallet: origin if opened over file:// (cordova) (4ee44be)

  • aepp,wallet: allow raw data sign (7d0136d)
  • chain: add cache option to getHeight (c7d0955)

  • compiler: add CompilerCli8 class (29f1cd3)

  • compiler: provide compilation warnings (d0ec012)

  • compiler: update cli and http compilers to 7.4.0 (2041d8b)

  • contract: resolve names on node side in Ceres (474f0fd)

  • contract: support all names delegation to contract (92dae86)

  • jwt utilities (c747ce6)

  • node: add param indicating retry (6f0dbd8)

  • node: show error code if available (2cce91d)

  • spend to payable contract (7621716)

  • support new delegation format in Ceres (786e954)

  • tx-builder: get actual gas price from node (09d19bf)

  • tx-builder: pick queryFee from the node if not provided (ca495c8)

  • tx-builder: reject used accounts in GaAttachTx in Ceres (88b1d5d)

  • tx-builder: validate nameTtl in NameUpdateTx (bca877e)

  • contract: build address by signed tx (60a283b)
  • contract: don't duplicate NoSuchContractFunctionError message (2f3bba5)

  • improve error message when no wrapped value (054bc89)

  • node,middleware,compiler: version check if deployed at path (450296e)

  • node,middleware: remove duplicate retry policy (f6470a2)

  • node: add missed conversion of difficulty and hashrate to number (271ff5e)

  • node: don't remember failed version request (fba0e79)

  • node: show correct error message if body is missed (ed10482)

  • node: show correct error message if ECONNREFUSED (ef347a1)

  • tx-builder: don't accept ttl equal to block height (d9cde12)

  • tx-builder: don't estimate gas for non-transactions (f72167a)

  • tx-builder: limit ttl to 3 in case tx built internally (08d14c2)

  • tx-builder: remove invalid oracle tx type in validator (78e7c48)

  • contract: use current nonce in static calls (758bdfc)

  • node: don't retry 500 code responses (696e7db)

  • node: throw clear error message if unsupported protocol (21dfe34)

  • node: uncatchable exception if request failed in queue (dec62a4)

  • typos in error messages and docs (5c84671)

  • wallet: return accounts according to subscription (fa900c0)
    aepp,wallet: support inner transaction signing (725782b)
  • aepp,wallet: support signing typed data (78ce3b2)

  • compiler: add generateAci, generateAciBySourceCode (981bcf2)

  • middleware: generate autorest wrapper (bd08a08)

  • middleware: implement MiddlewareSubscriber (b51b0a3)

  • contract: use fallback account if onAccount not provided (9033cd7)

  • converting proxied options to JSON (efebbd1)

  • provide types in exports field of package.json (dbd19e7)

  • reject prefixes other than provided in isAddressValid (9462add)

  • tx-builder: buildTx produces the same type as unpackTx accepts (d3d6c88)

  • tx-builder: decode tag in entry error message (db0d96f)

  • wallet: emit internal error if something broke while broadcast (332d1b5)

  • wallet: throw reason of internal error to handle it in wallet (276699b)

  • aepp: remove select option in connectToWallet (adf9c3e)
    is required
  • AeSdk.getContractInstance renamed to AeSdk.initializeContract

  • getContractInstance function replaced with Contract class

  • Contract methods accessible on the instance itself

  • contract.methods.<name>.get,send removed

  • contract.bytecode,sourceCode moved to contract.$options

  • contract.calldata renamed to contract._calldata

  • contract.deployInfo removed

  • contract.options renamed to contract.$options

  • contract.decodeEvents renamed to contract.$decodeEvents

  • contract.call renamed to contract.$call

  • contract.compile renamed to contract.$compile

  • contract.deploy renamed to contract.$deploy

  • use sourceCode instead of source

  • getContractInstance accepts address instead of contractAddress

  • prepareTxParams, getVmVersion are not exported anymore

  • isGA method removed

  • in options
  • TX_TTL not exported anymore

  • sync buildTx accepts denomination in the first argument

  • Enum FIELD_TYPES is not exported anymore

  • Not able to build/unpack CompilerSophia entry (tag 70)

  • Enums PROTOCOL_VM_ABI, interface CtVersion not exported anymore

  • Enums VM_VERSIONS, ABI_VERSIONS, PROTOCOL_VERSIONS renamed

  • stateHash of Channel entry decoded as st_-prefixed string instead of hex

  • key of MtreeValue entry decoded as a buffer instead of a hex

  • SpendTx payload doesn't accept arbitrary strings anymore

  • unpackTx return an object of transaction parameters

  • unpackTx doesn't return rlpEncoded anymore

  • verifyTransaction doesn't accept parent tx types anymore

  • TxBuilder accepts and returns poi field unpacked as TreesPoi

  • buildTx accepts transaction type and version in the first argument

  • buildTx return string instead of object

  • buildTx doesn't return txObject anymore

  • buildTx doesn't return binary anymore

  • buildTx doesn't return rlpEncoded anymore

  • buildTx doesn't accept excludeKeys option anymore

  • Use version instead of VSN, vsn in unpackTx, buildTx

  • txType property of unpackTx removed

  • get method of MPTree accepts and returns typed values

  • writeInt function removed

  • returnType of contract call result structure is a value of CallReturnType enum

  • writeId, readId functions removed

  • readPointers, buildPointers functions removed

  • formatSalt function removed

  • validateParams, unpackRawTx functions removed

  • AMOUNT constant removed

  • Dropped compatibility with aesophia_http below 7.1.1, aesophia_cli below 7.0.1

  • AccountMemory requires networkId in signTransaction

  • AccountBase simplified

  • address in AccountBase is a property

  • MemoryAccount accepts only secretKey

  • MemoryAccount is not compatible with GA

  • ,
    oracle.pollQueries
    accepts a single query
    getAddressFromPriv doesn't accept private key as base64-encoded or raw string
  • isValidKeypair doesn't accept public key as base64-encoded string

  • bytesToHex function removed

  • hexToBytes function removed

  • rename umd export to Aeternity

  • Subpaths imports of SDK are not allowed

  • Removed getNetworkId from AeSdkBase

  • address a getter in AeSdkBase

  • addAccount is a sync function

  • verifyMessage removed from accounts and AeSdkBase

  • verify and verifyMessage accepts address instead of hex string or Uint8Array

  • node@12 not supported

  • removeAccount throws an error if the account is not found

  • signMessage always returns Uint8Array

  • encryptKey, decryptKey are not exported anymore

  • sha256hash not exported anymore

  • height method removed

  • signUsingGA method removed

  • POINTER_KEY_BY_PREFIX removed

  • ID_TAG_PREFIX, PREFIX_ID_TAG, ID_TAG removed

  • TX_TYPE removed.

  • GAS_MAX removed

  • calculateMinFee removed

  • salt, createSalt removed

  • Pointer removed

  • getBalance
    accepts OracleAddress (
    )
  • channel: emit newContract event (8d71bba)

  • contract: add ability to compile by path in node.js (74867b7)

  • contract: add CompilerCli (de56cbe)

  • contract: allow to create GA using sourceCodePath, bytecode (9410af2)

  • contract: decode emitted events of contract deploy (bf46eb6)

  • contract: don't require compiler (d2f9fa8)

  • contract: extract $getCallResultByTxHash method (0a8d138)

  • contract: support unit type (b5bf7a8)

  • node: exponential retry of requests on failure (aadec0d)

  • setup downleveled types for [email protected] and above (fd2b97f)

  • support CERES protocol version (8960a91)

  • tx-builder: deserialisation of channels.get.offchain_state (ed31aff)

  • tx-builder: implement buildAuthTxHashByGaMetaTx (bd656c2)

  • tx-builder: implement getExecutionCost and related functions (33085c2)

  • tx-builder: implement getTransactionSignerAddress function (2360cd2)

  • tx-builder: support incomplete MPTrees (115bcf5)

  • tx-builder: support recursive types (4f4dff6)

  • tx-builder: typed decoding of MPTrees (da1e35a)

  • tx-builder: unpack poi field of channel CloseSolo Slash tx (4a49b03)

  • tx-builder: validate address and enum fields in runtime (5898b3a)

  • account: add generate method to MemoryAccount (e0fa641)

  • add Ledger HW support (587e058)

  • ensure that used correct account type while signing transaction (46e8db3)

  • extract AeSdkMethods class with minimal interface (fd0fe76)

  • restore the ability to specify an array of accounts in AeSdk constructor (aba9b9f)

  • compatibility with @vue/cli@4 (41521ff)
  • contract: avoid any in arguments (70453f1)

  • contract: don't mark event field as required in Aci (2c44cd1)

  • contract: dry-run accept top as number (ebe5986)

  • contract: static call at specific height (99441dd)

  • contract: type of FunctionAci (0929304)

  • node: don't throw unhandled exception if version check failed (d4e5250)

  • oracle: ask height right before querying oracle to avoid not found (42706ca)

  • oracle: import getHeight instead of using a missing context (565c827)

  • tx-builder: calculation of gasLimitMax (0fb8a37)

  • tx-builder: don't check consensus protocol if sdk knows a single (6b8888b)

  • tx-builder: drop nonce validator to avoid false positive (a669aae)

  • tx-builder: ensure that TX RLP have the same length as schema (c042d73)

  • tx-builder: field DelegateIds in ChannelCreateTx (405243c)

  • tx-builder: provide proper type depending on checks being done (3cff062)

  • wallet: don't use Event.hasListeners that is not available in FF (05c0424)

  • wallet: explicitly convert error to JSON to don't pass stack trace (3948153)

  • wallet: provide origin on webext side instead of empty string (662d8d0)

  • channel: log field type in result of getContractCall (600d9e7)

  • channel: add missed types for minimumDepth, fee, gasPrice (a14ddfc)

  • channel: emit incoming message handler error instead of printing (d71efad)

  • channel: messageQueue type (1197ec4)

  • contract: don't throw ambiguous error if event types the same (669c326)

  • contract: don't throw error if already compiled (dcedb61)

  • contract: more specific error on calling without address (5c5a241)

  • don't swallow errors without checking their type and message (7456b0f)

  • don't use any in AeSdkBase constructor options (51fd3ae)

  • sync options between Contract and AeSdkBase (6acebaf)

  • tx-builder: avoid extra requests in tx validator (03c77e5)

  • tx-builder: mark nameTtl as shortUInt in NameUpdateTx (3bfbb52)

  • tx-builder: type of binary fields (e979224)

  • use crypto random to generate salt (88dcf38)

  • channel: handle round as number (97d7984)

  • getNetworkId throw proper error without node (3d9e73c)

  • move type packages required by TS projects to dependencies (90c5eb8)

  • node: avoid ts-expect-error missed in generated d.ts file (60d9755)

  • node: don't transform autorest properties (7982327)

  • Node: tread nameTtl, clientTtl as number (b82c398)

  • pollForQueryResponse: poll until query is expired (436f4a9)

  • sendTransaction: don't fall if onAccount missed in AeSdkBase (eebbcb7)

  • switch to aepp-calldata with fixed decoding of lists (c1a3b24)

  • AccountBase and inheritors are classes now

  • ChainNode, Contract, Oracle, Aens, Ae, GeneralizedAccount stamps not exported in the root, their methods exported instead

  • returns a promise
  • getNetworkId ignores force option

  • api and static properties are removed in Node

  • Node returns BigInts for coin amount fields instead of string or number

  • Node not accepts internalUrl

  • removed mempool method in Node

  • compilerVersion is removed in Compiler

  • setCompilerUrl changes compiler URL in sync

  • methods of Compiler requires options object according to their specification

  • methods of Compiler returns and accepts keys named in camelCase instead of snake_case

  • gas renamed to gasLimit
  • unpackTx not accepting transaction as Buffer, only as tx-encoded string

  • unpackTx doesn't have binary field in result

  • encode: since the prefix is evaluated by the type itself the required prefix parameter is no more accepted

  • calculateMinFee returns BigNumber instead of string

  • Fee helpers not exported anymore (BASE_GAS, GAS_PER_BYTE, KEY_BLOCK_INTERVAL,TX_FEE_BASE_GAS, TX_FEE_OTHER_GAS, calculateFee, DEFAULT_FEE)

  • buildRawTx, calculateTtl not exported anymore

  • TX_TYPE mapped to tag (number) instead of string

  • OBJECT_ID_TX_TYPE not exported anymore

  • TX_SERIALIZATION_SCHEMA combined with TX_DESERIALIZATION_SCHEMA

  • Transaction schemas doesn't contain tag anymore

  • removed ensureNameValid

  • name.update, name.revoke doesn't accept address in onAccount, only instances of AccountBase

  • call arguments in createGeneralizedAccount is required
  • filesystem option renamed to fileSystem

  • Contract instance doesn't accept address in onAccount, only instances of AccountBase

  • NodePool, AccountMultiple are removed (reimplemented in AeSdk)
  • DENOMINATION_MAGNITUDE not exposed anymore

  • The result of unpackTx returned instead of TxObject (in txObject option of onSign handler on wallet side; in tx field of contract call result)

  • validateKeyObj removed

  • deriveKeyUsingArgon2id removed

  • removed extra implementation of getAddressFromPriv in keystore

  • genSwaggerClient removed

  • RpcClient: sendMessage is a private method

  • RpcClient: handlers parameter is removed

  • RpcClient: doesn't contain aepp info anymore

  • RpcClient: doesn't contain networkId anymore

  • RPC helpers are not exposed anymore (isInIframe, sendMessage, getHandler, message,responseMessage, sendResponseMessage, isValidAccounts)

  • doesn't accept connection anymore

  • removed isConnected, isSubscribedAccount methods

  • signMessage returns Buffer by default

  • shareWalletInfo accepts rpcClientId instead of callback

  • shareNode argument in accept callback of onConnection removed

  • can't handle specific set of accounts for an app

  • txObject parameter of onSign callback is removed

  • callbacks accepts aeppId, params, and origin

  • rpcClients in wallet is not exposed anymore

  • onDisconnect callback on wallet side accepts client id instead of RpcClient

  • wallet can't selectively notify aepps about selecting/adding account

  • wallet can't provide metadata for accounts

  • removed action.{accept,deny} in permission callbacks

  • ae: drop stamps and use plain functions (8ed55d0)

  • aepp rpc: accept wallet info separately (baad98e)

  • aepp-rpc: depend on simplified version of RpcClient (f329549)

  • aepp-rpc: extract common error checks (eaa8683)

  • aepp-wallet: rewrite to ts all except rpc (19cb42f)

  • AeppRpc: make to init in sync (86c9d6c)

  • chain: drop stamps and use plain functions (4197b3d)

  • chain: remove deprecated methods (cefaa55)

  • compiler: extract genVersionCheckPolicy (ac14fd1)

  • don't provide default fee when transaction is not present (b004694)

  • drop ensureNameValid (d0d1258)

  • drop compiler stamp (ddf1363)

  • drop functions to generate txs with specific type (3cf767d)

  • drop TxObject wrapper (a083c7b)

  • encoder: remove required prefix param (dec13d7)

  • export in tree shaking friendly way (40aca86)

  • extract all fee-related stuff into a separate module (cebb90b)

  • extract base sdk classes (487cc14)

  • fix spend types (6b089e7)

  • getNetworkId: drop unnecessary force option (7d6549a)

  • getQueryObject: remove deprecated decode method (7e9835c)

  • inline NAME_BID_TIMEOUTS into computeAuctionEndBlock (5fdb80e)

  • NodeApi: return BigInt instead of string | number (7f37e74)

  • node: drop internalUrl (8336673)

  • node: rewrite to ts, drop stamp (370635e)

  • oracle: drop stamps and use plain functions (04ce814)

  • prepareTxParams: inline calculateTtl (2f03793)

  • remove ability to connect without sharing node if requested (7dd4af5)

  • remove extra getAddressFromPriv (0f88c39)

  • remove getAccountNonce (62a00e5)

  • remove outdated destroyInstance method (0213375)

  • rename gas to gasLimit where possible (dece758)

  • rewrite AE_AMOUNT_FORMATS to enum (448a2a3)

  • rewrite ae/contract to ts (8159d84)

  • rewrite TX_TYPE to enum (f97e479)

  • rpc account: don't pass extra options through rpc connection (141e932)

  • rpc-client: add notify method (9e97a1a)

  • rpc-client: provide method handlers instead of onMessage (5f1a007)

  • RpcClient: remove custom set of accounts (5c26f3a)

  • RpcClient: remove origin property (7155ed3)

  • rpc: inline extra helpers (9a0a2eb)

  • rpc: use webextension-polyfill (a54fdfd)

  • simplify transaction schema (5f720ec)

  • tests: migrate remaining tests ts (4e2ece7)

  • tx schema: add shortInt type for fields not needed big numbers (0095455)

  • unpackTx: accept only tx_string, don't return binary (658adee)

  • use calculateMinFee instead of calculateFee (4ea59d7)

  • utils: migrate keystore.js to ts (c013c01)

  • wallet rpc: don't pass networkId from aepp to wallet (153fd89)

  • wallet-rpc: drop info object in RpcClient (010ebbb)

  • wallet-rpc: remove meta, condition unused by known wallets (4630643)

  • wallet-rpc: return value/throw error instead of accept/deny (98b9955)

  • wallet-rpc: rewrite to TypeScript (930e7d7)

  • wallet-rpc: simplify callback arguments (5fc6f8a)

  • wallet-rpc: store rpc data in maps instead of objects (0d3f04f)

  • wallet-rpc: switch to TypeScript version of RpcClient (7d8f6d7)

  • crypto: make (encode/decode)Base(58/64)Check private

  • use bs58 instead of bs58check

  • update rlp to 3.0.0

  • tx builder: throw exception if deposit is not zero

  • tx schema: remove default NAME_FEE equal to 0

  • tx builder: accept unencoded name in nameClaimTx

  • spelling of GeneralizedAccount

  • aci: remove call/callStatic from deployInfo

  • aci: remove createdAt property generated at client

  • contract: remove deprecated contractCallStatic

  • contract: remove deprecated contractDeploy

  • contract: remove contractCompile

  • contract: remove deprecated contractCall

  • remove deprecated topBlock

  • remove unused functions

  • contract events: remote contract support

  • contract instance: store aci as it is

  • wallet-rpc: inline resolveOnAccount helper

  • aepp-wallet schema: convert to TS

  • aepp-wallet schema: rearrange METHODS enum

  • aepp-wallet schema: remove unused enums

  • contractCompile: remove encodeCall

  • compiler: remove contractEncodeCallDataAPI

  • compiler: remove getCompilerVersion

  • contract: remove compileContractAPI

  • contract: remove contractGetACI

  • contract: remove contractDecodeCallDataByCodeAPI

  • contract: remove contractDecodeCallDataBySourceAPI

  • contract: remove contractDecodeCallResultAPI

  • compiler: remove validateByteCodeAPI

  • compiler: remove getFateAssembler

  • compiler: remove getBytecodeCompilerVersion

  • poll: avoid extra transaction info request to node

  • drop https scheme workaround for hosted compiler

  • node: don't wrap internal endpoints if internalUrl missed

  • tx builder: inline VALIDATION_MESSAGE

  • decodeEvents: accept event schemas as it is in ACI

  • contract: remove already processed fields from decoded events

  • aci: drop redundant per-method event decoding

  • contract events: remote contract support (c7599c7)

  • createGeneralizeAccount: estimate gas limit instead of using const (da88852)

  • decode encode: validate base58 prefix and payload length (e836260)

  • error: introduce error types (#1345) (444bb33)

  • package: build es version compatible with node (480c747)

  • poll: use getCheckTxInPool if available (690db5b)

  • swagger: converts operationId in snake case to pascal (e52b739)

  • swagger: split transactions by queues to post batch of txs from one account (0023fc7)

  • tx builder: accept unencoded name in nameClaimTx (eea92be)

  • tx builder: don't require produceNameId to create AENS txs (57ef9c7)

  • tx builder: provide default name fee (18e4bab)

  • validator: check contractId (5e667a5)

  • wallet: add switch for aepp wallet node sharing (b5640d6)

  • wallet: enable aepp to wallet node connection (d87e1fa)

  • wallet: provide switch for aepp wallet node connection (dfbab59)

  • )
  • chain: don't require address function to post transaction (07bc105)

  • channel force progress: add missed binary prefixes (78660d2)

  • channel: ignore messages that can't be handled, print to console (aaad8e3)

  • compatibility: update argon2-browser to version with default export (0e69d8b)

  • compatibility: use blakejs that doesn't refer to Buffer (94f1879)

  • contract events: don't throw error if events emitted by remote (fa1c569)

  • delegate signature: don't encode address depending on onAccount (563a972)

  • dry-run: don't combine requests by default (0f36efc)

  • error: remove duplicate error message (8b4df9a)

  • es: babel build on windows (30f5213)

  • keystore: encoding of hex privateKey, simplify tests (9f3ad6b)

  • spelling of GeneralizedAccount (21c1dd3)

  • tx builder: reject more than 32 pointers (9c06dab)

  • tx builder: throw exception if deposit is not zero (7b3d0e3)

  • aci: drop redundant per-method event decoding (a84d781)

  • aci: remove call/callStatic from deployInfo (84d082d)

  • aci: remove createdAt property generated at client (406684c)

  • aepp-wallet schema: convert to TS (1775e91)

  • aepp-wallet schema: rearrange METHODS enum (8a40105)

  • aepp-wallet schema: remove unused enums (95bf0e9)

  • compiler: remove contractEncodeCallDataAPI (7d02317)

  • compiler: remove getBytecodeCompilerVersion (13283be)

  • compiler: remove getCompilerVersion (fb929f8)

  • compiler: remove getFateAssembler (165d492)

  • compiler: remove validateByteCodeAPI (90ba164)

  • contract instance: store aci as it is (978225e)

  • contractCompile: remove encodeCall (6d0ade5)

  • contract: remove already processed fields from decoded events (45bae5f)

  • contract: remove compileContractAPI (5ae9c62)

  • contract: remove contractCompile (7390629)

  • contract: remove contractDecodeCallDataByCodeAPI (2fe798a)

  • contract: remove contractDecodeCallDataBySourceAPI (8b13f70)

  • contract: remove contractDecodeCallResultAPI (b9fbfa6)

  • contract: remove contractGetACI (23ada71)

  • contract: remove deprecated contractCall (c079e6e)

  • contract: remove deprecated contractCallStatic (1e3ac6d)

  • contract: remove deprecated contractDeploy (08e423e)

  • crypto: make (encode/decode)Base(58/64)Check private (c151183)

  • decodeEvents: accept event schemas as it is in ACI (17b9cc4)

  • drop https scheme workaround for hosted compiler (9fc0a02)

  • hd-wallet: expect that bip39 used externally (f6243ad)

  • hd-wallet: remove default export (951ebb2)

  • node: don't wrap internal endpoints if internalUrl missed (50d7bba)

  • poll: avoid extra transaction info request to node (22c4838)

  • remove deprecated topBlock (4535c07)

  • remove unused functions (8c00de5)

  • return empty array instead of throwing UnsignedTxError (c6bacdf)

  • rpc: remove forceValidation flag (9f958c3)

  • tx builder: inline VALIDATION_MESSAGE (defb7e1)

  • tx schema: remove default NAME_FEE equal to 0 (9d8339a)

  • update rlp to 3.0.0 (bb32b77)

  • use bs58 instead of bs58check (32e836b)

  • wallet-rpc: inline resolveOnAccount helper (1277b5b)

  • make contractDeploy a wrapper, remove unused code

  • inline getConsensusProtocolVersion function

  • invert and rename forceCodeCheck option to validateByteCode

  • require compiler 6 and above

  • make contractCall/Static a wrapper around getContractInstance

  • contract instance: thread all extra options as contract's

  • contract instance: remove unnecessary setOptions function

  • remove contractDecodeData as extra wrapper

  • remove contractEncodeCall as extra wrapper

  • don't accept ak_ addresses as hash, bytes and signature

  • transformation: drop extra wrapper around bindings

  • transformation: don't export extra functions

  • drop unnecessary skipTransformDecoded option

  • drop unnecessary skipArgsConvert option

  • encode using calldata package (eeebbd5)

  • poll-interval: reduce poll interval to be a more sensible default (9e55b2b)

  • support for new node feature next-nonce of release 6.2.0 (#1299) (e40b046)

  • events: fix event decoding order and address prefix (faad530)

  • events: fix test for incorrect address return type (31aaeec)

  • events: ignore unknown events in decoding (45795fa)

  • node errors: construct error message by server response (d556936)

  • semverSatisfies: ignore build number (c3cce0a)

  • swagger: detection of empty response (9bfab02)

  • contract instance: remove unnecessary setOptions function (b88e767)

  • contract instance: thread all extra options as contract's (10fb7ba)

  • crypto: remove unused asymmetric encode/decode functions (51def34)

  • drop unnecessary skipArgsConvert option (6d4a599)

  • drop unnecessary skipTransformDecoded option (bb49239)

  • inline getConsensusProtocolVersion function (75f0447)

  • invert and rename forceCodeCheck option to validateByteCode (72122fa)

  • make contractCall/Static a wrapper around getContractInstance (c4ec019)

  • make contractDeploy a wrapper, remove unused code (48d36f9)

  • remove contractDecodeData as extra wrapper (5df2285)

  • remove contractEncodeCall as extra wrapper (a4b303f)

  • require compiler 6 and above (f9cef12)

  • specify browserlist to better choice of features to transpile (c2ec71a)

  • transformation: don't export extra functions (fa38b40)

  • transformation: drop extra wrapper around bindings (9b70f8e)

  • invert and rename forceCodeCheck option to validateByteCode

  • require compiler 6 and above

  • make contractCall/Static a wrapper around getContractInstance

  • contract instance: thread all extra options as contract's

  • contract instance: remove unnecessary setOptions function

  • remove contractDecodeData as extra wrapper

  • remove contractEncodeCall as extra wrapper

  • don't accept ak_ addresses as hash, bytes and signature

  • transformation: drop extra wrapper around bindings

  • transformation: don't export extra functions

  • drop unnecessary skipTransformDecoded option

  • drop unnecessary skipArgsConvert option

  • support for new node feature next-nonce of release 6.2.0 (#1299) (e40b046)

  • aens: enable commitmentHash preclaim in tests (5de05e5)

  • )
  • semverSatisfies: ignore build number (c3cce0a)

  • commitlint issue (2c1cf54)

  • don't accept ak_ addresses as hash, bytes and signature (cbaac62)

  • drop unnecessary skipArgsConvert option (6d4a599)

  • drop unnecessary skipTransformDecoded option (bb49239)

  • inline getConsensusProtocolVersion function (75f0447)

  • invert and rename forceCodeCheck option to validateByteCode (72122fa)

  • make contractCall/Static a wrapper around getContractInstance (c4ec019)

  • make contractDeploy a wrapper, remove unused code (48d36f9)

  • remove contractDecodeData as extra wrapper (5df2285)

  • require compiler 6 and above (f9cef12)

  • specify browserlist to better choice of features to transpile (c2ec71a)

  • contract instance: remove unnecessary setOptions function (b88e767)

  • contract instance: thread all extra options as contract's (10fb7ba)

  • remove contractEncodeCall as extra wrapper (a4b303f)

  • transformation: don't export extra functions (fa38b40)

  • transformation: drop extra wrapper around bindings (9b70f8e)

  • delegateNameTransferSignature

  • delegateNameRevokeSignature

  • drop following oracle delegation signature methods over the new common createOracleDelegationSignature implementation accepts an object param (88b7bf3)

    • delegateOracleRegisterSignature

    • delegateOracleExtendSignature

    • delegateOracleRespondSignature

  • drop assertedType, use decode instead (00d563f)

  • drop waitMined static method (2f299de)

  • tx-validator now gives different, more meaningful, errors (95a2a23)

  • no longer exports buildHash function, use hash or buildTxHash (9e1fde7)

  • tx-verification is now done by default (989b36f)

  • deposit-trap:
    enforce zero value for
    deposit
    during contract deploy (
    )

    tx serialisation: accept unpackTx output produced by deserialisator (ff0b3f5)

    crypto: drop extra "personal" from message functions

  • crypto: remove unused formatAddress function

  • crypto: remove unused addressToHex function

  • node-pool: inline helpers, export by default

  • string: use isAddressValid instead of isAeAddress

  • string: remove unused snakeOrKebabToPascal function

  • drop outdated protocols and transactions schemas

  • drop compatibility with node@5

  • rlp: import as it is (736b0f5)
  • typo name of broadcast failed error generator (ae7e823)

  • examlple-aepp: open only when ready to accept connection (4872eb9)

  • crypto: drop extra "personal" from message functions (34288cb)

  • crypto: remove outdated generateSaveWallet function (37298be)

  • crypto: remove unused addressToHex function (93f9def)

  • crypto: remove unused formatAddress function (a5d4b62)

  • crypto: remove unused hexStringToByte function (ed39a76)

  • crypto: remove unused prepareTx, encodeTx, decodeTx functions (64d15eb)

  • crypto: rename messageToBinary to messageToHash adding hashing (df37004)

  • node-pool: inline helpers, export by default (ed1cfb5)

  • string: remove unused snakeOrKebabToPascal function (79bdc04)

  • string: use isAddressValid instead of isAeAddress (ac7d827)

  • drop compatibility with node@5 (f5e2fdb)

  • drop outdated protocols and transactions schemas (f18d305)

  • refactor: rename forceCompatibility to more clear ignoreVersion (72f1d326)

  • refactoring: require compiler above or equal to 4.1.0 (c9f48f91)

  • RpcClient: Drop unnecessary action stuff (84545fd7)

  • Combine RpcWallet and RpcClients (12892002)

  • Drop old names support, split ensureNameValid and isNameValid (315a78a9)

  • refactor(contract-aci): export single function instead of stamp (091b3282)

  • Combine Accounts and Selector into AccountMultiple (0cacd3b3)

  • Use swagger-client instead of a custom implementation (4b3260d5)

  • Remove OracleNodeAPI wrapper (c6f9a76d)

  • Flatten options of contractCallStatic, remove extra dryRunContractTx (f3ffb664)

  • txDryRun: Simplify arguments, support txEvents option (401c53da)

  • contracts: Mark handleCallError as private, simplify arguments (bdf76e24)

  • import/no-named-as-default linter error (d63e1511)

  • oracle: make pollForQueries a sync function (dc955e14)

  • chore: drop aevm support and backend (compiler) option (6eb702dd)

  • refactor(schema): export enum with consensus protocol versions (e92f187d)

  • Use es modules version in browser if supported (b49c38f0)

  • Add typescript support (abde033a)

  • remove outdated aecrypto example (7df05bfe)

  • refactor node examples (e8c443cf)

  • changelog: add missed single quote in example (45fd0002)

  • resolveName: Document verify option (ca865596)

  • Remove outdated docs (cf9c166f)

  • decodeTx: Fix arg naming and annotation (883819c0)

  • contract-events: Remove outdated contract, update links and markup (37d39d61)

  • Update docs/guides/import-nodejs.md (9dc274ed)

  • Update docs/guides/import-nodejs.md (93bfce11)

  • break down json obj keys necessary for account initialization in nodejs docs (af5ee41d)

  • Ignore pycache in the docs folder (9989e8e7)

  • Specify the python version more precisely (d6204523)

  • Add pycache to .gitignore (f0b7e1f1)

  • Add navigation and update some titles (8ad15ced)

  • docco template: Remove extra new lines around code, skip extra blocks (65ce3cf1)

  • aecontract: Make a list out of a long sentence (8ff7839c)

  • aens-usage: Use more semantic markup, compatible with mkdocs (de3d3cd5)

  • docs readme: Fix typos and formatting (5b0c790d)

  • Add initial mkdocs and readthedocs configuration (b688a96b)

  • Extract quick-start to guides (28f7e6f7)

  • Update testnet URL (7bb823f8)

  • assertedType: Make the last parameter more obvious (50094d3a)

  • travis: Build docs to gh-pages (7c935a2b)

  • Docs root: Add link to API reference (4a36102d)

  • Move outdated disclaimer to the root readme (80a6a663)

  • Remove generated docs (fd802b00)

  • Fix api docs generation (56e3aa9d)

  • remove extra char in regex (37eeefae)

  • refactor wallet detector (1bc8d027)

  • shareWalletInfo: Don't create unnecessary copy of info (3a4e50b9)

  • Inline receive helper that is used once (a4a13889)

  • rpc: Inline helpers used once (21903f4d)

  • rpc: Prefer default export (70fc3f0f)

  • rpc helpers: Remove unused getWindow function (c12b528f)

  • don't use AsyncInit where it is not necessary (84373697)

  • contract-aci: reuse defaults from Contract stamp (47013962)

  • cleanup MIN_GAS_PRICE (a5b28842)

  • remove unused option string (0e28af23)

  • remove unused dryRunAccount default option (8c42b706)

  • Consistent new on Error creation (39f93d3f)

  • height: Use a shorter syntax (b013bf9d)

  • height: Improve naming of internal promise (7915119a)

  • Move source code to "src" folder (ddbce389)

  • sign-using-ga: don't pass extra options (44bab6d0)

  • )
  • missed aepp id in wallet connect handler (1ed9284a)

  • get-node-info: bring url and internalUrl back (e984f3b3)

  • contract error decoding (d56931ac)

  • contract-aci: don't proxy prepareArgsForEncode from helpers (7e40eda0)

  • Improve handling of call error (584eb5e4)

  • require node above or equal to 5.2.0 (ebb36f06)

  • update dependencies (d876cff7)

  • deps: bump ssri from 6.0.1 to 6.0.2 (e0dfb8c9)

  • deps: bump y18n from 4.0.0 to 4.0.1 (9e4acd61)

  • deps: bump elliptic from 6.5.3 to 6.5.4 (feb3aa68)

  • deps: bump axios from 0.19.2 to 0.21.1 (0f619f27)

  • deps: bump ini from 1.3.5 to 1.3.7 (95580324)

  • deps: bump highlight.js from 10.4.0 to 10.4.1 (9fcfadfe)

  • deps: bump highlight.js from 10.1.1 to 10.4.0 (43aff25f)

  • deps: bump node-fetch from 2.6.0 to 2.6.1 (80ed6d70)

  • Update node to 5.8.0 (b6ff3422)

  • Update .gitignore (1f1563dc)

  • add vscode .history folder to gitignore (f4d61df4)

  • Update testnet URL in JS files (dc1b807a)

  • add Iris consensus protocol (41fd4a13)

  • add vsn 2 version of GA_META transaction (b5abe098)

  • add new versions of CHANNEL, CHANNEL_CREATE transactions (366981a3)

  • support compilers below 6.0.0 (876e5164)

  • update channel tests to fate (35a996d8)

  • Faster tests (5d629103)

  • Extract strings tests into separate file (f3c7d3fa)

  • ga: Remove extra await (72bfc746)

  • Make tests more precise (fe7a8567)

  • Add lint script (#1045)

  • Refactor tests (#1039)

  • Refactor bytes unit tests (#1050)

  • travis: Run linter and unit tests firstly (#1051)

  • Disable Travis on all branches except master, develop (#1054)

  • Refactor contract, oracle, chain (#1048)

  • Refactor state channels (#1047)

  • Expose
    ACIHelpers
    and
    ACITransformation
    to bundle (
    ) (
    )
  • Chain: Add option allowUnsynced for poll method which allow to depend on get tx/info API (9c80ce0)

  • Channel: add timeout message handler (#983) (1940a15)

  • Channel: Channel force progress (#964) (8f15bef)

  • Contract: Add unpacked transaction to contract call with error (#981) (4efd341)

  • Node: Add debug option to Channel stamp (#967) (68fcba5)

  • Integrate amount formatter to transaction builder (
    )
  • Account: Implement Message Signing (singMessage, verifyMessage) (#903)

  • AEX-2: Add removeRpcClient method to RpcClient/RpcWallet stamp's(#912)

  • Guide Add guide for AENS usage

  • Aepp<->Wallet: Add tests for Aepp<->Wallet communication (#834)

    )
  • Test: Increase code covarage (#830) (6f760fb)

  • CI: Move to Travis CI (#809) (2d77f20)

  • CI: enable daily builds on latest node and compiler and enable codecov (#820) (3c52a1e)

  • ACI: Add check for contract address validity and existence. Add forceCodeCheck option for bytecode verification skip (#788) (c0cccc9)

  • Contract: Add ability to pass arguments or callData for contract deploy/call/callStatic API (#768) (a828076)

  • Contract: Adjust fee calculation for contractCall tx using FATE backend (#793) (7254ac1)

  • Compiler: Add new API validateByteCodeAPI available on compiler >= 4.1.0 (#788) (c0cccc9)

  • Tx: Always verify transaction before send it to the node (#798) (170f479)

  • ACI: Add additional method to RPC communication. Required sdk update on wallet side Add getContractByteCode API

  • Flavor: Remove deprecated params:

  • remove url and internalUrl instead use nodes: [ { name: 'NODE_NAME', instance: await Node({ url, internalUrl }) } ]

  • remove keypair params instead use accounts: [MemmoryAccount({ keypair })]

  • remove setKeypair function from Account stamps

  • TxHelpers: Use BigNumber in auction end block calculation (777c012)

    Add ability to pass arguments or callData for contract
    deploy/call/callStatic
    API (
    ) (
    )
  • Http: Assign error object to http error (#770) (87062ea)

  • state channels: add round method (#763) (c950937)

  • state channels: allow off chain updates to be cancelled with custom error code (#753) (ae4426e)

  • state channels: allow to pass metadata to transfer update (#755) (ddc6611)

  • state channels: make state channels compatible with node v5.0.0… (#688) (deed7fc), closes #632 #653 #658 #660 #680 #693 #687

  • state channels: make state channels compatible with node v5.1.0… (#776) (74952aa)

  • function (
    ))
  • AENS: auction name fee calculation. Name fee validation and calculation in claim/bid (#706)

  • AENS: Add nameId computation function (#709) (#706)

  • ) (
    ), closes
    • AENS auction support

    • compiler 4.0.0 support

    • node 5.0.0 support

    • SDK use FATE for contract by default

  • AE: Add pointers verification for spend by name

  • state channels: add backchannel updates test#664
    state channels: fix awaitingOnChainTx state handler (#608) (8b7b65a)
  • Swagger: Always throw error from axios error handler (#607) (0e5cf61)

  • Implement Generalized account support (
    )
    MemoryAccount: Add validation of keypair (#594) (b8c2b20)
  • State Channels: persist connection by pinging every 10 seconds (#571) (a70f919)

  • State Channel: make state channel compatible with [email protected] (#568) (0d0e09b)
  • TxBuilder: Add helper for producing tx hash (#579) (e1b405e)

  • AE Make all AE stamps composed with Accounts (#581)

  • ACI: Automatically decide to send transaction on-chai or call-static. Add options object like last arguments of generate fn under instance.methods
    ACI: Generate JS function proto for each of contract function (#439) (2f47b4d)
  • Compiler/ACI: Make ACI compatible with compiler 3.0.0 (#441) (2a8eb1a)

  • Node: Avoid usage of "universal-url" package (#434) (a8268d5)

  • TX: encode payload as base64 (#460) (ad490af)

  • TX_BUILDER: Fix bug related to contract fee calculation. (#472) (7214cfb)

  • interface from:
    • (type:String, data: String) => Any to (source: String, fn: String, callValue: String, callResult:String) => Any. (callResult is callType from call result, can be ok, revert, ...)

    Transaction Builder: Implement vm/abi validation for contract/oracle tx based on consensus protocol version. Add custom verification based on transaction type (#425) (#426)

    Dependencies:
    Use URL class instead of "url" package
  • Dependencies: Use custom version of json-bigint

  • Dependencies: Avoid usage of semver package and cleanup deps

  • RPC: rpc client: Handle case if aepp opened without wallet

  • Channels: Fix state channel test's

  • WEBPACK: webpack configs: Mark all dependencies as external

  • WEBPACK: Setup webpack-bundle-analyzer plugin

  • ACI: Add Option sophia type to ACI (#390) (83f5279)

  • ACI: Implement arguments validation for generic sophia types(list, map, tuple, record) (#384) (956e59e)

  • ACI: Update due to compiler API changes (#331) (e047f3b)

  • AE: Allow to spend % of balance. (#371) (f97a2ae), closes #336

  • Aepp: Add Compiler to Aepp rpc methods. Update example app (#312) (9c72521)

  • Aepp: Refactor Aepp example app. Allow to spend with payload and add reverse iframe approach.

  • Compiler: Add decode CallData by source/bytecode (#354) (761f36b)

  • Fortuna: Node 3.0.0 compatibility (#397) (17b78d5)

  • RPC: Add getNodeInfo to AEPP stamp through RPC (#359) (2ddeea8)

  • State Channels: Add cleanContractCalls method (#338) (778159a)

  • State Channels: Ping every 10 seconds to persist connection (#324) (6d0e156), closes #276 #299 #300 #303 #302 #279 #275 #276 #299 #300

  • State Channels: Remove endpoint param (#391) (8d9ea7e)

  • Compiler: Add decode CallData by source/bytecode (#354) (761f36b)

  • RPC: Add getNodeInfo and getNetworkId to AEPP stamp through RPC (#359) (2ddeea8)

  • State Channels: Add cleanContractCalls method (#338) (778159a)

  • State Channels: Ping every 10 seconds to persist connection (#324) (6d0e156)

  • )
  • State Channels: Add cleanContractCalls method (#338) (778159a)

  • Channel: Get full channel state support

  • DOCS: Adjust ACI, Contract and Usage

  • channel.withdraw(...).state has been renamed to signedTx

  • channel.deposit(...).state has been renamed to signedTx

  • channel.leave().state has been renamed to signedTx

  • channel.createContract(...).state has been renamed to signedTx

  • channel.callContract(...).state has been renamed to signedTx

  • Utils: Add basic http client stamp (es/utils/http)

  • Contract: ACI stamp (New Contract interface base on contract ACI schema)

  • Account: Extend Account.address() with accountFormatter now you can do

  • Channel: Improve channel rpc usage

  • Channel: Improve channel tests and error handling

  • Channel: Improve state channel params handling

  • Chain: Add ability to get account/balance on specific block hash/height

  • Universal: Add { compilerUrl } to Universal, Contract, Wallet stamp initialization

  • Crypto: Fix name hash function arguments parsing in Crypto

    calculation
  • TX_BUILDER: Improve error handling in tx builder

  • Oracle: Change default gasPrice to 1e6

  • Oracle: Change minFee calculation, multiply min fee by 1e9

  • TX: Fix contract tx fee calculation

  • Chain: Refactor error handling in sendTransaction function

  • Contract: Change default gasPrice to 1e9

  • TX_BUILDER: Change Fee byte_size to 1

  • and
    verifyTx
    to error from poll function(when you wait for transaction will mined)
  • Chore: Depend on bip39 from npm instead of git repo

  • Channel: Change Channel legacy API to JSON RPC

  • TX_BUILDER: Change minFee calculation, multiply min fee by 10^9

  • Contract: Add errors handling for dry-run

  • Docs: Add keystore docs

  • Ae: Add verify options to send function which verify tx before broadcasting and throw error if tx is invalid

  • Rpc: Add dryRun to RPC methods

  • Rpc: Add Oracle transaction creation to Aepp rpc

  • Docs: Add tx builder docs

  • Docs: Add doc's for utils/bytes and tx builder schema

  • TX_BUILDER: refactor calculateFee function in TxBuilder(use BigNumber)

  • TX_BUILDER: Extend response of Oracle, Aens, Contrat with rawTx

  • Ae: Change response of send function now it's and object with transaction data(hash, rawTxHash, ...)

  • Chain: Move Contract and Oracle API wrapper's to Chain stamp

  • Chore: Rename epoch in CHANGELOG, README, HACKING

  • to
    chain
    stamp
  • Node: Retrieve node version from /api

  • Chore: Fix unpack tx example in bin/aecrypto.js

  • Chore: Remove unused function's from crypto.js

  • ,
    Contract
    ,
    Chain
    API wrapper files from
    epoch
    to
    node
  • Chore: Rename Contract api wrapper method's

  • to bundle
  • Chore: Contract call static now using dry-run API

  • Test: Improve test's for Transaction verification

  • Rename epoch to aeternity node(docker configs, some docs)
  • Tx: Use new tx builder in TX stamp

  • Contract: Set default values for amount and deposit to 0 for contract transaction

  • Rpc: Improve RPC server

  • prepare
    instead of
    postinstall-build
    (thanks @davidyuk)
  • Docs: Refreshed Docs: README.md + docs/usage.md

  • Tx
    Implement native build of
    AENS
    transaction.
  • Keystore Update keystore for new requirements

  • parameter became
    Url
    . (
    -u
    for hostname,
    -U
    for internal)
  • CLI New keystore following these specifications: https://www.pivotaltracker.com/n/projects/2124891/stories/155155204

  • CLI Add gas param to deploy and call commands

  • Tx Add ability to create spend transaction natively

  • Keystore Implement ethereum keystore using AES-126-CTR and SCRYPT as key derivation function

  • CLI Change --privateKey to flag on ACCOUNT ADDRESS command

  • Build Change node version in Dockerfile

  • Node API endpoints to meet new Node specifications

  • Chore Update docco config and change rename package to recursive-rename

  • Docs Improved documentation

  • Contract Add check for MAX_GAS in call and deploy contract

  • Chore change hash prefix separator from $ to _

  • Chore Add keywords ('SDK', 'CLI') to package.json

  • CLI Link aecli to ./bin/aecli.js in package.json (After "npm link" you can use CLI globally)

  • Aens Wait until pre-claim transaction block was mined before send claim transaction

  • Build Updated webpack, webpack-cli and added new dev deps accordingly

  • Node Add Node Compatibility Check

  • Docs Fancy-shmancy diagram in README

  • DocsGenerated documentation files since they are linked in static docs

  • Build Switch from Yarn to pnpm for building

  • Docs Structure of documentation

  • Docs Generate Markdown from Docco

  • Docs More API documentation (still incomplete)

  • Build SDK entrypoint factories (in /es/ae/universal.js)

  • Build Module load path (src -> es)

  • Chore Lower mining rate (5s) in docker-compose

  • API Remaining tests to use new API

  • API Adapted new method of obtaining transaction hash, breaks compatibility (see below)

  • Docs Package description now reads SDK for the æternity blockchain

  • Chore Authors are now taken from AUTHORS instead of package.json

  • Docs Moved code examples from README to separate file in docs

  • 1d60eac
    9e74b53
    0116d74
    fe74643
    b0288cc
    5a11dc3
    5306e6b
    f862b67
    a4a0232
    4150890
    8700534
    88c242a
    c8dc8cc
    05fcdfd
    e2f83d6
    2d6c59d
    0af61da
    2727713
    e347d25
    3b2f20c
    847bfa6
    14.0.0
    migration guide
    tool
    5047e43
    e9f9694
    c785521
    1652a4b
    329de9e
    2b247ff
    f2c6d1d
    18c6789
    13.3.3
    0524553
    15063c6
    8ce976e
    13.3.2
    8c4287f
    6f8cdc9
    13.3.1
    562eda9
    13.3.0
    2c21139
    04508d0
    db2659a
    028876f
    daf7fa0
    0751244
    13.2.2
    bcaa5cf
    da6a025
    eeba565
    cc4222d
    13.2.1
    33fcfb4
    13.2.0
    18bdf5a
    fd0dc43
    fc6e42f
    e2ffc25
    36920b4
    13.1.0
    e5acdd4
    f1322b1
    f837e90
    290758b
    b62dcc6
    80d97fa
    13.0.1
    c493707
    9b3f68f
    13.0.0
    migration guide
    beta release
    5854cae
    026f4c1
    0ece313
    44de66b
    5be4cd9
    13.0.0-beta.0
    c1066c5
    177a100
    bab9eee
    d03ec1c
    3c34457
    13.0.0-alpha.1
    13.0.0-alpha.0
    12.1.3
    3eacc29
    12.1.2
    #1657
    95d5910
    12.1.1
    cee0f7c
    12.1.0
    7ebc67f
    8fa29e4
    4d4d117
    a574b7f
    918a885
    12.0.0
    9745c73
    73eae4e
    a74da7c
    916dba0
    0fc7418
    b4aa456
    c3ada74
    777e990
    5576cf9
    a7fe956
    e816428
    11.0.1
    c09fc0c
    01d493b
    ad4bddc
    11.0.0
    batching transactions
    error types
    bb6977d
    d9c6cf9
    ddcdaef
    c5b77fa
    d2a10e1
    e4b56fe
    0ba51e9
    0fdd296
    10.0.0
    5c690d2
    f6b8999
    5de05e5
    2bb494d
    2c1cf54
    8621352
    cbaac62
    f963bdb
    10.0.0-beta.1
    5c690d2
    2bb494d
    eeebbd5
    9e55b2b
    8621352
    faad530
    31aaeec
    9.0.1
    63e88ce74
    9.0.0
    456fe00
    fbf204d
    0ee9db4
    523e9bb
    831e4dd
    db6ca4c
    29d760e
    10ec2c3
    3a876bb
    8.2.1
    4001e64
    a1caa03
    8.2.0
    d5d741c
    953bf08
    798ab63
    8.1.0
    9e7c7b2
    95e0d93
    3cdc7f9
    8.0.0
    906ee0e
    8.0.0-beta.2
    0a69e49
    572d19f
    8.0.0-beta.1
    254f5a93
    59e5c9b5
    c6004bc7
    dfadac8d
    683082b3
    1d83f1a4
    eca6697b
    8ff5afe4
    9fcbeb32
    59014bd0
    985e3b96
    d34d8181
    4488b4d7
    f99d3045
    0d821614
    35d5c11a
    7b724b86
    bb7ec479
    2b410257
    3f244dfb
    be5aece7
    ed131b1b
    dfe3a05e
    ae1a5ef5
    f74ca4cb
    7b9628c2
    f81cd3a1
    6f900b98
    184566f9
    7.7.0
    #1060
    #1066
    #1056
    #1033
    #1037
    #1040
    #1043
    #1053
    7.6.0
    3f74a05
    7.5.0
    #1025
    2cb8cc2
    #1027
    a14d13a
    #1029
    #1031
    #1032
    7.4.2
    #1018
    a8b0aab
    #1021
    22c452c
    7.4.1
    #1011
    814f99b
    7.4.0
    #1007
    98b0e29
    #1006
    6b8e6fe
    7.3.1
    #996
    7.3.0
    #960
    5b6a30e
    #971
    4930635
    #991
    87b9ef9
    #992
    47179f7
    7.2.1
    7.2.0
    #921
    #936
    #933
    #939
    #937
    7.1.1
    #924
    a9d784f
    #926
    7.1.0
    #916
    #918
    #910
    Contract Event Guide
    Signature delegation guide
    #909
    6970efe
    7.0.0
    #882
    2e16e10
    #874
    43528f9
    #875
    a939395
    #863
    41b7bd1
    Add 7.0.0 migration guide
    Oracle
    AENS
    Contract
    7.0.0 migration guide
    7.0.0-next.1
    7.0.0-next.2
    7.0.0-next.3
    7.0.0-next.3
    #866
    72b073a
    #865
    7.0.0-next.2
    #848
    109b851
    #853
    #847
    75d8ad8
    #830
    6f760fb
    #849
    #852
    7.0.0-next.1
    #828
    475c2aa
    #801
    6c6177d
    #829
    b29a162
    #816
    #806
    #697
    Aepp example
    Wallet example
    #815
    dc7b4c2
    6.1.3
    4be8eb8
    6.1.2
    9ac705f
    6.1.1
    #783
    fe6021b
    #782
    c18047e
    6.1.0
    #746
    4c1f5e4
    #750
    fd14225
    #723
    c5f35d1
    #764
    07cb0e7
    #765
    5250e75
    #775
    c5f2582
    6.0.2
    6.0.1
    #730
    f7f9f17
    #728
    6.0.0
    #715
    c1854bf
    #688
    23936f5
    #632
    #653
    #658
    #660
    #680
    #693
    #687
    #714
    323ef6a
    5.0.0
    #669
    abd7c56
    #691
    0dbb2fe
    #682
    0d43804
    #671
    49fd0fd
    #692
    eded912
    5.0.0-next.1
    #647
    1ddb392
    #632
    d5f1632
    #653
    9708b43
    4.7.0
    #637
    #655
    15147af
    #662
    9d8d1e8
    4.6.0
    26beba8
    #630
    5b7eeb4
    4.5.1
    #620
    211e409
    4.5.0
    #605
    83a52fb
    #612
    21af2eb
    #604
    165cfe8
    #594
    b8c2b20
    #596
    14eaa3d
    #600
    8ad7583
    4.4.0
    #597
    9aaa05c
    227fc5c
    #577
    c38edd9
    4.3.0
    #566
    11c85eb
    #558
    33c1fd8
    #570
    #559
    #567
    8505dcf
    #577
    c38edd9
    #574
    674166c
    4.2.0
    #541
    956ed75
    #526
    48c42e4
    4.1.0
    #503
    053faae
    #498
    73552e5
    #496
    325cc90
    #505
    fb7bc00
    4.0.1
    #482
    7eb6bd8
    #480
    #479
    78cc990
    #486
    1538867
    #485
    4.0.0
    #474
    a1494fd
    #370
    #457
    d92f2c7
    #458
    3.4.1
    f951765
    3.4.0
    #432
    0700f3a
    #424
    #431
    3.3.0
    e2fec19
    #413
    46027cd
    #415
    668e7f1
    #416
    fd7b8ce
    3.2.1
    3.2.0
    #396
    b5b5c61
    #335
    e37cdfc
    #386
    e1fdce0
    #349
    0599d7d
    3.1.0
    #335
    e37cdfc
    #349
    0599d7d
    #331
    e047f3b
    #312
    9c72521
    3.0.0
    #335
    e37cdfc
    #331
    e047f3b
    #312
    9c72521
    2.4.1
    2.4.0
    2.3.2
    2.3.1
    2.3.0
    2.3.0-next
    2.2.1-next
    2.1.1-0.1.0-next
    2.1.0
    2.3.0-next
    2.2.1-next
    2.1.1-0.1.0-next
    2.1.0
    2.0.0
    1.3.2
    1.3.1
    1.3.0
    1.2.1
    1.1.2
    1.1.1
    1.1.0
    1.0.1
    1.0.0
    changed from base58check to base64check
    0.25.0-0.1.1
    0.25.0-0.1.0
    AE CLI
    AE PROJECT CLI
    0.25.0-0.1.0-next
    here
    here
    0.24.0-0.2.0
    HD Wallet
    0.24.0-0.1.0
    Node-0.24.0
    0.22.0-0.1.0-beta.1
    0.18.0-0.1.1
    0.18.0-0.1.0
    0.15.0-0.1.0
    Swagger file bug
    0.14.0-0.1.0
    0.13.0-0.1.1
    e572fae
    2cbaa7c
    2b064d8
    df2e5e3
    d556936
    cfb5f22
    #970
    8b475e0
    #897
    #768
    12aaca3
    #706
    #683
    a88042e
    #632
    #653
    #658
    #660
    #680
    #693
    #687
    #449
    const contractIns = await client.getContractInstance(contractSourceCode)
    console.log(contract)
     {
       interface: String, // Contract interface source code
       aci: String, // Contract interface json schema
       source: String, // Contract source code
       compiled: String, // Compiled contract code
       deployInfo: { address: contractAddress } // Object with deploy transaction,
       // Function
       compile: () => this, // Compile contract,
       deploy: (init = [], options = { skipArgsConvert: false }) => this, // Deploy contract (compile before if needed)
       call: (fn, params = [], options = { skipArgsConvert: false, skipTransformDecoded: false, callStatic: false } => CallRersult: Object // Call contract function
     }
    export const ADDRESS_FORMAT = {
      sophia: 1, // return address like `0xHEX_ADDRESS`
      api: 2, // return address like `ak_9LJ8ne9tks78hTD2Tp571f7w2MJmzQMRsiZxKCkMA2d2Sbrc4`
    }
    
    //
    
    export { ADDRESS_FORMAT } from 'es/account'
    await account.address(format: ADDRESS_FORMAT) // default ADDRESS_FORMAT.api
    // from
    await contract.methods.optionFn(Promise.resolve(1) || Promise.reject());
    // to
    await contract.methods.optionFn(1 || undefined);
     Exm: await client.spend(1, receiver, { onAccount: 'PUBLIC_KEY' })
     Add `onAccount` to `AENS`, `Contract`, `Oracle`.
     Add tests for using specific account to Contract, ACI, Account.
    1) Use Compiler instead of node API for encode/decode call-data and compile.
    2) Change Contract interface:
     - contractCallStatic (address, abi = 'sophia-address', name, { top, args = '()', call, options = {} } = {}) -> (source, address, name, args = [], { top, options = {} } = {}))
     - contractCall (code, abi, address, name, { args = '()', options = {}, call } = {}) -> (source, address, name, args = [], options = {})
     - contractDeploy (code, abi, { initState = '()', options = {} } = {}) -> (code, source, initState = [], options = {})
     - contractEncodeCall (code, abi, name, args, call) -> (source, name, args) // 'source' is -> Contract source code or ACI interface source
    const authContract = `YOUR_AUTH_CONTRACT`
    
    // Make current account Generalized
    await client.createGeneralizeAccount(authFnName, authContract, [...authFnArguments]
    
    // Make spend transaction using GA
    // One Way
        // encoded call data for auth contract
        const callData = 'cb_...'
        await client.spend(10000, receiverPub, { authData: { callData } })
    
    // or
        // sdk will prepare callData itself
        await client.spend(10000, receiverPub, { authData: { source: authContract, args: [...authContractArgs] } })
    const instance = await client.getContractInstance(source)
    // Deploy contract
    await.contract.init(100, 'test', options)
    //or
    await.contract.deploy([100, 'test'], options)
    // Call function
    const result = await instance.call('sum', [2, 5], options)
    //
      // Automatically decide to send tx on-chain or call-static(dry-run) base on if function stateful or not
      const result = await instance.methods.sum(2, 5, options)
      // Manually make on-chain
      const result = await instance.methods.sum.send(2, 5, options)
      // Manually make call-static
      const result = await instance.methods.sum.get(2, 5, options)
    //

    Changelog

    1.104.3 (2025-04-25)

    Bug Fixes

    • fix swapped name and symbol in aexn_contracts () ()

    (2025-04-16)

    Bug Fixes

    • make invalid aexn tokens display with invalid flag instead of just error () ()

    (2025-04-09)

    Bug Fixes

    • fix hc error when there is a fork and no total_stats records () ()

    • make tx stats async () ()

    Miscellaneous

    • update ubuntu in actions due to deprecation () ()

    (2025-04-07)

    Features

    • add holders count to stats endpoint () ()

    Bug Fixes

    • stream txs instead of fetching each in stats endpoint () ()

    (2025-03-27)

    Features

    • add ENV var to configure log file path () ()

    • add top miners for the last actual 24hs () ()

    • validate or handle scope parameter on all endpoints () ()

    Bug Fixes

    • handle names that are both inactive and in auction on names endpoint () ()

    • implement standalone /aex141/transfers for when there is no contract () ()

    • make the claims endpoint return all claims instead of just from last auction () ()

    (2025-03-11)

    Bug Fixes

    • activities crashing when there is a name created by a contract call () ()

    Miscellaneous

    • move the hyperchains into their own scope and fix message () ()

    (2025-03-05)

    Features

    • add hyperchain/config endpoint to read aeternity.yaml settings () ()

    • make docker paths the same as in the node images () ()

    Miscellaneous

    • make docker paths the same as in the node images ()

    • bump node to 7.3.0-rc5 () ()

    • remove deprecated poorly performant /by_names endpoint () ()

    • update docker OS versions to fix docker multiarch pipeline build () ()

    (2025-02-20)

    Features

    • increase the limit of the stats endpoints to 1000 () ()

    • introduce now transaction hash range scoping () ()

    Bug Fixes

    • ignore query params that start with underscore () ()

    Testing

    • update paginated test plug with new master test () ()

    Miscellaneous

    • use Phoenix with Bandit HTTP server () ()

    (2025-02-06)

    Features

    • add top miners endpoint () ()

    Bug Fixes

    • move tx fees to txs table to fix stats endpoint () ()

    Miscellaneous

    • update dialyzer to catch further errors () ()

    (2025-02-04)

    Features

    • add endpoint to get the total count of transactions for a given period () ()

    Bug Fixes

    • include DEX contract swaps contract_create_txi () ()

    • replace hc check to use the node functions () ()

    • swapped fields in transfer render function () ()

    Miscellaneous

    • pin ae_plugin to the current master by ref () ()

    • remove block v1 endpoint due to significant performance impact () ()

    (2025-01-22)

    Bug Fixes

    • fix regression by returning the v2 status endpoint () ()

    • return the correct number of transactions () ()

    Miscellaneous

    • fix test-action database dir removal () ()

    (2025-01-17)

    Features

    • add hyperchain sync support ()

    Miscellaneous

    • bump release-please version to 4 () ()

    • downgrade release please () ()

    • get rid of runtime startup warnings () ()

    (2025-01-07)

    Bug Fixes

    • adjust state_pre_transform_micro_node function on Db mod () ()

    • allow more tries for the contract nonce when retrieving events () ()

    • ignore the case where the swap event does not belong to any pair () ()

    (2024-12-19)

    Bug Fixes

    • update consensus.state_pre_transform_micro_node function () ()

    (2024-12-18)

    Features

    • validate oracles cursor () ()

    Bug Fixes

    • adjust off by one stats () ()

    • handle empty aexn count () ()

    • handle empty blockchain last_gen retrieval () ()

    • handle no stats division by zero error () ()

    Miscellaneous

    • change log lovel of log to warning from error () ()

    • fix default branch name in docker CI () ()

    (2024-12-03)

    Features

    • add debug endpoint temporarily to list swaps by txi_idx () ()

    • add gas to microblocks () ()

    Bug Fixes

    • pass extra argument to function from the node () ()

    • recalculate account active names counter () ()

    • rename aex9 transfers operation openapi docs () ()

    (2024-11-19)

    Features

    • scope statistics via scope param () ()

    Bug Fixes

    • always validate cursor deserialization, including miners () ()

    Miscellaneous

    • remove Plug.Session usage from Endpoint () ()

    (2024-11-15)

    Features

    • add active accounts stats () ()

    Bug Fixes

    • get the last key from a binary keys table () ()

    (2024-11-15)

    Bug Fixes

    • dex regression () ()

    (2024-11-13)

    Bug Fixes

    • reindex DEX swaps, now without DexCache () ()

    Miscellaneous

    • remove DEX cache, sync instead () ()

    (2024-11-11)

    Features

    • add total accounts stats () ()

    Bug Fixes

    • serialize/deserialize auction bids cursor to handle utf8 chars () ()

    Testing

    • fix integration tests () ()

    (2024-11-07)

    Bug Fixes

    • auction bid rendering issue () ()

    (2024-11-04)

    Features

    • add endpoint for account claims () ()

    • add mempool endpoint for listing pending transactions () ()

    Bug Fixes

    • adjust aex9 balance history endpoint () ()

    • remove handle_input usage from different PR () ()

    • rerun aex9 tokens contrat mint events fix () ()

    • transactions for account listing () ()

    Miscellaneous

    • fix all credo errors and avoid diffing () ()

    • remove NODE_VERSION dependancy in Dockerfile () ()

    • remove unused functions () ()

    • run all unrun migrations () ()

    (2024-10-22)

    Bug Fixes

    • add mistaken aexn transfer routes back to controller () ()

    • transfers cursor deserialization () ()

    • txs count route priority () ()

    (2024-10-17)

    Features

    • aex9 transfer statistics () ()

    Bug Fixes

    • adjust internal transfer activities structure when scoping () ()

    • call the right function on contract calls/logs endpoints () ()

    • fetch aex9 balance history using proper range structure () ()

    • make transfers endpoint work with new table fields order () ()

    Testing

    • fix failing contract test () ()

    Miscellaneous

    • add contract call index to origin () ()

    • add error description to invalid aexn contracts () ()

    • bump elixir version to 1.17 () ()

    • disable looger bloat in the tests () ()

    (2024-10-07)

    Features

    • add claims count on names/auctions () ()

    • add contracts count stats endpoint () ()

    Bug Fixes

    • add empty chain key-blocks validation () ()

    Miscellaneous

    • make dev container retain bash and iex history, updated logger () ()

    (2024-09-23)

    Features

    • add minutes per block in stats () ()

    • sort aexn transfers by txi_idx () ()

    Bug Fixes

    • activities cursor for gen streams () ()

    • contemplate case sensitivity when looking for names () ()

    Testing

    • adjust new aexn transfers format on activities test () ()

    Miscellaneous

    • add default padding to base64 oracles response/queries () ()

    • remove deprecated 2023 migrations () ()

    • remove v1 unused routes () ()

    (2024-09-12)

    Features

    • include metadata and owner on aex141 token request () ()

    • make auctions endpoints use name and hash () ()

    Bug Fixes

    • aexn transfer activities () ()

    • missing delta stat entry for last key block () ()

    • move console log config outside of json logs if () ()

    • repopulate dex swaps () ()

    Miscellaneous

    • publish ARM images to dockerhub () ()

    Testing

    • fix randomly failing transfers tests () ()

    (2024-09-02)

    Features

    • add support for handling WAE contracts as special AEx9 ones () ()

    (2024-09-02)

    Features

    • Add block dificulty stat () ()

    • add hashrate stats endpoint () ()

    Bug Fixes

    • dex contract swaps () ()

    Miscellaneous

    • add generation of key boundaries () ()

    • make lima files not required () ()

    (2024-08-26)

    Features

    • add beneficiary reward to key block response () ()

    • add block height to aex141 () ()

    • add node schemas to swagger definitions for mdw () ()

    • handle dex swaps scoping () ()

    Bug Fixes

    • activities pagination () ()

    • inconsistent micro time naming () ()

    • new stats paths in openapi () ()

    • specify right aex9 contract to count aex9 logs () ()

    Miscellaneous

    • structure oracle response as base64 () ()

    (2024-08-13)

    Features

    • add ability to roll back database on dev env () ()

    • add amount and name to activities info () ()

    • add dex action field () ()

    • add openapi missing stats route () ()

    Bug Fixes

    • handle invalid unix dates in filter () ()

    • oracles v3 endpoint was returning v2 data () ()

    Miscellaneous

    • fetch aexn tokens on render only () ()

    • redefine node module functions directly and avoid SmartGlobal () ()

    • rename statistics to stats to remain consistent () ()

    • sort DEX swaps by creation instead of contract creation () ()

    (2024-07-25)

    Bug Fixes

    • filter aex9 balances by amount correctly () ()

    • take max expiration between extension and prev expiration () ()

    Miscellaneous

    • remove overwrite of network_id and use values from aeternity.yaml () ()

    (2024-07-24)

    Bug Fixes

    • calculate auction expiration correctly when extension present () ()

    • rename aex141 token path to conform to the others () ()

    (2024-07-22)

    Features

    • make aexn prefix search case insensitive () ()

    Bug Fixes

    • correct url in openapi specs () ()

    • dex swaps retrieval () ()

    • use same format for pointers as the node () ()

    Testing

    • simplify intermittent name count test () ()

    Miscellaneous

    • add MIX_ENV=prod when building for SDK usage () ()

    (2024-07-10)

    Features

    • add endpoint to get names count () ()

    • add v3 for websockets () ()

    • additional fields to dex endpoints () ()

    • update node to 7.1.0 () ()

    Bug Fixes

    • add missing mutations in profile sync () ()

    • handle parent contract DEX swaps () ()

    Miscellaneous

    • add MIX_ENV=dev on docker-compose-dev () ()

    (2024-06-28)

    Features

    • add oracle extends endpoint on v3 () ()

    Bug Fixes

    • ignore nil mutations in sync server () ()

    (2024-06-25)

    Features

    • add flag to disable ipv6 () ()

    Bug Fixes

    • use the correct structure for mutations when syncing () ()

    (2024-06-19)

    Bug Fixes

    • remove destructuring of gen_mutations for mem mutations () ()

    (2024-06-19)

    Features

    • add contract calls/logs nested routes () ()

    • add creation time and block hash to nft () ()

    • mark aex9 as invalid () ()

    • more explicit dex amount representation () ()

    Bug Fixes

    • include opt_txi_idx when rendering transfers cursor too () ()

    • retrieve pair from external contract when external log () ()

    Testing

    • randmly failing tests and warnings () ()

    Miscellaneous

    • make the wealth rank task work with the database instead of AsyncStore and ets () ()

    • move aexn tokens rendering to contract modules () ()

    • restructure DEX endpoints () ()

    • task for generating migrations () ()

    (2024-06-05)

    Bug Fixes

    • rename 20240528120000_sync_account_balances.ex to 20240528120001_sync_account_balances.ex () ()

    (2024-06-05)

    Bug Fixes

    • aexn openapi schemas () ()

    • handle transfers txi_idx ref tuple () ()

    • reorder the PairCreated arguments for DEX events () ()

    (2024-05-29)

    Bug Fixes

    • rename migration file so it runs again () ()

    • update aex141 and names swagger () ()

    (2024-05-27)

    Bug Fixes

    • chunk dex_swaps migration and fix pattern match () ()

    • rename migrations () ()

    (2024-05-27)

    Bug Fixes

    • create migration to sync account balances () ()

    (2024-05-27)

    Features

    • add new name pointees endpoint to v3 () ()

    Bug Fixes

    • create RevTransfer on aex9 minting () ()

    (2024-05-21)

    Features

    • add aex141 contract transfers to v3 api () ()

    • add route for dex swaps by contract_id () ()

    • allow filtering names by prefix (case-insenstive) () ()

    • dex new swaps table () ()

    Bug Fixes

    • arm docker incompatibility () ()

    • handle empty transactions count () ()

    • make all operationIds in swagger_v3 PascalCase () ()

    Miscellaneous

    • update credo to get rid of warnings () ()

    • update openapi schema () ()

    (2024-05-01)

    Features

    • add average of transaction fees for last 24 hours with trend () ()

    • add openapi schema for dex controller () ()

    Bug Fixes

    • extend auctions only if the extension is longer that the timeout () ()

    • handle not found auction bids () ()

    Miscellaneous

    • bump otp version () ()

    • bump version to 7.0.0 () ()

    (2024-04-24)

    Bug Fixes

    • add int-as-string on pagination next/prev urls () ()

    • extend auction properly () ()

    (2024-04-23)

    Miscellaneous

    • update node to 7.0.0-rc1 () ()

    (2024-04-23)

    Miscellaneous

    • update node to version 6.13 () ()

    (2024-04-22)

    Bug Fixes

    • add support for paying_for txs on contract calls migration () ()

    (2024-04-18)

    Features

    • add reverted calls migration to update fun/args () ()

    Bug Fixes

    • remove hardcoded node log level in favor of aeternity.yaml config () ()

    • store function name for reverted contract calls () ()

    (2024-04-15)

    Features

    • add raw data pointers support for ceres () ()

    • include 0 count statistics throughout the network lifespan () ()

    • resolve aens name to contract address when calling contract () ()

    Bug Fixes

    • move transactions count to v3 properly () ()

    • update names and oracles to v3 () ()

    • use tx hash instead of index in v3 api version () ()

    Miscellaneous

    • remove schemes from swagger v1 file () ()

    (2024-04-02)

    Bug Fixes

    • avoid converting to atom on runtime metrics formatter () ()

    Testing

    • change tests using nonexisting column () ()

    (2024-03-29)

    Features

    • add config to allow logging to console () ()

    • allow none logger level configuration () ()

    • render name_fee on names/auctions () ()

    Bug Fixes

    • docker logs mount bad permissions () ()

    • include local-idx cursor when paginating tx call activities () ()

    • randomly failing tests () ()

    • telemetry error when application starts () ()

    Miscellaneous

    • add credo checks on config files too () ()

    (2024-03-19)

    Features

    • allow getting block-specific AEx9 balances () ()

    • allow logger level configuration () ()

    Bug Fixes

    • allow same creation block to be used on by-hash aex9 balances () ()

    • handle invalid hashes error () ()

    • use endpoint-specific ordering validation () ()

    Miscellaneous

    • add logs message on deprecated routes () ()

    • restructure v3 routes and remove tx_index () ()

    (2024-03-06)

    Features

    • add remaining v3 routes without the ones deprecated () ()

    • allow encoding ints as strings via query parameter () ()

    Bug Fixes

    • process HC seed contracts with the correct format () ()

    • return 404 when contract is not found () ()

    (2024-02-26)

    Bug Fixes

    • logging revoked name on sped () ()

    (2024-02-26)

    Features

    • add v3 name and auction detail endpoint () ()

    • include 48hs transactions count trend on stats () ()

    Bug Fixes

    • restructure aex141 activities meta_info match () ()

    • skip node call on empty db () ()

    • sync spend with revoked name () ()

    (2024-02-08)

    Miscellaneous

    • migrate dex swap tokens () ()

    • update swagger.json schemes value () ()

    (2024-02-02)

    Bug Fixes

    • handle heavy endpoint timeout () ()

    • ignore 0-gen db for name stats () ()

    • include all auction claims when closing up an auction () ()

    (2023-12-28)

    Features

    • index and fetch dex swap tokens () ()

    Bug Fixes

    • pick starting transaction from 24hs ago for counting () ()

    Miscellaneous

    • index name statistics using key blocks () ()

    (2023-12-20)

    Features

    • add names approximate time on expire/activation () ()

    Bug Fixes

    • always return state on contract logs write () ()

    • check return_type instead of ret_value for errors () ()

    • handle micro-block cursor properly () ()

    Miscellaneous

    • add cache manifest building on docker build () ()

    (2023-12-13)

    Miscellaneous

    • update node version to most recent 6.12.0 () ()

    (2023-11-27)

    Bug Fixes

    • use last gen status regardless of transaction index () ()

    Miscellaneous

    • generalize json/view rendering () ()

    (2023-11-23)

    Bug Fixes

    • fetch previous names before rendering them () ()

    (2023-11-12)

    Bug Fixes

    • ignore errored contract calls fun_arg_res when syncing () ()

    (2023-11-09)

    Features

    • add last 24 hours transactions count () ()

    • add name activation statistics () ()

    • track dex pair creations () ()

    Miscellaneous

    • add syncing queue for async syncing requirements () ()

    • filter all aex9 contract account transfers () ()

    • make names restructuring migration async () ()

    • unify pagination returns and cursor serialization () ()

    (2023-10-12)

    Features

    • add statistics date filtering () ()

    Bug Fixes

    • check contract creation for child contracts () ()

    • update holders and contract balance on init () ()

    Miscellaneous

    • add open auction bids to name history () ()

    • index aex9 mint and burn as transfer () ()

    • move previous names into separate table () ()

    • offloads app startup by async keys loading () ()

    (2023-09-18)

    Features

    • count microblock txs () ()

    • index and query aex9 transfers by contract and account () ()

    • sort aexn contracts by creation () ()

    Bug Fixes

    • display only the current auction bids for a name () ()

    • enable 1000 limit on block statistics endpoint () ()

    Miscellaneous

    • add aexn_type to contract txs () ()

    • add functional error responses and tests cases for it () ()

    • ensure suffix on name history () ()

    • reverse call logs () ()

    (2023-09-06)

    Features

    • add approximate_auction_end_time to auctions () ()

    Bug Fixes

    • render sext encoded log () ()

    Miscellaneous

    • add allowance and approval events () ()

    • enable V3 routes for all envs () ()

    • upgrade to node 6.11 () ()

    (2023-08-30)

    Bug Fixes

    • handle aex141 templates without tokens count () ()

    (2023-08-27)

    Miscellaneous

    • add contract_id to create internal calls () ()

    (2023-08-25)

    Bug Fixes

    • match entity using nft collection and token id () ()

    (2023-08-25)

    Miscellaneous

    • enable nft marketplaces tracking () ()

    (2023-08-25)

    Miscellaneous

    • count holders based on events () ()

    (2023-08-24)

    Features

    • add block statistics endpoint () ()

    • enable async migrations () ()

    Bug Fixes

    • use inner tx type to render contract creation () ()

    Miscellaneous

    • prepare wealth to be updated on block basis () ()

    (2023-08-23)

    Features

    • query active entities (e.g auctions) () ()

    (2023-08-22)

    Features

    • include aexn meta info on aexn activties () ()

    Bug Fixes

    • index entrypoints with proper cursor () ()

    • load aex141 contract for aex141 activities () ()

    Miscellaneous

    • remove dup mgiration since it takes too long for testnet () ()

    • unify convert_params usage into util function () ()

    • use extracted tx mod and name () ()

    (2023-08-18)

    Miscellaneous

    • return bad request for input exceptions () ()

    (2023-08-18)

    Features

    • add name history endpoint () ()

    Bug Fixes

    • expire memory stores based on v1 heavy endpoints () ()

    • fix some readme typos () ()

    • ignore field/transaction counts when they are duplicated in the transaction () ()

    • return db state after broadcasting () ()

    Testing

    • isolate async test cases () ()

    Miscellaneous

    • count object keys only from memory () ()

    • remove old mocked websocket tests () ()

    • use functional single item pipe () ()

    (2023-08-14)

    Features

    • add drop tables config () ()

    • add statistics and /statistics/transactions endpoint () ()

    • add week/month interval filter on statistics () ()

    Bug Fixes

    • dedup txs activities when present on several fields () ()

    • fix auction bids expiring index () ()

    • put revoked name key for counting () ()

    • use map for DeleteKeysMutation () ()

    Refactorings

    • remove name cache () ()

    Miscellaneous

    • add aexn type to contracts response () ()

    • add healthcheck on all swagger v2 endoints () ()

    • count names and oracles from keys () ()

    • fetch only oracles tree () ()

    (2023-08-07)

    Bug Fixes

    • increase timeout of call affected by migration () ()

    (2023-08-07)

    Miscellaneous

    • add v2 yaml file back to the static directory () ()

    • disable cache for DB block mutations () ()

    • get block height finding the header () ()

    • use aexn extensions from byte code () ()

    (2023-08-03)

    Features

    • include last tx hash on delta/total stats () ()

    • index Hyperchains seed contracts () ()

    Bug Fixes

    • filter oracle by state param () ()

    • handle empty stats () ()

    • restructure pattern-match for decode_call_result () ()

    Miscellaneous

    • log and reindex aexn () ()

    • remove all consistency credo warnings () ()

    (2023-07-28)

    Features

    • add auction-only claims v3 endpoint () ()

    • detect AEX-n meta info () ()

    • filter owned nfts by collection () ()

    • nft metadata endpoint () ()

    Bug Fixes

    • allow using hyphen on name cursors () (), closes

    • rename AuctionBidBid to BidClaim () ()

    Refactorings

    • create map or list directly () ()

    Miscellaneous

    • allow nft owner call for hackaton contracts () ()

    (2023-07-24)

    Bug Fixes

    • add missing fname contract creation call () ()

    Miscellaneous

    • deps: bump node-fetch from 2.6.1 to 2.6.7 in /node_sdk () ()

    • deps: bump semver from 6.3.0 to 6.3.1 in /node_sdk () ()

    • move nested name records to individual tables () ()

    Testing

    • add devmode test for Chain.clone calls () ()

    (2023-07-18)

    Features

    • add v3 initial endpoints for names/auctions () ()

    Testing

    • rewrite some mem tests with store () ()

    (2023-07-12)

    Bug Fixes

    • only bootstrap accounts for configured hardforks () ()

    Testing

    • leave controller tests to coverage () ()

    Miscellaneous

    • compact type increment counts mutations into a single one () ()

    • encode event logs within a single migration () ()

    • keep cache after switching from db to mem commit () ()

    • use builtin term to binary for values () ()

    (2023-07-07)

    Miscellaneous

    • log mem and db sync profiling () ()

    (2023-07-06)

    Features

    • add further block times to different endpoints () ()

    (2023-07-05)

    Features

    • add channels last updated time () ()

    Refactorings

    • use same get code logic from node () ()

    Testing

    • add async: false to all test that mock modules () ()

    Miscellaneous

    • stream generations mutations () ()

    (2023-06-30)

    Features

    • add block_time to all activities () ()

    • add micro block time to oracle nested resources () ()

    • add support for swagger using JSON format () ()

    • cache mem sync mutations () ()

    Bug Fixes

    • create contract call event tx when Chain events () ()

    Testing

    • add devmode Contract.create call test () ()

    Miscellaneous

    • add decimals to account balances () ()

    • add migration for entrypoint () ()

    • add mix files to credo checks () ()

    • include credo and leave test for dev shell () ()

    (2023-06-19)

    Features

    • add approximate_expiration_time to names () ()

    Bug Fixes

    • consider all oracles expirations () ()

    • include aexn contracts with special chars () ()

    • run aex9 count migration () ()

    Testing

    • add async:false to more test modules () ()

    • fix intermittent test failures due to async mocking () ()

    • integrate devmode and SDK for custom test txs () ()

    (2023-06-13)

    Bug Fixes

    • return txs count after cache () ()

    (2023-06-13)

    Features

    • add approximate_expiration_time to oracles () ()

    Miscellaneous

    • add transactions count to websocket keyblock () ()

    • count only aexn contracts with valid meta info () ()

    (2023-06-08)

    Bug Fixes

    • remove circular rendering on Oracles.render_query/2 () ()

    Miscellaneous

    • add function parameter alias to contract logs () ()

    Testing

    • remove mock from contracts sync () ()

    (2023-05-31)

    Features

    • add support for node 6.8.1 back () ()

    • add target to ws object msg () ()

    • allow filtering channels by active/inactive () ()

    • include inactive channels on channels listing () ()

    Bug Fixes

    • adjust printed unit on store_account_balance log () ()

    Miscellaneous

    • apply Node persist config () ()

    • track internal calls for wealth () ()

    • use count id by type also on /count () ()

    (2023-05-29)

    Bug Fixes

    • rename OracleQueries migration to run after ContractLogs () ()

    (2023-05-25)

    Features

    • add counters to ws block broadcast () ()

    • encode custom event args () ()

    • filter internal calls by contract and function () ()

    • include oracle responses on oracle queries endpoints () ()

    Bug Fixes

    • handle old oracle responses when migrating int transfers () ()

    • reindex reward_oracle int transfers () ()

    • rename OracleResponses migration table () ()

    Miscellaneous

    • increase inactivity timeout () ()

    • let docket volumes be optional () ()

    • revert "chore: update node to 6.8.1 ()" () ()

    • update node to 6.8.1 () ()

    (2023-05-15)

    Features

    • filter logs by contract and event () ()

    Miscellaneous

    • rename update_type_count file to match module () ()

    (2023-05-11)

    Miscellaneous

    • check if record exists on delete keys mutation () ()

    (2023-05-11)

    Miscellaneous

    • clear done in memory async tasks () ()

    (2023-05-08)

    Bug Fixes

    • update account balance () ()

    Miscellaneous

    • prune wealth migration () ()

    (2023-05-04)

    Bug Fixes

    • delete async task if block is not found () ()

    (2023-05-03)

    Bug Fixes

    • delete inactive name owner deactivation records when activated () ()

    • set correct node module for channel withdraw () ()

    (2023-05-03)

    Bug Fixes

    • set proper migrations path on mix release () ()

    (2023-05-02)

    Miscellaneous

    • show last applied migration () ()

    (2023-05-02)

    Features

    • add channels updates nested endpoint () ()

    • sort aex9 balance per amount () ()

    Bug Fixes

    • consider existing oracles on inactive ones count () ()

    Refactorings

    • commit migration instead of direct db write () ()

    (2023-04-24)

    Features

    • add contracts detail page () ()

    • wealth endpoint () ()

    Bug Fixes

    • adapt activities to new int transfers format () ()

    (2023-04-18)

    Features

    • add /contracts endpoint to list contracts () ()

    • track aex9 contract supplies () ()

    • track aex9 logs count () ()

    • track aex9 token holders count per contract () ()

    Bug Fixes

    • adjust the order for contract call event mutations () ()

    Miscellaneous

    • update aex9 response with holders () ()

    (2023-04-05)

    Features

    • add /oracles/:id/responses nested endpoint () ()

    • aexn contracts count endpoints () ()

    • display int transfers source tx () ()

    Bug Fixes

    • add lima contracts amount minted to supply () ()

    Miscellaneous

    • fix credo refactor errors () ()

    • remove unused tx sync cache () ()

    • sum account mintings by network () ()

    (2023-03-29)

    Features

    • add /oracles/:id/queries to list an oracle queries () ()

    • count id txs by type or type group () ()

    • filter inner txs fields with ga_meta type () ()

    Miscellaneous

    • ignore oracle responses that don't have associated query () ()

    • precompute tx ids () ()

    (2023-03-20)

    Bug Fixes

    • count total pending async tasks from db () ()

    • handle return type for failed GAMeta txs as well () ()

    • remove name logs () ()

    Miscellaneous

    • limit ws subscriptions () ()

    • remove LoggerJSON backend from test env () ()

    Testing

    • add unit tests to Db.Channel module () ()

    • add unit tests to tx controller and context () ()

    (2023-03-10)

    Bug Fixes

    • add base case for txs from gen () ()

    • ignore failed ga_meta_tx sync processing () ()

    • revert git change to allow dev build () ()

    • set config to serve endpoints on prod () ()

    Miscellaneous

    • aggregate request metric per route () ()

    • allow mounting db dir with docker () ()

    • make web config runtime config () ()

    • set docker user to aeternity () ()

    (2023-02-28)

    Miscellaneous

    • avoid deleting oracle queries for later use of them () ()

    • remove oracle query response check () ()

    (2023-02-28)

    Miscellaneous

    • add fallback for contracts endpoints () ()

    (2023-02-27)

    Bug Fixes

    • use top height hash for aex9 account balances () ()

    Testing

    • add coverage for name auction endpoint () ()

    (2023-02-23)

    Features

    • add template token edition () ()

    • allow filtering activities by type () ()

    • encode args using types for AEX-N events () ()

    Bug Fixes

    • add address to Burn event () ()

    • ignore all nft events with args mismatch () ()

    • set proper release node to reopen mnesia () ()

    Miscellaneous

    • cleanup field parser module () ()

    • remove console info log for dev environment () ()

    • remove no longer needed oracle queries nonce fix () ()

    • skip dev and miners rewards for HC () ()

    CI / CD

    • publish images with prod () ()

    (2023-02-10)

    Features

    • specialize ws subscription by source () ()

    Bug Fixes

    • encode txs 404 address properly () ()

    Testing

    • add activities integration tests for the new activity types () ()

    Miscellaneous

    • add handling for previous update format () ()

    • let aeternity.yaml be used by default () ()

    (2023-02-07)

    Bug Fixes

    • handle other call not found cases () ()

    (2023-02-07)

    Features

    • add optional json logger () ()

    • allow filtering by prefix and scoping contract calls () ()

    Bug Fixes

    • allow retrieving the latest txs by hash () ()

    • encode blocks on the /v2/blocks endpoint using formatter () ()

    • handle call not found () ()

    • set hostname as default telemetry host () ()

    Testing

    • update websocket integration tests () ()

    Refactorings

    • fetch txs subscribers once () ()

    • removed unused block cache () ()

    Miscellaneous

    • add NODE_URL docker build argument () ()

    • allow aex9 account balance at a block hash () ()

    • remove priv volume for prod () ()

    • use only Jason library () ()

    (2023-01-30)

    Features

    • add metrics observability () ()

    • monitor error 500 () ()

    Bug Fixes

    • adapt claim actvities to use the new txi_idx stored format () ()

    • fix bugs found through integration tests () ()

    • look for pointee also on previous name record () ()

    • use proper names for transaction types for events and transactions () ()

    Refactorings

    • remove duplicated v2 ws enqueuing () ()

    Miscellaneous

    • add MIX_ENV=test for being able to run tests () ()

    • add support for channels local index reference () ()

    • cleanup dialyzer warning and util module () ()

    • fix some of dialyzer overspec errors () ()

    (2023-01-18)

    Bug Fixes

    • allow cursors with names with dashes on them on pagination () ()

    Refactorings

    • enqueue a block only once to ws broadcasting () ()

    (2023-01-16)

    Features

    • update node to version 6.7.0 () ()

    Bug Fixes

    • skip importing hardfork accounts for custom networks () ()

    (2023-01-13)

    Features

    • add channel participants to channel txs () ()

    Bug Fixes

    • formats call return composed by tuple value () ()

    (2023-01-12)

    Bug Fixes

    • ignore gen-based internal transfers for txi indexed activities () ()

    Testing

    • improve aex9 dex coverage () ()

    Miscellaneous

    • ci: always enable semver tags () ()

    (2023-01-11)

    Features

    • add offchain rounds to channel transactions () ()

    • allow filtering activities by ownership only () ()

    • render inner tx details () ()

    Miscellaneous

    • ci: use custom token instead of default () ()

    • cleanup library dependencies () ()

    • remove migrations since scratch sync needed for 1.34 () ()

    • remove unused code () ()

    (2023-01-04)

    Features

    • add block hash to activities () ()

    • include source tx_hash on nested names endpoints () ()

    • introduce {bi, {txi, local_idx}} for precise internal txs refs () ()

    • query channel reserve at a hash () ()

    Miscellaneous

    • ci: conditional dockerhub build env () ()

    • ci: make sure workflow is triggered on push () ()

    • remove tx hashes handling on int contract calls () ()

    • use master instead of latest to pull docker image (

    (2022-12-23)

    Features

    • add node details to channel page () ()

    • add v2 websocket implementation () ()

    • format aexn activities same as aexn transfers endpoints () ()

    • return event name when it is aexn () ()

    Bug Fixes

    • handle inner name_update pointers () ()

    • name of sender parameter of get_aex9_pair_transfers () ()

    • remove dockerization from ci tests run () ()

    • remove extra colon before in path parameter name () ()

    CI / CD

    • enable docker image tests () ()

    • publish only tagged images (w/o tests) () ()

    Miscellaneous

    • add migration and update docs for nft templates () ()

    • add proper typing to sync transaction nested function calls () ()

    • add typespecs to all Db.Model records () ()

    • add union of model-specific State typespecs () ()

    (2022-12-09)

    Features

    • add /v2/channels/:id detail page () ()

    • use aex9 event-based balance () ()

    Testing

    • ensure proper model declaration () ()

    CI / CD

    • automatically publish docker images () ()

    Miscellaneous

    • allow network id for local environment () ()

    • index only event-based aex9 balances () ()

    (2022-12-02)

    Features

    • add aex9 presence after event () ()

    • add auth function name to ga_attach () ()

    • add name /transfers and /updates paginated endpoints () ()

    • handle nft template edition limit () ()

    Refactorings

    • get immediately returned nft extensions () ()

    Testing

    • use strict version on otp ci () ()

    • validate kbi range with blockchainsim () ()

    Miscellaneous

    • add template limit details to edition () ()

    (2022-11-28)

    Features

    • add /names/:id/claims endpoint () ()

    • handle nft contract limits () ()

    Bug Fixes

    • adjust git revision digits to allow variable length () ()

    • encode non-string contract log data () ()

    • update async tasks db count on save () ()

    Testing

    • validate multiple and remote aexn transfers () ()

    Refactorings

    • move ws subscription to specific module () ()

    Miscellaneous

    • add node version argument to docker builds ()

    • handle dry run timeout () ()

    • remove unnecessary smart_record dependency () ()

    • remove unused migrations () ()

    (2022-11-17)

    Bug Fixes

    • avoid double aex9 event balance update () ()

    • handle account_pubkey recipient pointee ()

    Miscellaneous

    • divide swagger v2 docs into separate resource files () ()

    (2022-11-14)

    Features

    • add name claims to the activities retrieved by name hash () ()

    • add oracle query expiration internal refund transfers () ()

    • display name buyer from inner claim tx () ()

    Bug Fixes

    • ignore oracle queries that do not have the right calculated nonce () ()

    • render binary pointer key on name related endpoints () ()

    • scope contract calls filtered by function properly () ()

    • use last call txi for hash account balance () ()

    Miscellaneous

    • allow /txs/count to be filtered by tx_type () ()

    • use built-in phoenix websocket () ()

    (2022-11-06)

    Bug Fixes

    • reintroduce nft_template model () ()

    (2022-11-04)

    Features

    • add response_id to channel settle rendering () ()

    • index nft templates () ()

    Bug Fixes

    • handle non-existing mbs txs endpoint response () ()

    • recalculate internal oracle query tx nonces () ()

    • render all pointers on names endpoint () ()

    (2022-11-02)

    Features

    • update aex9 balance based on events () ()

    Bug Fixes

    • consider name updates and transfers for NameOwnerDeactivations () ()

    • events from the node are obtained in reverse order () ()

    • render list of keyword lists args () ()

    Testing

    • complement coverage for name syncing () ()

    • complement coverage for oracle syncing () ()

    (2022-10-24)

    Features

    • allow filtering names by owner/state ordered by deactivation () ()

    • handle burn nft () ()

    • render call details for ga_attach and ga_meta () ()

    Bug Fixes

    • increment ga contract stat only on success () ()

    Miscellaneous

    • add return_type for ga_attach_tx () ()

    • remove txi scoping support for new endpoints () ()

    (2022-10-17)

    Bug Fixes

    • handle any meta info value () ()

    (2022-10-17)

    Features

    • add tx internal transfers to activities () ()

    Bug Fixes

    • render bid for names in auction () ()

    Miscellaneous

    • add return type for ga_meta_tx () ()

    (2022-10-12)

    Features

    • add generation-only internal transfers to activities () ()

    Bug Fixes

    • always return txs from last microblock ()

    • index remote log also with called contract () ()

    • order gen-scoped txs and activities properly () ()

    • return original error messages on txs invalid requests () ()

    Testing

    • use always valid contract for invalid range test () ()

    Miscellaneous

    • update aex141 signatures () ()

    (2022-10-10)

    Miscellaneous

    • allow rendering static swagger.json (temporary fix) () ()

    (2022-10-07)

    Bug Fixes

    • allow sorting backward when gen first-last is the same ()

    • handle other node tx locations () ()

    • return {auction_bid, source} tuple on names owned_by_reply () ()

    (2022-10-05)

    Features

    • index oracle extend internal calls () ()

    Bug Fixes

    • add missing origin to oracle created by internal call () ()

    • return proper error when aex141 token is a partial int () ()

    • set proper auction_timeout on names () ()

    • transform non encodable binary oracle fields into list () ()

    Refactorings

    • move Db.Name syncing code to Sync.Name () ()

    • print migrations total/duration using returned values () ()

    (2022-09-29)

    Features

    • add aexn transfer activities () ()

    Bug Fixes

    • consider last txs when calculating mb tx count () ()

    Testing

    • add cases websocket broadcasting () ()

    Miscellaneous

    • improve dialyzer warnings to catch unmatched results () ()

    • upgrade phoenix and other deps () ()

    (2022-09-26)

    Miscellaneous

    • bump erlang to OTP 23 and elixir to 1.11 () ()

    • cleanup tests warnings () ()

    (2022-09-26)

    Features

    • add /accounts/:id/activities endpoint () ()

    • include internal transactions as activities () ()

    Refactorings

    • allocate smaller tuples for query streams () ()

    Miscellaneous

    • remove phoenix_swagger () ()

    (2022-09-14)

    Features

    • add /key-blocks endpoints with txs/mbs count () ()

    • add /key-blocks/:hash_or_kbi endpoint with mbs/txs count () ()

    • add /key-blocks/:hash_or_kbi/micro-blocks endpoint () ()

    • add /v2/micro-blocks/:hash endpoint () ()

    Miscellaneous

    • accept contract param besides contract_id () ()

    • disable phoenix code_reloader by default () ()

    (2022-09-05)

    Bug Fixes

    • map recipient record when filtering by nft collection () ()

    (2022-09-01)

    Features

    • generalize transfer history for aex141 () ()

    • index miners count and total rewards from fees () ()

    • index nft transfers by collection () ()

    Bug Fixes

    • calculate prev on build_gen_pagination correctly () ()

    • convert transfer event token_id to integer () ()

    • handle out_of_gas_error on aex141 cleanup () ()

    • handle variant owner return () ()

    Refactorings

    • add type definitions to Model records () ()

    Miscellaneous

    • add micro_blocks to /v2/blocks/{height} () ()

    • update aex141 metadata signature () ()

    Testing

    • add cases for rocksdb multiple dirty delete calls () ()

    • update oracle and aex9 integration tests () ()

    (2022-08-23)

    Features

    • log open/closed channels together with their locked AE () ()

    Bug Fixes

    • check for nil before encoding contract pks () ()

    • filter contracts after account balance dry-run on blockhash () ()

    • query aexn by exact name or symbol on v1 and v2 () ()

    • use block_index on v1 aex9 height balances () ()

    Miscellaneous

    • add progress indicator on name fees migration () ()

    • set dry run gas upper limit () ()

    • sorts aex9 account balances from last to first () ()

    Testing

    • complement to missing unit tests for AEX-141 () ()

    • skip creating a store on integration tests () ()

    • update hardfork accounts integration case () ()

    • update integration test regardin aex9 missing presence () ()

    (2022-08-18)

    Features

    • add txs per second stat on /stats () ()

    • complement to migrated tokens () ()

    • expose names locked/burned fees on stats () ()

    • synchronize async tasks write () ()

    Bug Fixes

    • decrease async task producer dequeue time () ()

    • dequeue async tasks non-preemptively () ()

    • handle dry-run error when contract is not present () ()

    • increase auctions started stat only once () ()

    Miscellaneous

    • adapt to AEX-141 standard change () ()

    Refactorings

    • decrease consumer async server wait and sleep () ()

    (2022-08-03)

    Bug Fixes

    • include ga_attach_tx when counting contracts () ()

    • include tx-type-specific data inside "tx" attribute () ()

    • send duplicated tx websocekt message if sources differ () ()

    • update stats caching condition to only do it once per kb () ()

    Miscellaneous

    • add typing and credo fixes to ets module () ()

    (2022-08-01)

    Features

    • imports hardforks preset accounts () ()

    Bug Fixes

    • broadcast in-memory blocks () ()

    Miscellaneous

    • remove unused supervisor () ()

    • remove unusued Sync.Server gens_per_min field () ()

    (2022-07-27)

    Features

    • add new store kind to serve async tasks () ()

    • add new type count index for /txs/count?type=x () ()

    • allow filtering transactions count by scope () ()

    • display tx hash instead of txi when tx_hash=true () ()

    Bug Fixes

    • adjust inactive name owner table () ()

    • avoid dirty reads when using iterator () ()

    • avoid erasing mem state when State.commit/2 () ()

    • avoid returning results from other tables on AsyncStore.next/prev () ()

    Refactorings

    • extract expand/top params into the PaginationPlug () ()

    • move formatting to main render functions () ()

    • save only the used txi on aex9 presence () ()

    Testing

    • add helper with_state/2 function for declarative tests () ()

    • add name sync tests for more scenarios () ()

    • assert decimal is nil on out_of_gas_error () ()

    • fix random non-deterministic test failures () ()

    Miscellaneous

    • add aex9 validation to v1 hash endpoints () ()

    • add aex9 validation to v1 range endpoints () ()

    • add mistakenly removed async in-mem tasks () ()

    • clear state hash for every key block () ()

    (2022-06-29)

    Features

    • add nft holder endpoints () ()

    Bug Fixes

    • use block/hash param on account balances () ()

    • verify if task was concurrently deleted () ()

    (2022-06-27)

    Bug Fixes

    • dedup aex9 presence () ()

    (2022-06-23)

    Features

    • truncate aexn name and symbol sorting fields () ()

    Bug Fixes

    • add swagger files in docker image build ()

    • truncate aexn cursor ()

    Miscellaneous

    • add truncate metainfo migration () ()

    (2022-06-20)

    Features

    • include tx_hash when listing AEx9 transfers () ()

    (2022-06-14)

    Bug Fixes

    • handle names search endpoint when no prefix () (), closes

    • use valid name auction route as specified in docs () ()

    Miscellaneous

    • enable credo and remove unused code () ()

    • reduce gas limit to Node base gas () ()

    (2022-06-10)

    Features

    • add endpoints to list aex141/nft contracts () ()

    • save and display aexn extensions () ()

    • set low gas limit according to Node base gas () ()

    Bug Fixes

    • display unencoded block hash when not found () ()

    Testing

    • fix name/stats integration tests () ()

    Refactorings

    • add StatePlug to deal with endpoint responses () ()

    • generalize aexn create contract mutation () ()

    (2022-06-01)

    Bug Fixes

    • handle update aex9 state on contract create logs () ()

    • retrieve block hash for name ptr_resolve from state () ()

    Miscellaneous

    • add independent static swagger v1 and v2 files () ()

    (2022-05-27)

    Features

    • update aex9 state with logs () ()

    Bug Fixes

    • include ga_attach_tx when trying to find call origins () (), closes

    Refactorings

    • invalidate aexn contract () ()

    • replace aex9 sync cache with non deduped params () ()

    (2022-05-23)

    Bug Fixes

    • update v1 auction bids structure in Format module () ()

    • use correct key format for listing name owner tables () ()

    Miscellaneous

    • revert swagger name operation names () (), closes

    (2022-05-18)

    Bug Fixes

    • fetch key hash using aec_chain on update_aex9_presence () ()

    • handle /tx/:hash endpoint when tx doesn't exist () ()

    • handle aex9_controller errors with FallbackController () ()

    • handle prev/next when key_boundary is nil () ()

    Refactorings

    • dirty reads + add Store abstraction () ()

    • generalize aex9 meta info with aexn contract () ()

    • generalize fetch aexn tokens () ()

    • move aex9 contract pubkeys to aexn records () ()

    Miscellaneous

    • add fallback for mismatched presence to balance () ()

    • replace aex9 migrations by one that creates all aex9 contracts () ()

    (2022-05-04)

    Features

    • add Ping operation to websocket () (), closes

    • display mdw gens processed per min on the status page () ()

    Bug Fixes

    • allow contract call to GA contract () ()

    • docker include priv volume for migrations to be found () ()

    • handle requests for blocks that don't exist gracefully () ()

    • handle stating server when syncing from scratch () ()

    Testing

    • add aex9 tests iterating throughout all contracts () ()

    • refactor integration tests to unit tests () ()

    Refactorings

    • restructure AuctionBid table for better indexing () ()

    • use aex9 balance records on account endpoints () ()

    • use declarative state for executing mutations () ()

    • use State for building database streams () ()

    Miscellaneous

    • include priv dir for db migrations ()

    • remove unused node and db stream code () ()

    (2022-04-19)

    Bug Fixes

    • enable sync server to receive old :DOWN messages () ()

    (2022-04-19)

    Features

    • index aex9 contracts on Chain.clone and Chain.create () ()

    Bug Fixes

    • don't display source_hash when invalid compilation info () (), closes

    • fix displaying single txis for v2 () ()

    • get next block hash on async task () ()

    • restart sync server after sync fails () ()

    Testing

    • coverage analysis () ()

    • fix intermittent RocksDbCF concurrent error () ()

    CI / CD

    • speed up dialyzer without docker () ()

    Miscellaneous

    • add diffing script to compare two different environments () ()

    (2022-04-05)

    Bug Fixes

    • get pubkey for child contracts () ()

    Miscellaneous

    • clean node db hooks from mdw () ()

    Testing

    • fix integration inactive names cases by expiration/deactivation () ()

    Refactorings

    • fetch expired oracle/names inside mutation () ()

    • include code to fetch stats inside StatsMutation () ()

    • perform async invalidations on a sync server () ()

    • rename /v2/names/* by=expiration to by=deactivation () ()

    (2022-03-31)

    Bug Fixes

    • get bi for a block hash () ()

    • initialize aex9 balance when not exists () ()

    (2022-03-29)

    Bug Fixes

    • aex9 creation for child contracts () ()

    • deactivate name on update with ttl 0 () ()

    • delta stat resume when name is not revoked () ()

    • fix /names/owned_by path () ()

    Testing

    • disable async tasks () ()

    • fix v1/v2 stats tests () ()

    Refactorings

    • async tasks persisted with rocksdb () ()

    • chain and name tables persisted with rocksdb () ()

    • contract tables persisted with rocksdb () ()

    • oracles persisted with rocksdb () ()

    (2022-03-09)

    Features

    • /v2/deltastats () ()

    • add /v2 routes to support versioning () ()

    • add AEX9 v2 endpoint to retrieve balance history () ()

    • add aex9 v2 endpoints () ()

    Bug Fixes

    • /aex9/transfers/from timeout () ()

    • /stats counters with negative values () ()

    • derive aex9 presence error handling () ()

    • fix missing streams errors () ()

    Testing

    • fix intermittent prev_key async test () ()

    Refactorings

    • add fallback controller to deal with errors consistently () ()

    • change name routes to be consistent with core () (), closes

    • commit only through mutations () ()

    • migrations with rocksdb () (

    Miscellaneous

    • added check script for readme routes ()

    • drop old model sum_stat () ()

    • ignore data directory on docker/git () ()

    • mnesia and mdw.db under same data dir () ()

    (2022-02-08)

    Bug Fixes

    • properly assign m_bid to actual bid value () ()

    (2022-02-08)

    Features

    • /aex9/by_contract search () ()

    • aex9 contract created by :contract_call_tx () ()

    • sum of auctions, names, oracles and contracts in total stats () ()

    Bug Fixes

    • render auctions by name using just the AuctionBid key () ()

    • updates txi when internal call expiration is unchanged () ()

    Refactorings

    • extract range independently of the direction requested () ()

    (2022-01-28)

    Features

    • /names/owned_by for inactive names () ()

    • add encoded query_id on query txs () (), closes

    • aex9 balances for an account with token info () ()

    • aex9 presence on calls other than transfer () (

    Bug Fixes

    • aex9 migrations origin handling () ()

    • avoid loading block_hash for building oracle tree when syncing () ()

    • execute block_rewards mutation before stats mutation () (), closes

    • expirations shall run at the end of a height () (

    Miscellaneous

    • disable accoutnt txs legacy endpoint (), closes

    CI / CD

    • invert order to avoid setting git user ()

    Testing

    • fix auction sorting check () ()

    • fix oracles and tx_controller integration tests () ()

    • fix the single stats test that is failing () ()

    • restructure oracles integration tests () ()

    Refactorings

    • add name transfer/update/revoke mutations () ()

    • add tx context for dealing with tx mutations () ()

    • create ContractCreateMutation () ()

    • extract channel_create_tx syncing to Sync.Transaction () ()

    (2021-12-27)

    Features

    • add cursor-based pagination to contract logs/calls () ()

    • add cursor-based pagination to stats () ()

    • db transactions per microblock () ()

    • index contract init events and internal calls () ()

    Bug Fixes

    • base32 encode account cursor on transfers ()

    • build expiring mutation using mnesia transaction ()

    • build oracles expiration transaction using mnesia transaction ()

    • get info for contract with :ref instead of :code ()

    Miscellaneous

    • add additional logging information for auction updates (), closes

    • include date on info.log () (), closes

    • prev_stat is not used () ()

    Refactorings

    • remove dep from chain subscriber ()

    Testing

    • add contract controller endpoints integration tests () ()

    • refactor name controller integration tests () ()

    (2021-12-09)

    Bug Fixes

    • add missing aliases on the Db.Oracle module ()

    Refactorings

    • add oracle expiration mutation when syncing () ()

    • extract block rewards syncing into mutation () ()

    Testing

    • add stats endpoints integration tests () ()

    • name and auction sync logs ()

    Miscellaneous

    • remove cleanup name expiration ()

    (2021-11-30)

    Features

    • add cursor-based pagination to transfers endpoints ()

    • add mutations abstraction to deal with mnesia updates () (), closes

    • allow scoping transfers by txis () (), closes

    • async derive_aex9_presence ()

    Bug Fixes

    • add name ttl to last_bid tx ()

    • allow filtering transfer by kind when backwards direction () ()

    • always display the correct contract_id on contract logs (), closes

    • binary encoding for websocket broadcasting ()

    Refactorings

    • code review changes ()

    • move task sup to async tasks ()

    • task sets done and simplified long task consumer ()

    • tests comparision of names with auction ()

    CI / CD

    • credo fixes ()

    • credo moduledoc finding ()

    • credo warnings ()

    • disable old credo warnings ()

    Miscellaneous

    • remove comment ()

    • use Blocks.height type ()

    Testing

    • add aditional test case for transfers ()

    • add test case with mixed prefixes ()

    • add testcase for account filtered transfers backwards ()

    • async store tests ()

    (2021-11-04)

    Bug Fixes

    • gameta claimed name rendering ()

    (2021-11-03)

    Features

    • account presence based on aex9 balance () ()

    • add cursor-based pagination to scoped txs ()

    • add gas_used to create contract tx info () ()

    • add name hash to owned_by response () ()

    Bug Fixes

    • add AETERNITY_CONFIG env variable to docker-compose ()

    • add ex_json_schema to deps for phoenix_swagger to use ()

    • adjust Mnesia module return types for consistency ()

    • aex9 presence async processing state () ()

    Miscellaneous

    • base documentation on hosted infrastructure ()

    • expose service ports when starting docker-shell container () ()

    • simplified account presence filtering () ()

    CI / CD

    • credo and unused code ()

    • dialyzer ()

    • new plt version ()

    • new plt version ()

    Testing

    • add async task produce/consume tc ()

    • add sender = recipient integration case ()

    • add sync_transaction write fields test ()

    • add tests to Chain.clone events handling ()

    Refactorings

    • add :scope, :query and :offset to Conn.assigns ()

    • add Collection module to deal with complex pagination () ()

    • add paginated auction name endpoints () ()

    • add paginated name endpoints without making use of streams () ()

    (2021-09-17)

    Features

    • /v2/blocks endpoint returns mbs sorted by time () ()

    • add oracles v2 endpoint without making use of streams () ()

    • adds recipient account and name to spendtx () ()

    • backup and restore db table () ()

    Bug Fixes

    • adjust tuple structure sent on AEX9 balances endpoints ()

    • don't read from cache the last 6 blocks () ()

    • indexes remote call event logs also by called contract () ()

    • recipient account is the pointee if name have one () ()

    Testing

    • add blockchain DSL for testing purposes () ()

    • move integration tests to a separate directory () ()

    • separate unit/integration tests and add to ci () ()

    • small integration tests updates () ()

    CI / CD

    • add ci proposal with github actions ()

    • add commitlint ()

    • add credo to ci () ()

    • add dialyzer to project ()

    Miscellaneous

    • add git_hooks lib for optional use () ()

    • format elixir files ()

    • prepend slash to pagination next () ()

    • remove warnings () ()

    restructure dex contracts swaps pagination cursor (#2045) (d01b5d7)

  • swap route v2/v3 route mapping for aex141 token detail (#2032) (085c260)

  • recalculate aex9 holders to fix some invalid aexn contracts false positives (#1972) (817ce6e)

  • reindex previous names with new names structure (#1975) (afdb424)

  • update aexn transfer statistics migration version (#1980) (9430cca)

  • update origins restructure migration (#1978) (b75390e)

  • remove further unused v1 routes (#1962) (114537c)

  • rename aex9-transfers route and add docs (#1979) (b6e16ea)

  • rename minutes_per_block ot milliseconds_per_block (#1967) (36c536f)

  • simplify setup for testnet (#1875) (07db9c6)

  • transfer transactions count summary to v3 (#1878) (76a6d33)

  • update node version to 1.72 (#1881) (e53cee5)

    restructure aexn routing for v3 (#1774) (011c4b4)

    use right index when querying next Time record on stats (#1714) (6aedb5b)

    display approximate expiration time for auctions (#1403) (208f414)

  • filter contract calls by entrypoint (#1413) (409ed52)

  • remove dev docker compose warning (#1408) (3245573)

  • remove swagger ui (#1430) (b4adf6b)

  • return nil for invalid amount of aex9 holders (#1409) (03ae588)

  • update aexn parameters to OAS3 (#1434) (1da6406)

  • index inner contract creations for /contracts endpoint (#1326) (3767186)

    use 404 on missing single path param (#1217) (b5b9da3)

    update endpoints healthcheck (#1213) (ddab030)

    use mix releases for prod docker images (#1190) (fc7356d)

    use path to decide websocket version (#1164) (8941457)

    use txi_idx values for displaying pointees (#1148) (cf5a09d)

    ) (
    )

    track nft template edition supply (#1078) (dfd84fd)

    update balance when adding liquidity (#1094) (dd41834)

    ci: separate docker compose by env (#1086) (1d63f4a)

  • ci: simplify workflow triggering (#1074) (f4e3cbe)

  • remove old makefile (#1091) (07b02cb)

  • specialize build envs (#1089) (71f5b84)

  • include tx_hash on NameClaim activity (#1052) (40797ab)

    root dir cleanup (#1046) (21aa19f)

  • set network_id as runtime config (#1045) (159371a)

  • sort event logs by index (#944) (be3ec7f)

  • support listing active/inactive names when filterng by owner (#947) (8a1c8cb)

  • add /v2/micro-blocks/:hash/txs endpoint (#900) (2312a8a)

  • add nft collection stats (#899) (5f5583a)

  • create nft ownership based on Mint event (#897) (929e7c5)

  • index and fetch nft owners on a collection (#894) (1d06bbf)

  • index channels and add active channels endpoint (#889) (d86b1cc)

  • remove rocksdb wrapping code that created DB inconsistencies (#865) (530add4)

  • temporarily hardcode node version in docker build (a6da18c)

  • treat AENS.update calls name_ttl as an absolute height (#872) (89bf5d2)

  • increase long tasks throughput (f93d72b)

  • rerun failed task and fix processing state (#848) (8afcb9f)

  • update opts usage on Names.fetch_previous_list/2 (#825) (c5e7f40)

  • runs dry-run only once per contract and block (#778) (5690902)

  • sort active names by activation height (#760) (a57cf3c)

  • sync latest gens in-memory for instant invalidation (#676) (af95379)

  • sync up to latest micro-block (#726) (bff7d0f)

  • consider empty generations on mdw height (#766) (a3d8621)

  • ignore tx_hash when iterating through queries (#795) (6be2041)

  • remove blocks cache displayed on /v2/blocks (#787) (f1672c4)

  • use single-block transactions to avoid duplicated deletions (#786) (49cf42f)

  • encapsulate all Database calls through State (#762) (922f7d8)

  • present aexn tokens using state from the StatePlug (#759) (68f04f5)

  • raise detailed message when deleting txn missing key (#792) (e6f0366)

  • raise exception when transaction commit fails (#783) (84a5110)

  • remove migrations and old aex9 tables (#773) (19114fa)

  • remove unused Db.Util functions (#791) (1b172ae)

  • remove unused ets tables (#804) (d909dd7)

  • remove unused Invalidate.invalidate/1 function (#761) (e172833)

  • rename file to match module name (#799) (1476e85)

  • use latest State on NamesExpirationMutation (#782) (321308c)

  • ignore aex9 balances only when there's a single <<>> balance (#677) (f55742d)

  • remove aex9 presence for remote calls (#683) (7d11889)

  • revert change on prev key iteration (#681) (5117fad)

  • rearrange aex9 transfer pubkeys for pair transfer (#649) (809e058)

  • write block_index to aex9 balance (#657) (1ed2811)

  • update aex9 balance on any call and invalidate it on fork (#630) (685ba96)

    fix aex9 balances route for a contract (#606) (59bb989)

  • handle name ownership and pointers when tx is internal (#601) (95b2f5a)

  • missing InactiveNameOwner record (#598) (85f6c74)

  • oracle expiration stats (#585) (859b452)

  • set contract created stats min value to 0 (#609) (9be2d02)

  • start syncing mdw after running migrations (#587) (5b580b1)

  • update readme for /v2/deltastats (#613) (bd8570b)

  • stats tables persisted with rocksdb (#579) (2860bbd)

    add contracts v2 endpoints (#559) (74aadab)

  • add paginated /names/search/:prefix endpoint (#447) (3f213d7)

  • add prev link cursor on paginated endpoints (#526) (0eca223)

  • add v2 blocks endpoints (#549) (24c4020), closes #498

  • add v2 oracles endpoints (#550) (76d47a0), closes #498

  • add v2 stats endpoints (#556) (11dd8f6)

  • add v2 transfers endpoints (#554) (bd94755)

  • add v2 txs endpoints (#552) (86daad0)

  • aex9 transfers pagination (#551) (d765a25)

  • allow mdw sync module to restart after a failure (#564) (f6b7b47)

  • cached aex9 balances (#571) (d53ba6b)

  • rocksdb without mnesia (#475) (37f5889)

  • use Mnesia module (#506) (9b50a8e)

  • integration tests db path (#542) (90c4961)

  • raise exception when aex9 contract doesn't exist (#540) (26044d5)

  • update names search streams to use new Database module (#544) (507bc94)

  • )
  • Mnesia to Database (#528) (934ebd8)

  • mutations derive to default impl (#553) (c406a57)

  • remove and make private unused modules/functions (#527) (d6fc8e9)

  • remove unused web code (#532) (93c2487)

  • rename write mutation (#533) (ec1badd)

  • update name routes to be consistent with core (40f598c)

  • remove no longer needed migrations (#576) (de01738)

  • rename name endpoints swagger operation ids (#561) (308c556), closes #179

  • withhold non-migrated v2 routes (#548) (f73f27d)

  • )
  • contract compilation info (#457) (16a88d0)

  • index AENS internal calls (#472) (b089194)

  • index ga_attach_tx by contract (#413) (fc2f3cb)

  • )
  • extract pointers from internal calls (#486) (4475676), closes #477

  • fix dockerfile for multiple node releases (67b57a4)

  • get aex9 meta info error handling (#496) (a8fc71d)

  • inactive name owner table for sync (#463) (f936572)

  • index Oracle.respond internal contract calls (#480) (e065bf4), closes #468

  • index the origin of contracts created via Chain.clone/create (#474) (a0f39e9)

  • make db transactions synchronous (#443) (7ee8347)

  • name and oracle int calls filtering (#488) (b35daa1)

  • name expiration after aens.update with name_ttl = 0 (#491) (9ab3502)

  • nested or nil mutation processing (#493) (fcc9119)

  • register oracles created through Oracle.register contract calls (#466) (d2409c7), closes #380

  • skip processing internal calls for Chain.* events (#467) (25bcf4e)

  • stats count for existing objects (#454) (5fb8ea2)

  • validate existing contract when filtering calls by contract_id (#446) (35c6054), closes #422

  • restructure tx_controller integration tests (#427) (0a17539)

    extract name claim mutation (#431) (66be18a)

  • extract oracle extand/response mutations (#444) (9e520e2)

  • extract OracleRegister transaction into mutation (#430) (8c0933d)

  • key blocks mutation (#441) (c64fda6)

  • split contract events mutation into multiple MnesiaWrite (#458) (1521121)

  • split ga_attach_tx mutation to use FieldMutation instead (#445) (378b74d)

  • trim unused code from the paginated endpoints (#494) (5aa92aa)

  • revert chainsubscriber refactor (#412) (1b1e52f)

  • sync height 0 without mbs and txs (9b9bbdf)

  • use last synced gen for stats and totalstats (#401) (53b27e7)

  • dedup existing records (03708c2)

  • implement cursor-based pagination for scoped oracles & names (#324) (a82981c)

  • long running async tasks (cd18e3d)

  • use cursor-based pagination for blocks endpoints (#333) (18a859c)

  • cancel task timer (a1d11f9)

  • contract might not be present (65b18df)

  • dedup args for any task type (af7b9c6)

  • filtering aex9 call (9c374bd)

  • getting aex9 recipients (6adf87c)

  • increase task timeout (8715600)

  • long task without timeout (f2256c7)

  • reindex transfers to be able to filter by account + kind (710ee08), closes #359

  • remove old oracle expiration (369aa50)

  • remove unexisting auction fields (#350) (9621d66)

  • start long task (71b3404)

  • update contracts txi (e08334c)

  • validate name expiration (13703a4)

  • format and dialyzer (1d605f4)

  • ignore existing credo warnings (a953db1)

  • linter (63e4600)

  • new plt (bb7022b)

  • new plt (90b336e)

  • avoid mutual side effects on stats (1ca419a)

  • include kind filter on account transfers test (9b1e3d5)

  • long tasks test fixed (a77b5a6)

  • longs tasks stats (598c75e)

  • notify and wait for consumer (fb03a09)

  • proto_vsn for name unit tests (f8aaa10)

  • add recipient details for /tx and /txi (#318) (7868e9d)

  • add support for Chain.clone and Chain.create events (8e3b0c8), closes #208

  • async account aex9 presence (#279) (2c0d44d)

  • async tasks status (#286) (6ccce3d)

  • auto migrate_db on start (#261) (a577816)

  • contract calls with dry-run (8407dc0)

  • contract create init details (#310) (aa8158d)

  • delay slow aex9 migration balance (6e885fa)

  • publish to websocket subs afer height sync (#304) (d0696f8)

  • aex9 presence check demands mnesia ctx (56d33fc)

  • aex9 presence write within transaction (#282) (f342d50)

  • application init warning (5461dc2)

  • base64 encode queries when returning oracle query txs (#274) (239c967), closes #264

  • duplicated indexation when receiver=sender (3a878e4)

  • fix /txs route handling (#296) (c1d1e1b)

  • fix default range gen fetching (095315c)

  • fix dockerfile for multiple node releases (d6c52cb)

  • handle contracts w/o creation tx gracefully and consistently (#293) (c68cb66), closes #269 #208

  • internal server error on aex9 balance(s) range (#297) (1757f4c)

  • missing AeMdw.Txs alias from rebase (778c059)

  • mix version comma (bbc74ac)

  • name auction bid details when expand=true (83d3831)

  • oracle expire validation (#315) (3bcb95f)

  • oracle extend validation (#306) (781c4b7)

  • rescue :aeo_state_tree.get_query error (326a528)

  • return nil when contract tries fetching non-synced tx (#272) (61d3622)

  • revert field indexation (keeps both fields) (a03e1cf)

  • set :app_ctrl mode to :normal to allow MDW to sync (#284) (b546d72)

  • start :aesync and :app_ctrl_server when initializing app (23c41ef), closes #275

  • start all aecore services after starting app_ctrl_server (351c9cf)

  • plt version (cdc14d9)

  • revert force PLT creation (ce3aedf)

  • temp delete priv/plts (82cb5ba)

  • temporarily create plt without condition (f1f78d8)

  • temporarily remove old plt file (bd601f8)

  • additional sync case when recipient = sender (edb9d1e)

  • fix oracles integration tests (#255) (14c59fb)

  • fix oracles/names tests (d5cb035)

  • replace last_txi with very high value (33e2d87)

  • uniq integration case check for recipient = sender (a81513f)

  • use mnesia sandbox (90e6688)

  • add paginated txs endpoint (#283) (435d184)

  • convert from gen to txi differently (2d3cdea)

  • migration logs with Log.info (f9b4e15)

  • move first_gen! and last_gen! to Db.Util module (385e00f)

  • only add contract creation txs when tx_type is contract (63417ee)

  • use aetx getters for retrieving tx fields (4197983)

  • index inner transactions (#248) (0a02727)

  • restructure ETS stateful DB streams implementation (#241) (40a2a3d)

  • update NameController tests to be unit tests (#235) (32bc946)

  • use specific docker image version of Elixir (#240) (93cb45d)

  • add release please workflow (88cff95)

    warnings as errors (cc162b8)

    #2142
    2d10fe5
    1.104.2
    #2135
    0dee0e6
    1.104.1
    #2128
    b1ffeaf
    #2133
    e2d0b93
    #2131
    051168e
    1.104.0
    #2126
    a9b65f2
    #2132
    6ff7961
    1.103.0
    #2127
    1112d7c
    #2111
    eecace6
    #2122
    256e873
    #2123
    ded2de7
    #2117
    9ebdf6d
    #2120
    4c6667c
    1.102.0
    #2116
    092ab54
    #2112
    0dd63dc
    1.101.0
    #2106
    205fb1a
    #2086
    249791d
    #2086
    #2110
    6c48030
    #2103
    87a26fc
    #2108
    9bda7ab
    1.100.0
    #2095
    042a78f
    #2096
    c3c1bda
    #2090
    14e4074
    #2098
    4220311
    #2093
    29bd874
    1.99.0
    #2000
    03d3f80
    #2085
    d2301a7
    #2078
    bd2fd2f
    1.98.0
    #2074
    263c3ae
    #2076
    c3e232e
    #2084
    efed991
    #2083
    b3e9e43
    #2088
    c7bbe90
    #2077
    bc5bb69
    1.97.1
    #2073
    4d4da97
    #2057
    817ea69
    #2072
    cd73793
    1.97.0
    74e098d
    #2062
    35af3fa
    #2070
    2903e0a
    #2039
    ddf61e5
    1.96.2
    #2053
    407f5a1
    #2055
    933ee8a
    #2052
    5cfac38
    1.96.1
    #2049
    7b010f3
    1.96.0
    #2038
    fbad967
    #2037
    79e5c1a
    #2034
    e164160
    #2030
    07b50b7
    #2036
    6c7ac6f
    #2029
    a0eb067
    #2033
    f4ce73d
    1.95.0
    #2024
    1935147
    #2023
    8b605a7
    #2028
    58f3c55
    #2027
    9279c9e
    #2026
    cff8565
    1.94.0
    #1998
    e5daa8a
    #2020
    e627c2c
    #2005
    6ec809f
    1.93.0
    #2010
    fd32144
    #2011
    3b7be6b
    1.92.2
    #2015
    fcd3081
    1.92.1
    #2013
    353bd2e
    #2004
    0c6bf9d
    1.92.0
    #1960
    7210f83
    #2008
    4c409e6
    #2001
    afae4d1
    1.91.1
    #2002
    e942adf
    1.91.0
    #1941
    f5e114c
    #1983
    067f021
    #1997
    5cad6c0
    #1991
    4a3ebc1
    #1994
    532ca0b
    #1993
    c55a8aa
    #1996
    e916bf8
    #1989
    200a116
    #1984
    6e5edc8
    #1981
    0619c4b
    1.90.1
    #1987
    4e707e3
    #1982
    ab9b286
    #1988
    65c5d6f
    1.90.0
    #1921
    edc13a6
    #1977
    acc31eb
    #1969
    2e33b92
    #1974
    8f8fcd7
    #1971
    94fb010
    #1976
    5a9fbde
    #1961
    4e6147c
    #1970
    8ab1df1
    #1964
    13ea64f
    #1965
    7e5bb2a
    1.89.0
    #1953
    1b6cbf2
    #1936
    9458297
    #1956
    1c82965
    #1959
    7527ce9
    1.88.0
    #1947
    19b2fc3
    #1945
    b32a95c
    #1944
    2d6909c
    #1952
    c713483
    #1949
    4452cac
    #1937
    1783f0d
    #1951
    dd788b4
    #1939
    8602169
    1.87.0
    #1920
    338ada9
    #1923
    d294fa9
    #1940
    f4f73b3
    #1927
    1aba034
    #1922
    5694232
    #1935
    f76137e
    #1934
    42ba1b5
    #1929
    fbc084c
    1.86.0
    #1913
    7b76954
    1.85.0
    #1911
    d2c8b00
    #1918
    c304bfe
    #1912
    ca0d83c
    #1915
    cfaac71
    #1924
    9695796
    1.84.0
    #1905
    d06934b
    #1906
    11c8475
    #1862
    ffa7238
    #1886
    6248a65
    #1900
    9d70528
    #1902
    d5a259f
    #1904
    9e5e305
    #1908
    0e223fe
    #1889
    b213694
    1.83.0
    #1839
    56fba66
    #1838
    fe0975a
    #1885
    27d1901
    #1863
    232723b
    #1870
    bb44c54
    #1874
    f44d45a
    #1851
    761b635
    #1876
    e4daf3f
    #1880
    6988432
    #1882
    5bdcf70
    1.82.2
    #1867
    d689d47
    #1871
    7dd50b8
    #1848
    3ee3b28
    1.82.1
    #1866
    847dab4
    #1864
    a7de382
    1.82.0
    #1836
    982e12a
    #1837
    bb895ed
    #1846
    503ad87
    #1830
    a15c74c
    #1843
    dbe35de
    #1847
    6f6f747
    1.81.0
    #1737
    9cbd5e6
    #1828
    219417b
    #1835
    1f6835c
    #1826
    56d2150
    #1832
    e8514fa
    #1831
    c1c3abd
    #1834
    b2cbe8c
    1.80.0
    #1824
    e8c077f
    #1827
    078356f
    1.79.0
    #1822
    a3233ed
    #1820
    9ee2181
    1.78.1
    #1817
    a1b84c5
    1.78.0
    #1812
    80d4b58
    #1808
    d359312
    #1799
    f6e1e5b
    #1814
    8e06ba5
    #1796
    0511351
    #1813
    2767a18
    #1801
    6e13a42
    #1792
    42ee54f
    #1807
    6d676cf
    #1811
    6d78af8
    #1800
    4d5949e
    1.77.5
    #1797
    2f330e9
    1.77.4
    #1791
    acc9ba6
    #1794
    15ce77f
    #1790
    0a40932
    1.77.3
    #1788
    eb95c2f
    #1776
    0f2d9fc
    1.77.2
    #1787
    66cf9af
    #1785
    7e84fd4
    1.77.1
    #1779
    f9d40fd
    1.77.0
    #1777
    2d1ef20
    #1781
    6fc8d0f
    1.76.0
    #1770
    76d52c3
    #1762
    e3ce830
    #1772
    bd78e3c
    #1775
    f7e2c09
    #1773
    826b877
    #1766
    3d55193
    #1741
    3dc584e
    #1769
    f00fa29
    #1771
    cb78b3e
    1.75.0
    #1749
    eac8a60
    #1754
    301f76f
    #1753
    e08dbf5
    #1746
    1d788af
    #1752
    a2c027e
    #1751
    7f2647a
    1.74.4
    #1745
    635249b
    #1743
    21d942e
    1.74.3
    #1738
    a37a79f
    1.74.2
    #1732
    0828e4b
    1.74.1
    #1734
    881c994
    1.74.0
    #1731
    d58d752
    #1729
    8b34e16
    #1728
    0294ba6
    1.73.0
    #1708
    f220f48
    #1724
    dc7e145
    #1710
    65575cb
    #1712
    df59b68
    #1725
    8f9af21
    #1727
    e4e0f00
    #1715
    587844b
    1.72.1
    #1722
    1023ae1
    #1720
    7fcc55d
    1.72.0
    #1702
    d98b960
    #1706
    84a6837
    #1711
    21a6b8d
    #1717
    af232e4
    #1707
    e0ba8ae
    #1718
    41e74c1
    #1716
    54b54ff
    #1704
    b009208
    1.71.0
    #1701
    db4f45d
    #1700
    75d945e
    #1697
    797b1ef
    #1705
    fae0967
    #1699
    3a214d9
    #1696
    4f80b8b
    #1695
    bc10039
    1.70.0
    #1683
    62065cc
    #1694
    f459a04
    #1691
    9f5e850
    #1687
    4bb632d
    1.69.1
    #1686
    302202a
    1.69.0
    #1677
    6b145dc
    #1680
    1bb6d13
    #1681
    4f55387
    #1685
    02a9eaf
    #1684
    f9f8c4d
    1.68.2
    #1675
    3afe25e
    #1679
    7983ed1
    1.68.1
    #1673
    91d29a8
    #1663
    4bc5776
    #1674
    9ac9c87
    1.68.0
    #1628
    006503c
    #1652
    b7a073d
    #1658
    f21c3e0
    1.67.0
    #1639
    a64d2b1
    #1645
    2875c61
    #1648
    3d26843
    #1646
    5f3b91d
    #1640
    28e0531
    1.66.4
    #1643
    da8e284
    1.66.3
    #1637
    07bd70a
    #1627
    fdcf633
    1.66.2
    #1630
    65c2678
    1.66.1
    #1625
    c3e8814
    1.66.0
    #1623
    82a7943
    #1620
    a1a0af5
    #1621
    1156a98
    #1610
    6d89854
    #1618
    6d65207
    #1617
    9355e30
    #1619
    0c17998
    1.65.0
    #1607
    455084d
    #1608
    ee77609
    #1606
    ead1621
    #1601
    d3f0651
    #1605
    d5bc9f0
    #1598
    f9c0116
    #1596
    cb07826
    1.64.0
    #1594
    3539e95
    #1587
    0806849
    #1583
    daa4e53
    #1589
    1e29e46
    #1586
    610ba26
    #1591
    6fbf370
    #1571
    5a3bd21
    #1582
    e2faf61
    #1585
    67ea069
    1.63.0
    #1573
    dc0aecc
    #1579
    798a523
    #1575
    d44e047
    #1578
    121cd28
    #1483
    dc4d90d
    1.62.5
    #1569
    5b0d867
    1.62.4
    #1567
    8d783bd
    1.62.3
    #1565
    43eed29
    1.62.2
    #1563
    e1b27cb
    1.62.1
    #1561
    4c0d4ee
    1.62.0
    #1558
    3d0c86a
    #1557
    7f62111
    #1554
    5fd3bd3
    #1556
    f3ea4b4
    1.61.0
    #1551
    23b1927
    1.60.0
    #1546
    66a54d8
    #1543
    47f9fc5
    #1548
    4703a08
    #1542
    7515310
    #1541
    f6bb850
    #1545
    eeb9d55
    1.59.1
    #1537
    77909cd
    1.59.0
    #1527
    637a744
    #1536
    6d0691b
    #1530
    ad287ec
    #1535
    77d387b
    #1534
    e90667a
    #1531
    34a04d5
    #1533
    aed582b
    #1526
    dd75063
    #1529
    dad0822
    1.58.0
    #1517
    c7331ec
    #1496
    a52e2cb
    #1516
    a269518
    #1521
    5617a37
    #1512
    74cdb9e
    #1524
    dc866bb
    #1515
    a9a0e9e
    #1519
    1a01b5e
    #1518
    c99958b
    #1525
    ae9a51f
    #1493
    1c3bd78
    #1520
    d151f25
    1.57.2
    #1509
    f65fa1b
    1.57.1
    #1499
    c2bb9da
    #1507
    2e2413f
    #1501
    0251aae
    #1508
    35ff502
    1.57.0
    #1486
    b1dd02d
    #1489
    231b169
    #1491
    e26a2a7
    #1484
    1a0e211
    #1495
    d2ecbb1
    #1494
    0440a7f
    #1490
    b58b278
    1.56.0
    #1475
    5f91ff6
    #1482
    33579e4
    #1481
    721fbd2
    #1478
    dbe6d0c
    #1476
    c6bcaeb
    #1473
    #1474
    372c60d
    #1469
    750c266
    #1472
    9b6d56f
    1.55.1
    #1465
    af3546f
    #1466
    3ff5a6c
    #1460
    abcec9e
    #1464
    72d064b
    #1468
    57d31ff
    1.55.0
    #1459
    f6e0bb4
    #1462
    7982211
    1.54.2
    #1404
    7b24e15
    #1451
    d2ba17a
    #1453
    1b5f77e
    #1457
    3f53f9a
    #1458
    9e41cd8
    #1456
    a257442
    1.54.1
    #1449
    bde081d
    1.54.0
    #1442
    0636068
    1.53.0
    #1435
    d922851
    #1436
    d7ab68e
    #1440
    6a1fc14
    #1444
    b46803d
    1.52.0
    #1432
    b769250
    #1419
    de3db7c
    #1420
    79618f9
    #1431
    5a8a36c
    #1412
    53c22c3
    #1415
    ba930f6
    #1417
    1c42754
    #1433
    565dfa3
    #1423
    f0ba7b4
    #1406
    2e41a79
    1.51.0
    #1399
    4be56fc
    #1397
    8ed0a7b
    #1402
    a72fe7b
    #1405
    3102d8a
    #1401
    ee7de9b
    #1396
    6e7f310
    #1306
    1b6000a
    1.50.1
    #1394
    38baa36
    1.50.0
    #1390
    b008217
    #1382
    490d379
    #1387
    a7f0f84
    1.49.1
    #1383
    021e988
    #1374
    25ece54
    #1379
    ef46747
    1.49.0
    #1335
    4284e63
    #1341
    11d53ac
    #1367
    c303cce
    #1340
    95bfa1e
    #1368
    cc601f1
    #1343
    eb58bf3
    #1369
    ca2fff8
    #1370
    83eaf77
    1.48.1
    #1353
    8feb46f
    1.48.0
    #1325
    fcb44a9
    #1327
    775b663
    #1330
    1495ddb
    #1314
    7c6fb6f
    #1339
    f835ef3
    #1323
    1b6133c
    #1329
    91ecf94
    #1342
    db0da2c
    #1334
    1fe2817
    #1223
    #1328
    6fa3873
    #1223
    f96f56c
    1.47.0
    #1317
    8a70312
    #1315
    a5b0bac
    1.46.7
    #1312
    1c0ff5e
    1.46.6
    #1310
    200be59
    1.46.5
    #1303
    dee9a63
    #1305
    21209ed
    1.46.4
    #1299
    6b4d3d7
    1.46.3
    #1296
    79e4242
    #1298
    592faae
    1.46.2
    #1289
    cf6d4fa
    1.46.1
    #1287
    0f72b8a
    1.46.0
    #1277
    5230feb
    #1280
    2f886e9
    #1274
    8f51484
    #1286
    5fdc504
    1.45.0
    #1269
    b9f2bb7
    #1273
    7d5164d
    #1270
    c1b0903
    1.44.0
    #1263
    c07fc64
    #1265
    789f578
    #1266
    b5b042e
    #1260
    732b37b
    #1267
    b4edb22
    #1262
    7986309
    1.43.0
    #1253
    c3244be
    #1258
    87783e1
    #1248
    89cf780
    #1252
    738bce2
    #1251
    f37a226
    #1254
    ab276df
    #1249
    9f51f40
    1.42.0
    #1240
    f8f2b7d
    #1241
    dfe86b5
    #1246
    12b270e
    #1245
    2d4db64
    #1239
    d29d29e
    1.41.5
    #1238
    dfc8998
    #1237
    c8ca3a4
    #1230
    b0165bb
    #1234
    940958a
    #1228
    700d338
    #1232
    3f657de
    #1235
    5bb5b1d
    1.41.4
    #1221
    84994fb
    #1226
    ff95030
    #1227
    b7ce3a0
    #1211
    880f0d3
    #1225
    2f55ac3
    #1224
    52ef103
    #1222
    ff14888
    #1229
    a94b1d2
    1.41.3
    #1207
    ddf4fd8
    #1203
    5ae60f1
    1.41.2
    #1208
    744b773
    1.41.1
    #1205
    159c51a
    #1201
    bc5291f
    1.41.0
    #1193
    6a3743f
    #1180
    ccb5f9c
    #1188
    c0b99b0
    #1191
    02e00c6
    #1196
    1be940a
    #1197
    a133ea4
    #1195
    2f25139
    #1194
    f37ef38
    #1133
    c3a0e30
    #1198
    32e0836
    #1200
    44a6b1a
    1.40.0
    #1179
    6631dee
    #1172
    d1f9e42
    #1175
    e496e53
    #1178
    2faf521
    #1177
    2abc1db
    1.39.1
    #1173
    6cb9d19
    1.39.0
    #1161
    d0e9965
    #1153
    de95c3e
    #1167
    6040929
    #1169
    63e7afd
    #1171
    c5ec27f
    #1158
    61f571c
    #1159
    c373db6
    #1166
    d80f7b5
    #1168
    fb4d45f
    #1162
    f74c6e0
    #1170
    047ab62
    #1163
    3fcde8d
    #1154
    e9e537e
    1.38.0
    #1145
    d6228c6
    #1149
    aa111a8
    #1138
    c112077
    #1151
    c1a797a
    #1137
    9c8bd08
    #1142
    b65830d
    #1139
    7c8aff9
    #1136
    e76ceba
    #1144
    33d5e28
    #1150
    ee066eb
    #1146
    fe1bcdf
    1.37.1
    #1131
    3c30342
    #1132
    0a5738b
    1.37.0
    #1121
    67e9918
    #1128
    aa8ba56
    1.36.0
    #1120
    27e3e19
    #1124
    a386a7e
    1.35.1
    #1115
    e152455
    #1118
    bafefe5
    #1123
    ad1871c
    1.35.0
    #1114
    d20f8f4
    #1111
    c91206e
    #1109
    37282f2
    #1107
    d1f0e6a
    #1116
    54e6cf6
    #1113
    0c8ad4b
    #1117
    ed0c517
    1.34.0
    #1098
    f743612
    #1104
    15bd964
    #1088
    e5df7b5
    #1106
    e595f0b
    #1103
    184b112
    #1097
    c8f498d
    #1099
    706b785
    #1100
    1.33.0
    #1083
    260027c
    #1072
    24bdc75
    #1092
    37a5005
    #1090
    bc54cd6
    #1093
    4ac2316
    #1062
    da7531f
    #1080
    295918d
    #1063
    08554db
    #1084
    7f05621
    #1085
    b7ca317
    #1081
    8eafec8
    #1082
    f403c40
    #1073
    73a906a
    #1079
    46f7ca3
    1.32.0
    #1064
    7c86a87
    #1070
    7fa832b
    #1067
    ffde479
    #1043
    d3013db
    #1059
    4d49efe
    #1071
    71212a8
    1.31.0
    #1057
    d348987
    #1048
    ea937a5
    #1049
    af52df2
    #1051
    8872290
    #1047
    3b2b16e
    #1056
    5f5a499
    #1055
    5aff9e0
    #1058
    0b32825
    1.30.0
    #1037
    bc31513
    #1040
    91a58f0
    #1038
    5870dc9
    #1036
    6198316
    #1025
    5f21192
    #1034
    3eafff2
    #1030
    1abc8f3
    904996b
    #1026
    054e87b
    #1041
    e329f49
    #1039
    6d8125b
    1.29.1
    #1020
    91c6036
    9041da0
    #1019
    bddbdff
    1.29.0
    #1014
    33d56f3
    #1001
    8539d2e
    #1016
    ca41a7b
    #1009
    31de473
    #1004
    a62d03f
    #1005
    6567619
    #1017
    0be0aed
    #1008
    84ba88f
    #1011
    5e8582a
    1.28.1
    #1000
    466e29c
    1.28.0
    #994
    0f46c5c
    #991
    c279099
    #992
    3c62446
    #982
    b87b3d7
    #995
    ef0922e
    1.27.0
    #983
    22c554d
    #987
    758acf9
    #981
    3340b7c
    #976
    aaf244a
    #978
    ed81098
    #977
    c19e09b
    1.26.0
    #965
    4c23fbe
    #970
    6f3a5e5
    #972
    8383c71
    #971
    8694384
    #964
    f6f69e3
    #968
    3e83163
    1.25.1
    #962
    b9e111a
    1.25.0
    #957
    ec875a3
    #958
    bb52e42
    #959
    ba40c78
    1.24.0
    #935
    0e8afb8
    37b5764
    #941
    3d9a137
    #954
    6d7260e
    #953
    f1036da
    #955
    2414b8b
    #952
    0bd99a9
    1.23.2
    #945
    fe0e3be
    1.23.1
    f99b2c5
    #936
    aec8bea
    #940
    70adf3f
    1.23.0
    #933
    d051180
    #927
    ba99629
    #926
    95cd809
    #932
    d19be47
    #929
    3de2cbb
    #925
    f47703a
    #931
    82d5e28
    1.22.0
    #915
    6cad834
    #917
    9298edd
    #916
    ca820ac
    #923
    49388a8
    #918
    f5b4270
    1.21.1
    #909
    fba6cfc
    #914
    d34ffb2
    1.21.0
    #906
    950f738
    #911
    5ab2cb2
    #905
    bd7229b
    #912
    05ece6c
    1.20.0
    #892
    1b5f016
    #895
    b8a2e09
    #896
    0540074
    #898
    2c16e47
    #903
    af3471f
    #904
    1b21738
    1.19.1
    #890
    251c5a8
    1.19.0
    #882
    c6cb13c
    #854
    725beb7
    #887
    322dac0
    #877
    9a3011b
    #878
    8e2be75
    #883
    c1d556d
    #879
    86c0383
    #868
    f3a9475
    #876
    01aba8a
    #874
    22066aa
    #867
    27071f4
    #871
    78467bd
    1.18.0
    #840
    d965275
    #855
    dcd4c68
    #861
    40da750
    #862
    d97058f
    #852
    77bb961
    #856
    53f7bfc
    #845
    540f6d7
    #858
    0e81e25
    #843
    900636d
    #857
    654228e
    #859
    8450d0a
    #853
    5c904f6
    1.17.0
    #834
    1e010de
    #838
    7d6de8b
    #822
    d75d45f
    #818
    407576e
    #832
    8b7a655
    #841
    5868472
    #835
    26b4bd4
    #826
    278e5ee
    #829
    45f184f
    #833
    a34ff73
    1.16.1
    #819
    e0650b5
    #820
    af64624
    #813
    d99bd16
    #814
    e7626d7
    #815
    c397067
    1.16.0
    #805
    2806136
    #809
    22bfcf6
    #811
    bfa532a
    #812
    3078c36
    1.15.0
    #793
    dde85c0
    #800
    9388279
    #798
    cae1dc3
    #789
    295da57
    #767
    f9825d6
    #781
    f7b0da0
    #801
    f059238
    #806
    048757e
    #788
    98e1804
    #775
    2406543
    #777
    1c678b5
    #796
    c57056a
    #785
    e2f728a
    #769
    af41a5c
    #802
    d5c52b3
    #779
    62e7c75
    #784
    c56e9c4
    #757
    b607abb
    #790
    2a4c3d9
    1.14.0
    #743
    483b9d5
    #745
    f62033c
    #750
    17e7be7
    1.13.1
    #737
    25b0e20
    1.13.0
    #724
    5e701bf
    8b806d8
    8a116e8
    #733
    6d233bb
    1.12.0
    #727
    b1695bb
    1.11.1
    #720
    d8c131e
    #714
    #717
    89138c6
    #716
    f2041ae
    #722
    d47b1a5
    1.11.0
    #704
    6d597dc
    #710
    bb2ff95
    #715
    81beaf0
    #712
    d718c0a
    #711
    9b416e7
    #702
    969d84c
    #699
    57c0070
    1.10.1
    #698
    c120449
    #700
    9fec9bf
    #697
    739b80b
    1.10.0
    #692
    9c1253e
    #696
    ea57b49
    #693
    #678
    8651dd5
    #670
    e678a02
    1.9.2
    #690
    8b4304f
    #688
    5d480bf
    #691
    803ab00
    #179
    1.9.1
    #671
    8f52477
    #686
    040c120
    #685
    f944f04
    #679
    a8fe572
    #659
    996b686
    #667
    71dc396
    #680
    e7cf6e8
    #660
    d392510
    #687
    6b78a88
    #668
    a496d72
    1.9.0
    #664
    2a02db4
    #638
    #650
    8c9e56f
    #645
    0934873
    #662
    d8c838b
    #646
    eebe129
    #647
    54f9d59
    #655
    f665330
    #633
    5947784
    #652
    4688dd4
    #658
    4854894
    #621
    02132ff
    #654
    adc2024
    392b171
    #656
    5dce45b
    1.8.1
    #642
    53d716c
    1.8.0
    #639
    232ef4d
    #636
    f68fc0f
    #635
    #637
    2642d24
    #624
    4c5e1b1
    #640
    2755773
    #599
    4657cb7
    #631
    9b844d7
    #632
    8a77729
    #628
    b238c0f
    1.7.3
    #620
    6e8c2da
    #619
    ce75528
    #622
    43a661b
    #611
    0910e84
    #610
    5991bc4
    #589
    32c2575
    #623
    a360c8b
    1.7.2
    #614
    6b15215
    #616
    de283b5
    1.7.1
    #592
    ce586bf
    #602
    6e1a2b7
    #593
    83af31b
    #612
    80adf01
    #583
    b451b4d
    #608
    a216b83
    #577
    0810dde
    #590
    3d8d22f
    #594
    93de2b3
    #588
    3d8aae4
    1.7.0
    #560
    0f8961a
    #530
    539042b
    #575
    d3abb00
    #563
    13a0a07
    #546
    1010cac
    #562
    4c60302
    #537
    348e3d9
    #531
    a97f3e7
    #543
    04b004c
    #547
    2664124
    #451
    40f598c
    #110
    #498
    #534
    42b09e8
    #573
    fac84b4
    4c57a1e
    #558
    7dc65c2
    #555
    c10a9b8
    #539
    f7e636f
    1.6.1
    #521
    91b1f0b
    1.6.0
    #505
    117a45d
    #514
    7224252
    #504
    3adb25d
    #515
    b3c0f3a
    #502
    8450838
    #499
    979c5ab
    1.5.0
    #461
    d206326
    #455
    4691bdd
    #381
    #60
    #424
    658c522
    #438
    ceee4b1
    #481
    d27dc0e
    #460
    1776b26
    #452
    d1ece21
    #450
    #484
    25d9d96
    9a4480e
    #410
    d00e0f7
    #449
    efeb945
    #440
    1d6541b
    #479
    79d918e
    #423
    36e0800
    #465
    fcaff4a
    #439
    a8cc83a
    #428
    e74dc17
    #429
    9036bf1
    1.4.0
    #392
    f0724ab
    #384
    045ee35
    #390
    eb76e5b
    #395
    ca7f295
    8d4c274
    c94f28d
    721ad99
    5ffcec1
    865421c
    #396
    #389
    cee643e
    #361
    #400
    55a7e48
    6be7a7f
    #391
    6389fb1
    #421
    2413b7b
    1.3.1
    4584411
    #371
    51beb6e
    #367
    9602804
    #383
    72c5001
    e42a197
    d63bf1b
    1.3.0
    7f0d4d7
    #342
    2f565cf
    #331
    #356
    0cf7058
    #307
    66a358a
    deede55
    #360
    78c6648
    84b06dc
    #301
    9ead4d0
    e5ce624
    689bb60
    f88f392
    016e357
    7255760
    713558e
    d814bdd
    bf258d2
    1795c2b
    038fb57
    1a89b38
    143bef7
    fc4c00e
    0584ff8
    1.2.1
    ce9293b
    1.2.0
    #262
    57c1ef3
    67b7097
    #258
    6dc5577
    #299
    a148f7b
    8d49e3d
    21aa314
    86bae6e
    #290
    bb53964
    20d6ee4
    #291
    9886344
    #271
    f41b9e6
    14acf7c
    4800c8f
    daea38e
    399ed19
    b19adda
    58ae0de
    27a070a
    9fce49f
    6661134
    #256
    c89ec18
    #260
    8d8bf9b
    #257
    6a460e0
    1.1.0
    #236
    9111b83
    #249
    17cbdfb
    #237
    e06296d
    #227
    a39cac6
    06a570e
    #210
    64d9dd5
    #222
    27e08aa
    #242
    534fd7f
    #233
    10f2acb
    #238
    e37287d
    #221
    0854208
    #231
    0df99b3
    3bee5a8
    e87e51f
    #243
    42dd057
    76956ef
    #245
    7229c7e
    8a0fbfc
    #251
    d5435c1
    #225
    720fcfc
    9b06e72