npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@keygate/onesec

v0.10.4

Published

A library for interacting with the onesec.to bridge

Readme

OneSec Bridge SDK

A TypeScript SDK for bridging tokens between EVM chains (Ethereum, Arbitrum, Base) and the Internet Computer (ICP) using the OneSec bridge protocol.

Features

  • Bi-directional bridging: Transfer tokens from EVM chains to ICP and vice versa
  • Multiple bridging modes: Direct wallet-based bridging and forwarding address bridging
  • Step-by-step execution: Track progress and handle errors at each step

Installation

# with npm
npm install onesec-bridge
# with pnpm
pnpm add onesec-bridge
# with yarn
yarn add onesec-bridge

Quick Start

EVM to ICP Bridging (Direct)

Use this approach when users can connect their wallet and sign transactions directly.

import { EvmToIcpBridgeBuilder } from "onesec-bridge";
import { JsonRpcProvider, Wallet } from "ethers";
import { Principal } from "@dfinity/principal";

// Setup wallet or use the browser wallet API.
const provider = new JsonRpcProvider("https://mainnet.base.org");
const wallet = new Wallet("your-private-key", provider);

// Create bridging plan
const plan = await new EvmToIcpBridgeBuilder("Base", "USDC")
  .receiver(Principal.fromText("your-icp-principal"))
  .amountInTokens(1_500_000n) // 1.5 USDC
  // alternative: use `.amountInTokens(1.5)`
  .build(wallet);

// Print plan overview
console.log("Plan steps:");
plan.steps().forEach((step, index) => {
  console.log(`  ${index + 1}. ${step.about().verbose}`);
});

// Execute step by step with progress tracking
let nextStep;
while (nextStep = plan.nextStepToRun()) {
  const status = nextStep.status();
  if (status.state === "planned") {
    console.log(nextStep.about().verbose);
  }
  try {
    const result = await nextStep.run();
    console.log(`  - ${result.verbose}`);
  } catch (error) {
    console.error("Step execution failed:", error);
    break;
  }
}

// Get final results after completion
const finalStep = plan.latestStep();
if (finalStep) {
  const status = finalStep.status();
  if (status.state === "succeeded") {
    console.log("Bridging completed successfully!");
    if (status.amount) {
      console.log(`Received: ${status.amount.inTokens} USDC`);
    }
    if (status.transaction) {
      console.log(`Transaction: ${JSON.stringify(status.transaction)}`);
    }
  }
}

EVM to ICP Bridging (Forwarding Address)

Use this approach when users cannot connect a wallet or prefer to send tokens manually.

import { EvmToIcpBridgeBuilder } from "onesec-bridge";
import { Principal } from "@dfinity/principal";

// Create forwarding-based bridging plan
const plan = await new EvmToIcpBridgeBuilder("Base", "USDC")
  .receiver(Principal.fromText("your-icp-principal"))
  .forward();

// Execute with progress tracking
let nextStep;
while (nextStep = plan.nextStepToRun()) {
  const status = nextStep.status();
  if (status.state === "planned") {
    console.log(nextStep.about().verbose);
  }
  try {
    const result = await nextStep.run();
    console.log(`  - ${result.verbose}`);
    
    // Show forwarding address to user
    if (result.forwardingAddress) {
      console.log(`Please send USDC to: ${result.forwardingAddress}`);
      // Wait for user to send tokens before continuing
    }
  } catch (error) {
    console.error("Step execution failed:", error);
    break;
  }
}

// Get final results after completion
const finalStep = plan.latestStep();
if (finalStep) {
  const status = finalStep.status();
  if (status.state === "succeeded") {
    console.log("Bridging completed successfully!");
    if (status.amount) {
      console.log(`Received: ${status.amount.inTokens} USDC`);
    }
    if (status.transaction) {
      console.log(`ICP Transaction: ${JSON.stringify(status.transaction)}`);
    }
  }
}

ICP to EVM Bridging

Transfer tokens from ICP to EVM chains. Requires an authenticated ICP agent.

import { IcpToEvmBridgeBuilder } from "onesec-bridge";
import { HttpAgent } from "@dfinity/agent";
import { Secp256k1KeyIdentity } from "@dfinity/identity-secp256k1";

// Setup ICP identity and agent
const identity = Secp256k1KeyIdentity.fromSecretKey(/* your private key */);
const agent = HttpAgent.createSync({
  identity,
  host: "https://ic0.app",
});

// Create bridging plan
const plan = await new IcpToEvmBridgeBuilder(agent, "Base", "USDC")
  .sender(identity.getPrincipal())
  .receiver("0x742d35Cc6575C4B9bE904C1e13D21c4C624A9960")
  .amountInUnits(1_500_000n) // 1.5 USDC
  // alternative: use `.amountInTokens(1.5)`
  .build();

// Execute with progress tracking
let nextStep;
while (nextStep = plan.nextStepToRun()) {
  const status = nextStep.status();
  if (status.state === "planned") {
    console.log(nextStep.about().verbose);
  }
  try {
    const result = await nextStep.run();
    console.log(`  - ${result.verbose}`);
  } catch (error) {
    console.error("Step execution failed:", error);
    break;
  }
}

// Get final results after completion
const finalStep = plan.latestStep();
if (finalStep) {
  const status = finalStep.status();
  if (status.state === "succeeded") {
    console.log("Bridging completed successfully!");
    if (status.amount) {
      console.log(`Received: ${status.amount.inTokens} USDC`);
    }
    if (status.transaction) {
      console.log(`EVM Transaction: ${JSON.stringify(status.transaction)}`);
    }
  }
}

