Aeternity

JellySwap aeternity package

What is JellySwap?

JellySwap is a cross-chain atomic swap protocol that supports many different blockchains. The aeternity package is used to interact with the Aeternity Hash Time Locked Contracts and to handle blockchain events. The main components of the module are Providers, Contract, Event, Adapter and Config.

Install package

Using yarn

$ yarn add @jelly-swap/aeternity@0.1.26-node

Using npm

$ npm install @jelly-swap/aeternity@0.1.26-node

Importing

JavaScript (ES3)

const jellyAeternity = require('@jelly-swap/aeternity');

JavaScript (ES6) / TypeScript

import * as jellyAeternity from '@jelly-swap/aeternity';

Config Module

This module contains the main configuration for the whole package.

const config = jellyAeternity.Config(token?, expiration?);

//Expected output
{ 
  network: 'AE',
  explorer: 'https://testnet.explorer.aepps.com/transactions/',
  providerUrl: 'https://sdk-testnet.aepps.com/',
  internalUrl: 'https://sdk-testnet.aepps.com/',
  compilerUrl: 'https://compiler.aepps.com',
  wsUrl: 'wss://testnet.aeternal.io/websocket',
  contractAddress: 'ct_2M9XPMwz1GggFRPatEd2aAPZbig32ZqRJBnhTT2yRVM4k6CQnb',
  receiverAddress: 'ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz',
  blockTime: 15,
  expiration: 10800,
  decimals: 18,
  unix: false,
  apiUrl: 'https://testnet.aeternal.io/' 
}

parameter

type

description

token

string

Name of the token (optional).

expiration

number

The Time Lock of the transaction (optional).

Provider Module

A Provider abstracts a connection to the Aeternity blockchain, for issuing queries and sending signed state changing transactions.

HTTP Provider - allows you to connect to Aeternity nodes you control or have access to, including mainnet, testnets, etc.

const httpProvider = new jellyAeternity.Providers.HTTP();

Waellet Provider

const waelletProvider = new jellyAeternity.Providers.Waellet();

Contract Module

Contract module is used to interact with the Sophia Contract and get blockchain specific data (balance, blockNumber, subscribe to events, get past events).

Create contract instance:

const aeternityContract = new jellyAeternity.Contract(provider);

parameter

type

description

provider

object

Provider instance that will be used for transaction signing.

subscribe

await jellyContract.subscribe(onEvent, filter?);

parameter

type

description

onEvent

function

Called when an event is received.

filter

function

Used to filter any received event (optional).

getPastEvents

Returns past blockchain events.

const pastEvents = await jellyContract.getPastEvents(eventType?, filter?, currentBlock?);

parameter

type

description

eventType

string

Can be 'new', 'withdraw' or 'refund' (optional). If not passed all events will be returned.

filter

function

Filter the received events (optional). If not passed all events will be returned.

currentBlock

number

Read events up to the currentBlock (optional). If not passed the currentBlock will be assigned to the latest mined block.

getCurrentBlock

Returns the latest block.

const currentBlock = await aeternityContract.getCurrentBlock();

getBalance

Returns the balance of the given address.

const balance = await aeternityContract.getBalance(address);

parameter

type

description

address

string

Aeternity Public Address.

getStatus

Returns the swaps statuses by given ids.

const statuses = await aeternityContract.getStatus(ids);

parameter

type

description

ids

array

List of ids.

newContract

Creates and broadcasts a new swap transaction.

const transactionHashSwap = await aeternityContract.newContract(swap);

parameter

type

description

swap

ContractSwap

Input data for the swap.

withdraw

Creates and broadcasts a withdraw transaction.

const transactionHashWithdraw = await aeternityContract.withdraw(withdraw);

parameter

type

description

withdraw

ContractSwap

Input data for the withdraw.

refund

Creates and broadcasts a refund transaction.

const transactionHashRefund = await aeternityContract.refund(contractRefund);

parameter

type

description

contractRefund

ContractRefund

Input data for the refund.

Event module

Event module is used to read past blockchain events and subscribe for new ones

Initialize event module:

const aeternityEvents = new jellyAeternity.Event(aeternityContract);

parameter

type

description

aeternityContract

AeternityContract

Aeternity contract instance.

getPast

Returns past blockchain events.

const pastEvents = await aeternityEvents.getPast(eventType, filter?, currentBlock?);

parameter

type

description

eventType

string

can be 'new', 'withdraw' or 'refund'

filter

function

