# icptopup-ts

> TypeScript agent for programmatically topping up canisters via ICPTopup

Latest version **0.0.1** (published 2025-02-08) · Apache-2.0 license · 0 weekly downloads

## Install

```sh
npm install icptopup-ts
pnpm add icptopup-ts
yarn add icptopup-ts
bun add icptopup-ts
```

## Health

**Score 30/100 (F)** — status: maintenance-mode.

Positive: has types; no vulnerabilities.

Warnings: low downloads; no esm support; pre 1.0.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 0.0.1 |
| Published | 2025-02-08 |
| First published | 2025-01-05 |
| Weekly downloads | 0 |
| License | Apache-2.0 |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 5 |
| Unpacked size | 997.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Maintainers | canscale |

## Links

- npm: https://www.npmjs.com/package/icptopup-ts
- Repository: https://github.com/CycleOperators/icptopup-ts
- Homepage: https://github.com/CycleOperators/icptopup-ts#readme
- Issues: https://github.com/CycleOperators/icptopup-ts/issues
- npm.io page: https://npm.io/package/icptopup-ts

## Dependencies (5)

- [@dfinity/agent](https://npm.io/package/@dfinity/agent.md) ^2.2.0
- [@dfinity/utils](https://npm.io/package/@dfinity/utils.md) ^2.8.0
- [@dfinity/candid](https://npm.io/package/@dfinity/candid.md) ^2.2.0
- [@dfinity/principal](https://npm.io/package/@dfinity/principal.md) ^2.2.0
- [@dfinity/ledger-icrc](https://npm.io/package/@dfinity/ledger-icrc.md) ^2.7.0

## Recent versions

- 0.0.1 (latest) — 2025-02-08
- 0.0.0-beta-2 — 2025-01-05
- 0.0.0-beta-1 — 2025-01-05
- 0.0.0-beta — 2025-01-05
- 0.0.0-alpha — 2025-01-05

## README

# icptopup-ts

TypeScript agent for programmatically topping up canisters via ICPTopup

- [Installation](#1-to-get-started-first-install-icptopup-ts)
- [Approving Funds for Topups](#2-approve-icptopup-to-mint-cycles-from-icp-on-your-behalf)
- [Usage](#3-instantiate-the-icptopup-actor)
- [Asynchronous Usage](#perform-an-asynchronous-topup)

## Topping up canisters from ICP

ICPTopup allows you to easily send cycles to up to 100 canisters at once.

### 1. To get started, first install icptopup-ts

`npm i icptopup-ts`

### 2. Approve ICPTopup to mint cycles from ICP on your behalf

```typescript
import ICPTopup from "icptopup-ts";

// in your function
const agent = HttpAgent.createSync({ identity, host: "https://ic0.app" });
const approvalBlockIndex = await ICPTopup.approveToSpendE8s({
  agent,
  e8sToApprove: BigInt(1e7), // approve a minimum of 0.1 ICP
});
```

### 3. Instantiate the ICPTopup Actor

In the agent, pass the identity that previously approved ICP to be spent by the ICPTopup service, and target the ICP mainnet host, https://ic0.app

```
const agent = HttpAgent.createSync({ identity, host: "https://ic0.app" });
const icpTopupActor = new ICPTopup(agent);
```

### 4. Call ICPTopup's synchronous `batchTopupSync()` API, or its [asynchronous](#perform-an-asynchronous-topup) topup API.

Both synchronous and asynchronous APIs allow you to specify:
`e8sToTransfer` - ICP transferred for minting cycles
`topupTargets` - the canisters being topped up.

The `topupProportion` in each topup target allows you to specify how much of the minted cycles you want to send to each canister. In the example below, there are 3 proportions total (2 + 1), and so 2/3rds of the minted cycles are being sent to the first canister, and 1/3rd of the minted cycles are sent to the second canister.

```TypeScript
  const result = await icpTopupActor.batchTopupSync({
    // Note: make sure the icp account spent from has enough e8s for the ledger transfer (10_000 e8s)
    e8sToTransfer: BigInt(1e7), // 0.1 ICP
    topupTargets: [
      {
        canisterId: Principal.fromText("qc4nb-ciaaa-aaaap-aawqa-cai"),
        topupProportion: 2n, // send up 2/3rds of the minted cycles here
      },
      {
        canisterId: Principal.fromText("gf3bz-2aaaa-aaaap-ahngq-cai"),
        topupProportion: 1n, // send 1/3rd of the minted cycles here
      },
    ],
  });
```

## Check your ICPTopup account allowance

The `ICPTopup.checkAllowance()` API provides a simple wrapper determining your ICP allowance with ICPTopup

```TypeScript
  const allowance = await ICPTopup.checkAllowance({
    account: {
      owner: identity.getPrincipal(),
      subaccount: [],
    },
  });
```

## Perform an asynchronous topup

ICPTopup usually takes 20-30 seconds to complete a topup.

While the synchronous `batchTopupSync()` API executes topups synchronously leaving the caller waiting for a response, the `batchTopupAsync()` API immediately returns a request identifier that can be used to immediately poll for the result of the topup.

Kicking off an asynchronous topup is nearly identical to a synchronous one.

```TypeScript
  // Kick off the topup
  const result = await icpTopupActor.batchTopupAsync({
    e8sToTransfer: BigInt(1e7), // 0.1 ICP
    topupTargets: [
      {
        canisterId: Principal.fromText("qc4nb-ciaaa-aaaap-aawqa-cai"),
        topupProportion: 1n, // send up 1/2 of the minted cycles here
      },
      {
        canisterId: Principal.fromText("gf3bz-2aaaa-aaaap-ahngq-cai"),
        topupProportion: 1n, // send 1/2 of the minted cycles here
      },
    ],
  });
```

And you can check the status of an asynchronous topup in two ways:

### 1. Check the latest status of the requestId with `getLatestTopupRequestStatus()`

```TypeScript
  if (!("ok" in topupResponse)) {
    throw new Error(
      "Async topup failed to kick off with error: " + topupResponse.err,
    );
  }

  const requestId = topupResponse.ok; // request id associated with the topup
  const latestRequestStatus = await ICPTopup.getLatestTopupRequestStatus(requestId);
```

Or

### 2. Poll for the final topup result with `pollAsyncStatusUntilComplete()`

```TypeScript
  await ICPTopup.pollAsyncStatusUntilComplete({
    requestId,
    pollIntervalInMs: 5000, // optional, defaults to 5sec
    logStatusUpdates: true, // optional, use if you want to output status update console logs
  });
```

---
_Source: https://npm.io/package/icptopup-ts · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