Supported Networks and Tokens

EVM Chains

  • Ethereum
  • Arbitrum
  • Base

Tokens

  • USDC
  • USDT
  • ICP
  • ckBTC
  • cbBTC
  • BOB
  • GLDT

Migration from v0.7.x

If you're using the deprecated oneSecForwarding() function:

// Old approach (deprecated)
const forwarding = oneSecForwarding();
const address = await forwarding.addressFor(receiver);

// New approach
const plan = await new EvmToIcpBridgeBuilder("Base", "USDC")
  .receiver(principal)
  .amountInUnits(amount)
  .forward();

Documentation

-

:factory: IcpToEvmBridgeBuilder

Builder for creating ICP to EVM token bridging plans.

Transfers tokens from ICP ledgers to EVM networks. Requires an authenticated agent to interact with ICP canisters on behalf of the user.

:link: Source

Methods

:gear: deployment

Set target deployment network.

| Method | Type | | ---------- | ---------- | | deployment | (deployment: Deployment) => IcpToEvmBridgeBuilder |

Parameters:

  • deployment: Target network ("Mainnet", "Testnet", or "Local")

:link: Source

:gear: sender

Set sender ICP account.

| Method | Type | | ---------- | ---------- | | sender | (principal: Principal, subaccount?: Uint8Array<ArrayBufferLike> or undefined) => IcpToEvmBridgeBuilder |

Parameters:

  • principal: ICP principal sending the tokens
  • subaccount: Optional 32-byte subaccount

:link: Source

:gear: receiver

Set EVM recipient address.

| Method | Type | | ---------- | ---------- | | receiver | (address: string) => IcpToEvmBridgeBuilder |

Parameters:

  • address: EVM address receiving the tokens

:link: Source

:gear: amountInUnits

Set amount to bridge in token's smallest units.

| Method | Type | | ---------- | ---------- | | amountInUnits | (amount: bigint) => IcpToEvmBridgeBuilder |

Parameters:

  • amount: Amount in base units (e.g., 1_500_000n for 1.5 USDC)

:link: Source

:gear: amountInTokens

Set amount to bridge in human-readable token units.

| Method | Type | | ---------- | ---------- | | amountInTokens | (amount: number) => IcpToEvmBridgeBuilder |

Parameters:

  • amount: Amount in token units (e.g., 1.5 for 1.5 USDC)

:link: Source

:gear: payApproveFeeFromAmount

Deduct the ledger approval fee from the bridging amount.

When enabled, the approval fee is subtracted from the specified amount, so the user only needs to have exactly the bridging amount in their account rather than bridging amount + approval fee.

| Method | Type | | ---------- | ---------- | | payApproveFeeFromAmount | () => IcpToEvmBridgeBuilder |

Examples:

// Without payApproveFeeFromAmount(): User needs 1.5 USDC + approval fee
const plan1 = await builder.amountInUnits(1_500_000n).build();

// With payApproveFeeFromAmount(): User needs exactly 1.5 USDC, approval fee deducted from amount
const plan2 = await builder.amountInUnits(1_500_000n).payApproveFeeFromAmount().build();

:link: Source

:gear: withConfig

Use custom configuration instead of defaults.

| Method | Type | | ---------- | ---------- | | withConfig | (config: Config) => IcpToEvmBridgeBuilder |

Parameters:

  • config: Custom bridge configuration

:link: Source

:factory: EvmToIcpBridgeBuilder

Builder for creating EVM to ICP token bridging plans.

Supports two bridging modes:

  • Direct bridging via build() - requires user to connect wallet and sign transactions
  • Forwarding via forward() - user sends tokens to a generated forwarding address

:link: Source

Methods

:gear: deployment

Set target deployment network.

| Method | Type | | ---------- | ---------- | | deployment | (deployment: Deployment) => EvmToIcpBridgeBuilder |

Parameters:

  • deployment: Target network ("Mainnet", "Testnet", or "Local")

:link: Source

:gear: sender

Set sender EVM address. Optional for direct bridging (inferred from signer).

| Method | Type | | ---------- | ---------- | | sender | (evmAddress: string) => EvmToIcpBridgeBuilder |

Parameters:

  • evmAddress: EVM address sending the tokens

:link: Source

:gear: amountInUnits

Set amount to bridge in token's smallest units.

| Method | Type | | ---------- | ---------- | | amountInUnits | (amount: bigint) => EvmToIcpBridgeBuilder |

Parameters:

  • amount: Amount in base units (e.g., 1_500_000n for 1.5 USDC)

:link: Source

:gear: amountInTokens

Set amount to bridge in human-readable token units.

| Method | Type | | ---------- | ---------- | | amountInTokens | (amount: number) => EvmToIcpBridgeBuilder |

Parameters:

  • amount: Amount in token units (e.g., 1.5 for 1.5 USDC)

:link: Source

:gear: receiver

Set ICP recipient account.

| Method | Type | | ---------- | ---------- | | receiver | (principal: Principal, subaccount?: Uint8Array<ArrayBufferLike> or undefined) => EvmToIcpBridgeBuilder |

Parameters:

  • principal: ICP principal receiving the tokens
  • subaccount: Optional 32-byte subaccount

:link: Source

:gear: withConfig

Use custom configuration instead of defaults.

| Method | Type | | ---------- | ---------- | | withConfig | (config: Config) => EvmToIcpBridgeBuilder |

Parameters:

  • config: Custom bridge configuration

:link: Source

License

MIT

Support

For issues and questions: