# JavaScript SDK

The SDK provides a way to programmatically interact with 8Pay's smart contracts.

It allows you to manage the subscriptions to your plans (e.g. trigger billings or terminate them).

## Installation

This is a [Node.js](https://nodejs.org/en/) module available through the [npm registry](https://www.npmjs.com/).

Before installing, [download and install Node.js](https://nodejs.org/en/download/).

Installation is done using the command:

```bash
$ npm install @8pay/sdk
```

To see all package details on the npm registry, click [here](https://www.npmjs.com/package/@8pay/sdk).

## Usage

This module uses [web3](https://www.npmjs.com/package/web3) under the hood, which is the most popular library used to interact with the `Web 3.0`.

To keep things familiar with `web3`, it follows the same strucure when sending transactions but adds additional functionalities.

To get started, import the module and provide it with an instance of `web3`:

```javascript
const Web3 = require('web3');
const EightPaySDK = require('@8pay/sdk');

const web3 = new Web3('<provider-url>');
const eightPay = new EightPaySDK(web3, EightPaySDK.Network.BSC);
```

### Sending transactions

There are two ways to sign a transaction before broadcasting it to the blockchain:

* Using an unlocked account (e.g. when using Metamask)

```javascript
eightPay.fixedRecurring.bill(planId, subscriptionIds)
    .send({ from: account })
```

* With privateKey

```javascript
eightPay.fixedRecurring.bill(planId, subscriptionIds)
    .send({ privateKey: '0x32df7......' })
```

### Estimate gas

The gas consumed by a transaction can be estimated using the `estimateGas` function which takes and `options`object and returns the amount of gas as number:

```javascript
eightPay.fixedRecurring.bill(planId, subscriptionIds)
    .estimateGas(options)
```

### Options

The `send` method accepts the same options available in `web3` like `gas`, `gasPrice`, `nonce` and so on.

### Events

The following events are emitted when sending a transaction: `transactionHash`, `receipt`, `confirmation` and `error`.

```javascript
const receipt = await eightPay.fixedRecurring.bill(planId, subscriptionIds)
    .send({ from: account })
    .on('transactionHash', hash => {})
    .on('receipt', receipt => {})
    .on('confirmation', confirmation => {})
    .on('error', error => {})
```

## Methods

Here is the list of all the available methods for each billing model.

### Fixed Recurring

#### Bill

Bills subscriptions of a plan.

Parameters:

* **planId** - id of the plan
* **subscriptionIds** - array of subscription ids

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];

const receipt = await eightPay.fixedRecurring.bill(planId, subscriptionIds)
    .send({ from: account })
```

#### Terminate

Forcefully cancels subscriptions of a plan.

The sender account must be the plan's admin or an operational account with terminate permission.

Parameters:

* **planId** - id of the plan
* **subscriptionIds** - array of subscription ids

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];

const receipt = await eightPay.fixedRecurring.terminate(planId, subscriptionIds)
    .send({ from: account })
```

### Variable Recurring

#### Bill

Bills subscriptions of a plan.

The sender account must be the plan's admin or an operational account with bill permission.

Parameters:

* **planId** - id of the plan
* **subscriptionIds** - array of subscription ids
* **amounts** - array of amounts to charge for each subscription

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];
const amounts = [eightPay.utils.parseAmount('10', '8PAY')];

const receipt = await eightPay.variableRecurring.bill(planId, subscriptionIds, amounts)
    .send({ from: account })
```

#### Terminate

Forcefully cancels subscriptions of a plan.

The sender account must be the plan's admin or an operational account with terminate permission.

Parameters:

* **planId** - id of the plan
* **subscriptionIds** - array of subscription on-chain ids

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];

const receipt = await eightPay.variableRecurring.terminate(planId, subscriptionIds)
    .send({ from: account })
```

### On Demand

#### Bill

Bills subscriptions of a plan.

The sender account must be the plan's admin or an operational account with bill permission.

Parameters:

* **planId** - id of the plan
* **subscriptionIds** - array of subscription ids
* **amounts** - array of amounts to charge for each subscription

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];
const amounts = [eightPay.utils.parseAmount('10', '8PAY')];

const receipt = await eightPay.onDemand.bill(planId, subscriptionIds, amounts)
    .send({ from: account })
```

#### Terminate

Forcefully cancels subscriptions of a plan.

The sender account must be the plan's admin or an operational account with terminate permission.

Parameters:

* **planId** - id of the plan
* subscriptionIds - array of subscription ids

```javascript
const planId = '0x57b2059e526841b3dfd964144513359c9fcfd6d91040b6c47f589c1e032b6bf4';
const subscriptionIds = ['0xe63ba761797e289076f80a7c0916a31740684806aaf507da85f81ee785fec6ba'];

const receipt = await eightPay.onDemand.terminate(planId, subscriptionIds)
    .send({ from: account })
```

## Accounts

The accounts utility can be used to obtain an account object from a private key or a mnemonic. The account object has two properties: `address` and `privateKey`.

```javascript
const privateKey = '<private-key>';
const account = eightPay.accounts.fromPrivateKey(privateKey);

// OR

const mnemonic = '<mnemonic>';
const mnemonicIndex = 0;
const account = eightPay.accounts.fromMnemonic(mnemonic, mnemonicIndex);

console.log(account);

/*
{
    address: '0x2F2....',
    privateKey: '0x1Ee...'
}
*/
```

## Utils

To help in parsing amount from and to ethereum decimals, you can use `addDecimals` and `parseDecimals` methods.

```javascript
const parsedAmount = eightPay.utils.parseAmount('1', '8PAY') // 1000000000000000000
const amount = eightPay.utils.formatAmount(parsedAmount, '8PAY') // 1
```
