# 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
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.8pay.network/integrations/javascript-sdk.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