Filter the received events (optional). If not passed all events will be returned.

currentBlock

number or string

Read events up to the currentBlock (optional). If not passed the currentBlock will be assigned to the latest mined block.

subscribe

await aeternityEvents.subscribe(onEvent, filter?);

parameter

type

description

onEvent

function

Called when an event is received.

filter

function

Used to filter any received event (optional). Adapter module.

Adapter module

The Adapter module is used to format the client data and prepare the input for the swaps.

Initialize adapter module:

const aeternityAdapter = new jellyAeternity.Adapter();

generateId

Generate swap id based on the input parameters. The same id will be generated by the Solidity Contract.

const id = aeternityAdapter.generateId(input);

parameter

type

description

input

ContractSwap

Input data for the swap.

addressValid

Checks if the passed address is valid or not.

const isAddressValid = aeternityAdapter.addressValid(address);

parameter

type

description

address

any

True if address is valid.

parseAddress

Returns the address in lower case.

const addressParsed = aeternityAdapter.parseAddress(address);

parameter

type

description

address

any

Address in lower case.

parseToNative

Parse AE amount to aetto amount i.e. 0.1 to 100000000000000000

const result = aeternityAdapter.parseToNative(amount);

parameter

type

description

amount

any

String representation of the aetto amount.

parseFromNative

Parse aetto amount to AE amount i.e. 100000000000000000 to 0.1

const result = aeternityAdapter.parseFromNative(amount);

parameter

type

description

amount

any

String representation of the AE amount.

formatInput

Returns object of type UserInputSwap.

const swapInput = aeternityAdapter.formatInput(data, receiver);

parameter

type

description

data

UserInputSwap

User input data.

receiver

string

Address of the receiver (optional). If not passed uses the receiver from the config.

Example

const jellyAeternity = require("@jelly-swap/aeternity");

const config = jellyAeternity.Config();

const httpProvider = new jellyAeternity.Providers.HTTP(config, {
  publicKey: "ak_SMwGaaRfryc8s7wPhpa1jzxAAtJfkWz2rZG5zrBny968Eqiqr",
  secretKey:
    "e6f7f740df605b297e1aec7326688ef8d31bed76d8e00f8f2ca76ff712938e373995cd2684368479b0d1069ea1471fc9926c0ca6489bc728f0b94c14c2c42fa0"
});

const adapter = new jellyAeternity.Adapter();

const { fixHash } = require("@jelly-swap/utils");

const aeternityContract = new jellyAeternity.Contract(httpProvider);

