# @inco/js

The @inco/js package contains the TypeScript SDK for creating dapps built on Inco.

## Current Status: Active Development

The SDK is currently going through active development, to support all new features that Inco offers. As such, do expect breaking changes in subsequent releases, which will be documented in the [CHANGELOG](./CHANGELOG.md).

## Install

Choose your favorite package manager:

```bash
npm install @inco/js
# or
bun install @inco/js
# or
yarn add @inco/js
```

## Usage

A typical usage of `@inco/js` includes 3 steps:

1. Encrypting a value.
2. Posting the ciphertext to the contract, which will perform confidential computes on it.
3. Requesting an attested decryption of the result of the computation.

### 1. Encrypt a value

```ts
import { getViemChain, supportedChains } from '@inco/js';
import { Lightning } from '@inco/js/lite';
import { createWalletClient } from 'viem';

// Setup: do it once at initialization
const chainId = supportedChains.baseSepolia;
const zap = Lightning.latest('testnet', chainId); // Connect to Inco's latest public testnet
const walletClient = createWalletClient({
  chain: getViemChain(chainId),
  account: /* Choose your account, e.g. from window.ethereum */,
  transport: /* Choose your transport, e.g. from Alchemy */,
});
const dappAddress = '0x00000000000000000000000000000000deadbeef'; // Put your contract address here

// Encrypt the plaintext value
const plaintext = 42;
const ciphertext = await zap.encrypt(plaintext, {
  accountAddress: walletClient.account.address,
  dappAddress,
});

console.log(ciphertext); // A long hex string representing the encrypted value
```

### 2. Post the ciphertext to the contract

This step does not require any specific `@inco/js` functionality. We recommend using [viem](https://viem.sh) to interact with the blockchain. Specifically, use the [`writeContract`](https://viem.sh/docs/contract/writeContract) method to submit transactions. Pass the `ciphertext` from the previous encryption step as the input ciphertext parameter of type `bytes`.

### 3. Request a reencryption

Following transaction submission, the Inco covalidator processes the computation request. The contract stores the computation result as a handle on-chain. This handle, referenced below as `resultHandle`, is a hexadecimal string of type `Handle` that serves as a reference to the encrypted computation output.

```ts
import { Hex } from "viem";

// Request a re-encryption of the result ciphertext
const resultHandle = "0x..." as Hex; // Retrieve the handle from the contract, e.g. using viem
// Use same walletClient as previous step
const resultPlaintext = await zap.attestedDecrypt(walletClient, [resultHandle]);

console.log(resultPlaintext[0].plaintext.value); // The decrypted value
```

Handles are processed asynchronously so you may need to wait for our covalidators to catch and compute the value. If you request an attested decryption before it has been processed you will get an error. To help ameliorate this the `attestedDecrypt` has built-in retries, you can further customise by passing a `BackoffConfig` as an extra argument:

```ts
type BackoffConfig = {
  maxRetries: number;
  baseDelayInMs: number;
  backoffFactor: number;
};

const resultHandle = "0x..." as Hex;
// Default backoff config shown for reference
const backoffConfig: BackoffConfig = {
  maxRetries: 10,
  baseDelayInMs: 1000,
  backoffFactor: 1.5,
};
const resultPlaintext = await zap.attestedDecrypt(
  walletClient,
  [resultHandle],
  backoffConfig,
);
```

## License

See the [LICENSE](./LICENSE) file.
