npm package: @pisa-research/client
Description: A client library for the PISA API.
Author: PISA Research Ltd
Latest version: 0.1.44

# PISA API Client

A thin client for the PISA API.

The client library supports **relay** and **event triggered** appointments. If no event information is provided when generating an appointment request then a relay appointment will be created.

See the API docs at /docs.html of the API for the complete list of parameters that are expected from the PISA API endpoint, including the parameters that are generated by this API client, whose description is here omitted.

# Hosted instances

Ropsten: https://alpha.pisa.watch \
Ropsten contract instance: [0xA02C7260c0020343040A504Ef24252c120be60b9](https://ropsten.etherscan.io/address/0xA02C7260c0020343040A504Ef24252c120be60b9)\
Ropsten API docs: https://alpha.pisa.watch/docs.html

# PisaClient

The API exports a single class called `PisaClient`, whose constructor takes two parameters: the url of the PISA API server, and the address of the PISA contract.
```
const PISA_API_URL = "https://alpha.pisa.watch";
const PISA_CONTRACT_ADDRESS = "0xA02C7260c0020343040A504Ef24252c120be60b9";

const pisaClient = new PisaClient(PISA_API_URL, PISA_CONTRACT_ADDRESS);
```

The `pisaClient` object exposes a `generateAndExecuteRequest` method to call the PISA API and interpret the response.

## generateAndExecuteRequest

```
generateAndExecuteRequest(
    signer: (digest: string) => Promise<string>,
    customerAddress: string,
    id: string,
    nonce: number,
    startBlock: number,
    endBlock: number,
    contractAddress: string,
    data: string,
    gasLimit: number,
    challengePeriod: number,
    eventAddress?: string,
    topics?: (string | null)[]
): Promise<AppointmentReceipt>
```

This method creates a requests for an appointment and calls the PISA endpoint. The return value is a Promise that resolves to an `AppointmentReceipt` if the request was successful, or is rejected in case of error.

- `signer`: a callback function that is given a digest of the encoded appointment, and must return the customer's signature.
- `customerAddress`: the checksummed address of the customer.
- `id`: a unique id chosen by the customer.
- `nonce`: a counter that can be incremented by the customer in order to replace a previous appointment with the given id.
- `startBlock`: the block when the appointment starts.
- `endBlock`: the block when the appointment ends.
- `contractAddress`: the address of the external contract to which the data will be submitted by PISA
- `data`: an ABI encoded function and arguments that will be executed at the contract address by PISA when the event specified by the appointment is observed.
- `gasLimit`: the amount of gas that will be supplied when calling the external contract. The maximum value is 2 million.
- `challengePeriod`: the number of blocks that PISA has to respond from the block height where an event is observed. It must be at least 100.

If `eventAddress` and `topics` are omitted, the request is for a ''relay'' appointment and PISA wil respond without waiting for a trigger. Otherwise:

- `eventAddress`: The address from which the trigger event is emitted.
- `topics`: An array of up to 4 elements. Each element is either a topic that must match for the event to be considered a trigger, or `null` if the corresponding log entry (if any) is to obe ignored.

## generateRequest and executeRequest

The `pisaClient` object also exports lower level methods `generateRequest` and `executeRequest`.

`generateRequest` has the same parameters as `generateAndExecuteRequest`, but returns a `SignedAppointmentRequest` instead of calling the PISA API. The returned signed appointment request can then be send to PISA by calling `executeRequest` with the signed appointment request.

## getAppointmentsByCustomer

The `getAppointmentsByCustomer` method can be use to query the API in order to retrieve all the appointments for a specific customer.

- `signer`: a callback function that is given the current block number, and must return the customer's signature.
- `customerAddress`: the checksummed address of the customer.
- `currentBlockNumber`: the most recent block number.

## backup and restore

The `backup` and `restore` methods allow to hire Pisa to store and retrieve some data.

The `backup` methods has the following parameters:
- `signer`: a function to sign the PISA appointment.
- `data`: the data to backup.
- `customerAddress`: the customer address backing up the data.
- `startBlock`: the start block from when the backup should begin - should be within 5 blocks of the current block. Backup will be held for 60,000 blocks.
- `id`: the id for this backup.
- `nonce`: the version of this backup. A backup can be replaced by providing the same backup id but a greater nonce.

The `restore` method has the following parameters:
- `signer`: a callback function that is given the current block number, and must return the customer's signature.
- `customerAddress`: the checksummed address of the customer.
- `currentBlockNumber`: the most recent block number.

# Simple example with ethers.js

In this example we use an ethers.js wallet to sign the digest, and we then use `generateAndExecuteRequest` to hire Pisa.

```
const PISA_API_URL = "https://alpha.pisa.watch";
const PISA_CONTRACT_ADDRESS = "0xA02C7260c0020343040A504Ef24252c120be60b9";

// metadata info
const userWallet; // an ethersjs wallet
const appointmentId = "0x61f307f9dc16833ff12d511e22a20ac2a4d0adaa2f48292ebad9e0c80a2bb75d";
const nonce = 0;
const startBlock; // current block height just retrieved from a provider
const endBlock = startBlock + 200;

// response info
const responseAddress = "0x81b7e08f65bdf5648606c89998a9cc8164397647";
const responseData = "0x28fbdf0d000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000";
const gasLimit = 100000;
const challengePeriod = 200;

// event info
const eventAddress = "0x9e64b53b935602cd0657343C69Fe200fb3cD05c8";
const topics = ["0x73ea0ff8e52eea08c37acf9b1de68b2f0039fd344d83d2563e2b266b073a93d4", null, "0x0000000000000000000000000000000000000000000000000000000000000001"];

const pisaClient = new PisaClient(PISA_API_URL, PISA_CONTRACT_ADDRESS);
const receipt = await pisaClient.generateAndExecuteRequest(
    digest => userWallet.signMessage(arrayify(digest)),
    userWallet.address,
    appointmentId,
    nonce,
    startBlock,
    endBlock,
    responseAddress,
    responseData,
    gasLimit,
    challengePeriod,
    eventAddress,
    topics
);
```