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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gasfree-kit/intent

v0.2.0

Published

Chain-abstracted stablecoin payment intents — powered by gasfree-kit

Readme

@gasfree-kit/intent

Chain-abstracted stablecoin payment intents for EVM chains.

Declare what you want ("send 50 USDT to this address") and the SDK handles multi-chain balance discovery, route planning, cross-chain bridging, and gasless execution automatically.

How It Works

 ┌──────────────────────────────────────────────────────────┐
 │                        Your app                          │
 └────────────────────────────┬─────────────────────────────┘
                              │
                              v
 ┌──────────────────────────────────────────────────────────┐
 │               @gasfree-kit/intent                        │
 │                                                          │
 │   discoverBalances ─> planIntent ─> executeIntent        │
 │                                                          │
 │   Routes:  direct  |  bridge  |  aggregate               │
 └────────┬──────────────────┬──────────────────┬───────────┘
          │                  │                  │
          v                  v                  v
 ┌────────────────┐ ┌────────────────┐ ┌────────────────────┐
 │ @gasfree-kit/  │ │ WDK USDT0      │ │  Multi-chain RPC   │
 │ evm-4337       │ │ bridge         │ │  (balance queries)  │
 │                │ │ (LayerZero)    │ │                    │
 │ ERC-4337       │ │                │ │  eth_call per chain │
 │ UserOps        │ │ Cross-chain    │ │                    │
 └────────────────┘ └────────────────┘ └────────────────────┘

Supported Chains

| Chain | Chain ID | Direct transfer | Bridge source | | -------- | -------- | --------------- | ------------- | | Ethereum | 1 | Yes | Yes | | Base | 8453 | Yes | Yes | | Arbitrum | 42161 | Yes | Yes | | Optimism | 10 | Yes | Yes | | Polygon | 137 | Yes | Yes | | Celo | 42220 | Yes | Yes | | Plasma | 9745 | Yes | Yes |

Prerequisites

This package depends on:

Both are installed automatically as dependencies.

Installation

npm install @gasfree-kit/intent

Required peer dependency:

npm install @tetherto/wdk-wallet-evm-erc-4337

Optional peer dependency (for cross-chain bridging):

npm install @tetherto/wdk-protocol-bridge-usdt0-evm

Quick Start

5-line integration

import { GasfreeIntent } from '@gasfree-kit/intent';

const intent = GasfreeIntent.create({
  chains: ['base', 'arbitrum', 'optimism'],
  signer: { seedPhrase },
  bundlerUrl: 'https://your-bundler.example.com',
  paymasterUrl: 'https://your-paymaster.example.com',
  isSponsored: true,
  sponsorshipPolicyId: 'your-policy-id',
});

const receipt = await intent.sendIntent({
  from: senderAddress,
  to: merchantAddress,
  amount: '50.00',
});

console.log(receipt.status); // "completed"

Step by step

1. Create a config

import type { IntentConfig } from '@gasfree-kit/intent';

const config: IntentConfig = {
  chains: ['base', 'arbitrum', 'optimism', 'polygon', 'celo'],
  signer: { seedPhrase: 'your twelve word seed phrase ...' },
  bundlerUrl: 'https://your-bundler.example.com',
  paymasterUrl: 'https://your-paymaster.example.com',
  isSponsored: true,
  sponsorshipPolicyId: 'your-policy-id',
  // Enable cross-chain bridging (requires wdk-protocol-bridge-usdt0-evm):
  // bridgeConfig: { enabled: true },
};

2. Discover balances

import { GasfreeIntent } from '@gasfree-kit/intent';

const intent = GasfreeIntent.create(config);

const balances = await intent.discoverBalances(senderAddress);

console.log(balances.total); // "83.50"
console.log(balances.chains); // [{ chain: 'base', balance: '50.00', ... }, ...]

3. Plan the intent

const plan = await intent.planIntent({
  from: senderAddress,
  to: merchantAddress,
  amount: '50.00',
});

console.log(plan.route); // "direct" | "bridge" | "aggregate"
console.log(plan.steps); // ordered execution steps
console.log(plan.estimatedFee); // "0" (sponsored) or "0.15" etc.

4. Execute the plan

const receipt = await intent.executeIntent(plan);

console.log(receipt.status); // "completed" | "partial" | "failed"
console.log(receipt.totalFee); // actual fee paid
console.log(receipt.executionTime); // ms

Route Types

The planner selects the simplest feasible route:

| Route | When | Steps | | --------- | ------------------------------------------ | ---------------------- | | Direct | Sender has enough on the destination chain | 1 transfer | | Bridge | One other chain has enough | 1 bridge + 1 transfer | | Aggregate | Balance split across multiple chains | N bridges + 1 transfer |

