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

@jim4565/dapp-wrapper

v1.5.0

Published

An abstraction layer over the Incentiv dApp SDK for simplified dApp development

Readme

Incentiv dApp-Wrapper

A minimized, focused wrapper around the Incentiv dApp SDK for core blockchain interactions.

Features

  • Core Blockchain Functions: connect, getProvider, getSigner, getUserAddress, isConnected
  • Smart Contract Integration: Register contracts and call methods with simplified API
  • Single Instance: One wrapper instance across your entire frontend application
  • TypeScript Support: Full type safety with comprehensive interfaces
  • Error Handling: Specific error codes and user-friendly messages

Installation

npm install @jim4565/dapp-wrapper

Peer Dependencies

npm install @incentiv/dapp-sdk ethers

Quick Start

Basic Setup

import { IncentivWrapper } from '@jim4565/dapp-wrapper';

// 1. Create wrapper (network configuration is built-in)
const wrapper = new IncentivWrapper();

// 2. Connect to wallet (triggers Incentiv Portal popup)
const userAddress = await wrapper.connect();

// 3. Register contracts (only way to add contracts)
wrapper.registerContract("SOLO", "0x1234...", yourABI);

Perfect API Usage

// Your preferred API - exactly as you described!
// Directly call contract methods - transactions are sent automatically!
const receipt = await wrapper.getContract("SOLO").playGame(true);

// View/pure functions return values directly
const gameDetails = await wrapper.getContract("SOLO").getGameDetails(1);
const balance = await wrapper.getContract("SOLO").getBalance();

// State-changing functions return transaction receipt
const txReceipt = await wrapper.getContract("SOLO").deposit(100);
console.log('Transaction hash:', txReceipt.hash);

// Payable functions with ETH value (only works with payable functions!)
const gameReceipt = await wrapper.getContract("SOLO").playGame(true).withValue("0.1");
const depositReceipt = await wrapper.getContract("SOLO").deposit(100).withValue("3");

// Wait for confirmation
const confirmedReceipt = await txReceipt.wait();
console.log('Confirmed in block:', confirmedReceipt.blockNumber);

// Core functions
const provider = wrapper.getProvider();
const signer = wrapper.getSigner();
const address = wrapper.getUserAddress();
const connected = await wrapper.isConnected();

Global Usage Pattern

Use one wrapper instance across your entire frontend:

// services/blockchain.ts
export class BlockchainService {
  private static instance: IncentivWrapper;

  static getInstance(): IncentivWrapper {
    if (!BlockchainService.instance) {
      BlockchainService.instance = new IncentivWrapper();
      
      // Register contracts after creation
      BlockchainService.instance.registerContracts([
        { name: "Game", address: "0x123...", abi: gameABI },
        { name: "Token", address: "0x456...", abi: tokenABI }
      ]);
    }
    return BlockchainService.instance;
  }
}

// In any component
const wrapper = BlockchainService.getInstance();

Wallet Connection

The wrapper provides multiple ways to connect to the Incentiv wallet:

Standard Connection

try {
  const userAddress = await wrapper.connect();
  console.log('Connected as:', userAddress);
} catch (error) {
  if (error.code === 'USER_REJECTED') {
    console.log('User rejected wallet connection');
  }
}

Alternative Connection Methods

// Force fresh connection (clears existing session)
const address = await wrapper.connectFresh();

Connection Status

// Check if already connected
const isConnected = await wrapper.isConnected();

// Get current user address
const userAddress = wrapper.getUserAddress();

API Reference

Core Methods

  • connect(): Connect to wallet (triggers Incentiv Portal popup)
  • connectFresh(): Force fresh wallet connection
  • getProvider(): Get ethers provider
  • getSigner(): Get current signer
  • getUserAddress(): Get connected user address
  • isConnected(): Check connection status
  • createSigner(address): Create new signer instance