async function start() {
  // Subscribe for contract events and pass handle function
  await aeternityContract.subscribe(e => {
    console.log(e);
  });

  // Get past blockchain events
  const swaps = await aeternityContract.getPastEvents();
  console.log(swaps);
  //...
  // { eventName: 'NEW_CONTRACT',
  //      network: 'AE',
  //      id:
  //       'b15bc721ef3b6d50b110aebea870b0ddccb71221014a6e5ae76ee524fe9da990',
  //      sender: 'ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz',
  //      receiver: 'ak_SxZpugqQpL6qBpDd5mUjs5mbHhCLjSK9V3DGLxk1kXyc2Uj42',
  //      outputNetwork: 'ETH',
  //      outputAddress: '0xF684C21Ec023E93da0B402ac0a274317eb51C2c7',
  //      inputAmount: '95285930000000000000',
  //      outputAmount: '100000000000000000',
  //      expiration: '1577530273701',
  //      hashLock:
  //       '0x1f379a22ab114074d40e4fe7eb5c2493a1ddd3c0b7066e222d2087f0330f66df',
  //      transactionHash: 'th_2TiizaRHoSEiFQy1woCGi87sGV97cR7E9jiSFVqSMq1TopA1yB' }
  //...

  const withdraws = await aeternityContract.getPastEvents("withdraw", w => w);
  console.log(withdraws);
  //...
  // { eventName: 'WITHDRAW',
  //      network: 'AE',
  //      id:
  //       '0xc44499faac054495162e19b13f949ea4dbc2a327c2cf0c674be716f0a853cf19',
  //      sender: 'ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz',
  //      receiver: 'ak_2oJ2LR2N5jy5hZsxYnu9fynhUztbbuFyFp16ENPrkRidSVHCcL',
  //      hashLock:
  //       '0x97e7c1bb168c06e0d068c8d6b1f276eba8fc927f7cc6cb7943ee24d13e242329',
  //      secret:
  //       '0x1652d513caca3a90c18d93bd0ed358d546ff0bcc147e7128116da64fef3d4fc2',
  //      transactionHash: 'th_ozHApXME3zNxcp3QAL8PdE266DwmxiKFEw2WVaGpXEbm46Cjm' },
  //...

  const refunds = await aeternityContract.getPastEvents("refund", r => r);
  console.log(refunds);
  //...
  // { eventName: 'REFUND',
  //      network: 'AE',
  //      id:
  //       '0xeae5087c274a7d120f24b0568e23f35fcf57d8211888f745dfd5c0299af7f1c7',
  //      sender: 'ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz',
  //      receiver: 'ak_29GUBTrWTMb3tRUUgbVX1Bgwi2hyVhB8Q1befNsjLnP46Ub1V8',
  //      hashLock:
  //       '0x573d07a76d833e5ce4a69008496c23f3167be3ea224cd5dab821e36fc54d6205',
  //      transactionHash: 'th_1DRrRDMUacMZCLUaHQFGgj7HLzfTVy1vLKWascPAHNU8DzbAP' },
  //...

  const currentBlock = await aeternityContract.getCurrentBlock();
  console.log(currentBlock);
  //208446

  const balance = await aeternityContract.getBalance(
    "ak_SMwGaaRfryc8s7wPhpa1jzxAAtJfkWz2rZG5zrBny968Eqiqr"
  );
  console.log(balance);
  //999073430000000000

  const ids = [
    "0x3bdf9efc4b3324a0d7453a2572a85bbbfc091f3f2731b956ea13631169f860cb",
    "0a384aa9b6f7f9ca6c0cc748839ae2b1ec0a1b20f84d2381ad78b04e55d4d87d"
  ];

  const fixedIds = ids.map(i => fixHash(i, false));

  const statuses = await aeternityContract.getStatus(fixedIds);
  console.log("STATUSES", statuses);
  //STATUSES [ 'REFUNDED', 'EXPIRED' ]
  // REFUNDED: 1,
  // EXPIRED: 1

  // ================ SWAP ================
  const userInputSwap = {
    inputAmount: "1",
    outputAddress: "0xdd74dd2697206a910c42f9f5ef8c760a306483b8",
    outputAmount: "1",
    outputNetwork: "ETH",
    secret:
      "pond cram isolate kite float moon tongue firm spirit hand peace together",
    sender: "ak_SMwGaaRfryc8s7wPhpa1jzxAAtJfkWz2rZG5zrBny968Eqiqr"
  };

  const swap = adapter.formatInput(userInputSwap);
  console.log(swap);
  // { inputAmount: '1000000000000000000',
  // outputAddress: '0xdd74dd2697206a910c42f9f5ef8c760a306483b8',
  // outputAmount: '1',
  // outputNetwork: 'ETH',
  // secret: 'pond cram isolate kite float moon tongue firm spirit hand peace together',
  // sender: 'ak_SMwGaaRfryc8s7wPhpa1jzxAAtJfkWz2rZG5zrBny968Eqiqr',
  // expiration: 1581337000814,
  // hashLock: '0x2a0bb3c4377b6a1c854d24f06c93022fd8798397e315db1f51b6da2d40350907',
  // receiver: 'ak_2ifr2XxhrMskWdnXZqJE2mVhhwhXYvQD6nRGYLMR5mTSHW4RZz',
  // network: 'AE',
  // options: { amount: '1000000000000000000' } }

  //broadcast swap transaction
  try {
    await aeternityContract.newContract(swap);
  } catch (e) {
    console.log("Failed to get tx hash from AE explorer.");
  }

  // ================ REFUND ================
  const refund = {
    id: "b55da87ed3922def59ab1f3a55999082cb2abbe8ba42ccc492c9436644994f93"
  };

  try {
    const refundHash = await aeternityContract.refund(refund);
    console.log(refundHash);
  } catch (e) {
    console.log("Refund Error. Check timestamp and id params.");
  }

  // ================ WITHDRAW ================
  const withdraw = {
    id: "6a7206270cbc6efc60e117bcb762747dd7ca700e01d622f27ac35483ea222d2b",
    secret: "4e9d424bfac1c8c5b7de6da1968ca6ac72d27c33e9552e91c12ad57266f2c9c6"
  };

  try {
    const withdrawHash = await aeternityContract.withdraw(withdraw);
    console.log(withdrawHash);
  } catch (e) {
    console.log("Withdraw Error. Check timestamp, id and secret params.");
  }
}

Last updated