Bridge and aggregate routes require bridgeConfig: { enabled: true } in the config. Without it, only direct routes are planned.

Events

Subscribe to lifecycle events for real-time UI feedback:

intent.on('balances:discovered', (event) => {
  console.log('Balances:', event.data);
});

intent.on('step:started', (event) => {
  console.log('Starting step:', event.data);
});

intent.on('step:completed', (event) => {
  console.log('Step done:', event.data);
});

intent.on('intent:completed', (event) => {
  console.log('Payment complete:', event.data);
});

intent.on('recovery:needed', (event) => {
  console.log('Recovery info:', event.data);
});

All event types: balances:discovered, plan:created, step:started, step:completed, step:failed, intent:completed, intent:failed, recovery:needed.

Event handler exceptions are swallowed and never affect execution.

Configuration Reference

| Parameter | Type | Default | Description | | --------------------- | -------------------------------------- | -------- | --------------------------------------------- | | chains | EvmChain[] | Required | EVM chains to discover balances on | | signer | IntentSigner | Required | { seedPhrase, accountIndex? } | | bundlerUrl | string | Required | Candide ERC-4337 bundler endpoint | | paymasterUrl | string | Required | Candide paymaster endpoint | | isSponsored | boolean | Required | Whether gas is sponsored | | sponsorshipPolicyId | string | - | Required when isSponsored is true | | paymasterAddress | string | - | Paymaster contract (non-sponsored mode) | | chainOverrides | Partial<Record<EvmChain, overrides>> | - | Per-chain RPC, bundler, paymaster overrides | | bridgeConfig | { enabled: boolean, ... } | disabled | Must be { enabled: true } for bridge routes | | balanceCacheTTL | number | 15000 | Balance cache TTL in ms | | bridgeTimeout | number | 300000 | Bridge step timeout in ms (5 min) | | transferTimeout | number | 120000 | Transfer step timeout in ms (2 min) | | maxRetries | number | 3 | Auto-retries per step on transient failure | | rpcFallbacks | Partial<Record<EvmChain, string[]>> | - | Fallback RPC URLs per chain | | onStatusChange | (event: IntentEvent) => void | - | Shorthand callback for all lifecycle events |

Error Handling

All errors extend GasfreeError from @gasfree-kit/core:

import {
  IntentValidationError,
  RoutePlanningError,
  InsufficientCrossChainBalanceError,
  BridgeError,
  IntentTimeoutError,
  IntentExecutionError,
} from '@gasfree-kit/intent';

try {
  await intent.sendIntent({ from, to, amount: '50.00' });
} catch (error) {
  if (error instanceof InsufficientCrossChainBalanceError) {
    console.log('Not enough USDT across all chains');
  } else if (error instanceof IntentTimeoutError) {
    console.log('Step timed out:', error.message);
  } else if (error instanceof RoutePlanningError) {
    console.log('No viable route:', error.message);
  }
}

Recovery

When a step fails, the receipt includes a recovery object explaining where funds are and what to do:

const receipt = await intent.executeIntent(plan);

if (receipt.recovery) {
  console.log(receipt.recovery.type); // "bridge_pending" | "transfer_failed" | "timeout"
  console.log(receipt.recovery.stuckChain); // which chain funds are on
  console.log(receipt.recovery.stuckAmount); // how much
  console.log(receipt.recovery.recoveryAction); // human-readable next step
  console.log(receipt.recovery.retryable); // can the SDK retry automatically?
}

Funds are never custodied by the SDK. If a bridge succeeds but the transfer fails, funds sit in the sender's own address on the destination chain.

Fund Safety

  • The SDK never holds, pools, or controls user funds
  • Every on-chain action requires the user's wallet signature
  • Bridge uses Tether's USDT0 protocol (LayerZero) which guarantees delivery or revert
  • If any step fails, funds remain in the sender's address on whichever chain they're on
  • All failures are reflected in the IntentReceipt with recovery guidance

Main Exports

| Export | What it does | | ----------------------- | ------------------------------------------------------- | | GasfreeIntent | Main class: discover, plan, execute, one-shot send | | discoverBalances | Standalone multi-chain balance discovery | | planIntent | Standalone route planning from a balance map | | validateIntentRequest | Validate an intent request before planning | | buildEvm4337Config | Build per-chain EVM4337 config from IntentConfig | | IntentEventEmitter | Typed event emitter for lifecycle events | | clearBalanceCache | Clear the in-memory balance cache | | Error classes | IntentValidationError, RoutePlanningError, etc. | | Types | IntentRequest, ExecutionPlan, IntentReceipt, etc. |

License

MIT