Contract Management

  • registerContract(name, address, abi): Register a single contract
  • registerContracts(contracts[]): Register multiple contracts
  • getRegisteredContracts(): Get list of all registered contract names
  • hasContract(name): Check if a contract is registered
  • getContractAddress(name): Get contract address by name
  • getContractMethods(name): Get all function names for a contract
  • getContract(name): Get contract instance by name

Contract Access

Contracts are accessed through the getContract() method for better encapsulation:

// Get contract instance
const soloContract = wrapper.getContract("SOLO");

// Check if contract exists
if (!soloContract) {
  console.log("Contract not found!");
  return;
}

// Access contract properties
console.log(soloContract.address);
console.log(soloContract.abi);

// Direct method calls - automatically sends transactions or reads state
const txReceipt = await wrapper.getContract("SOLO").playGame(true);
console.log('Transaction sent:', txReceipt.hash);

// With ETH value for payable functions
const payableReceipt = await wrapper.getContract("SOLO").playGame(true).withValue("0.1");
console.log('Payable transaction sent:', payableReceipt.hash);

// Alternative: Store contract reference for multiple uses
const game = wrapper.getContract("SOLO");
const gameReceipt = await game.playGame(true);
const gameWithValue = await game.deposit(100).withValue("3");
const gameStatus = await game.getGameStatus(); // Returns value directly for view functions

Validation Rules

withValue() Usage

The withValue() method has strict validation rules:

// ✅ Correct usage - only on payable functions
const receipt = await wrapper.getContract("Game").deposit(100).withValue("1.0");

// ❌ This will throw an error - view functions cannot receive ETH
try {
  await wrapper.getContract("Game").getBalance().withValue("1.0");
} catch (error) {
  console.error(error.message); 
  // "Cannot use withValue() on function 'getBalance' with stateMutability 'view'. Only 'payable' functions accept ETH value."
}

// ❌ This will throw an error - nonpayable functions cannot receive ETH
try {
  await wrapper.getContract("Game").updateSettings().withValue("1.0");
} catch (error) {
  console.error(error.message);
  // "Cannot use withValue() on function 'updateSettings' with stateMutability 'nonpayable'. Only 'payable' functions accept ETH value."
}

// ❌ This will throw an error - invalid ETH value
try {
  await wrapper.getContract("Game").deposit(100).withValue("-1.0");
} catch (error) {
  console.error(error.message);
  // "Invalid ETH value '-1.0'. Value must be a positive number."
}

Error Handling

try {
  // Direct method call - automatically sends transaction
  const result = await wrapper.getContract("Game").playGame(player, bet);
  console.log('Game transaction:', result.hash);
  
  // With ETH value for payable functions only
  const payableResult = await wrapper.getContract("Game").deposit(100).withValue("1.5");
  console.log('Payable transaction:', payableResult.hash);
  
  // This will throw an error - withdraw is not payable!
  // const errorResult = await wrapper.getContract("Game").withdraw().withValue("1.0");
  
  // Wait for confirmation
  const receipt = await result.wait();
  console.log('Confirmed in block:', receipt.blockNumber);
} catch (error) {
  if (error.code === 'WALLET_NOT_CONNECTED') {
    // Handle not connected
  } else if (error.code === 'USER_REJECTED') {
    // Handle user rejection
  } else if (error.code === 'INSUFFICIENT_FUNDS') {
    // Handle insufficient funds
  } else if (error.message.includes('Only \'payable\' functions')) {
    // Handle incorrect withValue() usage
    console.error('Cannot send ETH to non-payable function');
  } else if (error.message.includes('Invalid ETH value')) {
    // Handle invalid ETH value
    console.error('ETH value must be a positive number');
  }
}

TypeScript Support

Full TypeScript support with interfaces:

import { 
  IncentivWrapper, 
  TransactionResponse 
} from '@jim4565/dapp-wrapper';

// Simple creation - network is pre-configured
const wrapper = new IncentivWrapper();

License

MIT License - see LICENSE file for details.

Support