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

@idosgames/wallet

v0.2.1

Published

Wallet-bridge companion to @idosgames/core: connect browser & mobile wallets (EVM via wagmi/viem/WalletConnect, Solana via wallet-adapter) and move tokens/NFTs in and out of the game through client.blockchain.

Downloads

1,533

Readme

@idosgames/wallet

The on-chain half of the iDosGames blockchain flow. @idosgames/core's client.blockchain is deliberately report-only: it verifies deposits and issues signed withdrawals but never signs or broadcasts a transaction. This package is the missing piece — it connects browser & mobile wallets and runs the exact RewardPool contract calls, threading them through the request → submit → confirm / approve → deposit → report lifecycle so a player can move tokens and NFTs in and out of the game.

  • EVMwagmi + viem + WalletConnect. Browser (MetaMask / any injected wallet) and mobile (via WalletConnect) are both first-class.
  • Solana@solana/wallet-adapter for connection; the on-chain instruction building is delegated to a small SolanaProgramAdapter you implement with your program's IDL (see Solana).

Everything stays server-authoritative: the bridge only submits what the backend signed/verified and mirrors the confirmed result into the core cache.

Install

npm i @idosgames/wallet @idosgames/core
# EVM peer deps:
npm i wagmi viem @tanstack/react-query
# Solana peer deps (only if you support Solana networks):
npm i @solana/web3.js @solana/wallet-adapter-react @solana/wallet-adapter-base @solana/wallet-adapter-wallets

Entry points:

  • @idosgames/wallet — framework-agnostic bridge functions (viem + @solana/web3.js only). Use these directly if you're not on React.
  • @idosgames/wallet/react — wagmi/React hooks + providers. Everything below uses these.
  • @idosgames/wallet/react/solana — the Solana React bindings, kept off /react so an EVM-only game doesn't bundle the Solana adapters.
  • @idosgames/wallet/react/lazyLazyWalletLogin / LazySolanaWalletLogin / LazyWalletPanel: the sign-in buttons and the in-game deposit/withdraw panel, but each fetches the wallet machinery on demand (LazyWalletLogin on the player's first tap; LazyWalletPanel on mount). This is the only entry with no Reown AppKit in its module graph, which is what makes it safe to render on a login screen or in-game in sandboxed/preview bundlers where AppKit isn't installable. It also re-exports the supported chains as plain objects, so you never have to import the wagmi/chains / viem/chains barrel.

createEvmWalletConfig is memoised per WalletConnect project id: the sign-in button and the wallet panel both call it and get the same wagmi Config object, and a wagmi Config carries the connection in its own store. So a wallet connected on the login screen is already connected in the in-game panel — no reconnect, no second modal. For that to hold, keep both on the same chain set; both default to DEFAULT_EVM_CHAINS, so the simplest correct thing is to pass no chains to either. LazyWalletPanel takes the authenticated client as a prop (like the login button), plus optional appName / onClose / style / walletConnectProjectId.

Every subpath declares a browser export condition pointing at the ESM build. That is load-bearing, not cosmetic: some browser bundlers (CodeSandbox's classic Sandpack bundler among them) rank the require condition above import and would otherwise take the CommonJS build — where a dynamic import() cannot survive, so the lazy entry would eagerly require AppKit.

Operation category

The updated RewardPool contract tags each operation with a string category (default "game_topup"; "community_reward" is the other known value). Deposits read it back from the on-chain tx; withdrawals sign it into the hash, so it must be submitted on-chain verbatim — the bridge handles that. Pass a category to any deposit/withdraw call, or omit it for "game_topup". Constants live in @idosgames/core as BlockchainOperationCategory.

EVM

1. Set up the provider

createEvmWalletConfig builds a wagmi config wired for both browser and mobile wallets. Wrap your app with IDosGamesWalletProvider (WagmiProvider + react-query) once.

import { polygon } from "viem/chains";
import {
  createEvmWalletConfig,
  IDosGamesWalletProvider,
} from "@idosgames/wallet/react";

const wagmiConfig = createEvmWalletConfig({
  chains: [polygon], // match the EVM networks in your title's blockchain config
  walletConnectProjectId: "<your walletconnect cloud id>", // enables MOBILE wallets
  appName: "My Game",
});

export function Root() {
  return (
    <IDosGamesWalletProvider wagmiConfig={wagmiConfig}>
      <App />
    </IDosGamesWalletProvider>
  );
}

Connect/disconnect with wagmi's own hooks (useConnect, useAccount, useDisconnect) — the injected() connector covers MetaMask & browser extensions, walletConnect() opens the QR/deep-link modal for phones.

2. Deposit a token

useEvmBridge(client, titleID) binds the connected wallet to the four flows. Amounts are raw on-chain units — scale with viem's parseUnits.

import { parseUnits } from "viem";
import { useEvmBridge } from "@idosgames/wallet/react";
import type { BlockchainNetworkDefinition } from "@idosgames/core";

function DepositButton({ client, network, usdtAddress }) {
  const bridge = useEvmBridge(client, "my-title-id");

  async function deposit() {
    // approve → depositERC20(token, amount, userID, titleID, category) → report to backend
    const res = await bridge.depositToken({
      network, // BlockchainNetworkDefinition from getDefinitions()
      tokenAddress: usdtAddress, // ERC-20 contract
      amount: parseUnits("25", 6), // 25 USDT (6 decimals) as raw units
      // category defaults to "game_topup"
    });
    if (!res.ok) return alert(`${res.stage}: ${res.error}`);
    // core cache balance is already updated; res.data is DepositTokenResponse
  }

  return (
    <button disabled={!bridge.connected} onClick={deposit}>
      Deposit 25 USDT
    </button>
  );
}

3. Withdraw a token

const res = await bridge.withdrawToken({
  currencyID: "usdt",
  networkID: "polygon",
  walletAddress: bridge.account!, // destination — usually the connected wallet
  amount: "25.00", // human decimal; server scales & signs raw units
});
if (!res.ok) {
  // If it failed AFTER the debit, res.titleTransactionID is set — recover with
  // retryWithdrawal (while Pending) or confirmWithdrawal, NEVER a fresh request.
  console.error(res.stage, res.error, res.titleTransactionID);
}

The bridge runs requestTokenWithdrawal (debits in-game) → withdrawERC20 on-chain → confirmWithdrawal. A BridgeFailure tells you exactly where it stopped via stage (request / withdraw-onchain / confirm) so you can recover correctly — see Failure & recovery.

4. NFTs

// Deposit: safeTransferFrom(account, pool, id, amount, abi.encode(userID,titleID,category))
await bridge.depositNft({
  network,
  nftContractAddress,
  tokenId: 42n,
  amount: 1n,
});

// Withdraw: requestNFTWithdrawal → withdrawERC1155 → confirmWithdrawal
await bridge.withdrawNft({
  itemID,
  networkID: "polygon",
  walletAddress: bridge.account!,
  amount: "1",
});

Solana

The Solana RewardPool is a custom program whose instruction/account layout isn't in this SDK — so you provide a SolanaProgramAdapter (two methods: depositSpl and submitWithdrawal) built with your program's IDL / @solana/web3.js and the connected wallet from @solana/wallet-adapter-react. The SDK-side orchestration is identical to EVM.

import {
  SolanaWalletBridgeProvider,
  useSolanaBridge,
} from "@idosgames/wallet/react";
import { PhantomWalletAdapter } from "@solana/wallet-adapter-wallets";
import type { SolanaProgramAdapter } from "@idosgames/wallet";

// Wrap (alongside IDosGamesWalletProvider if you also support EVM):
<SolanaWalletBridgeProvider
  endpoint="https://api.mainnet-beta.solana.com"
  wallets={[new PhantomWalletAdapter()]}
>
  <App />
</SolanaWalletBridgeProvider>;

// Your program integration:
const adapter: SolanaProgramAdapter = {
  async depositSpl({ mint, amountRaw, userID, titleID, category }) {
    /* build + send the DepositSpl tx with your IDL; return the signature */
  },
  async submitWithdrawal(sig) {
    /* build + send withdraw_spl with the ed25519 sig-verify ix; return the signature */
  },
};

function Screen({ client }) {
  const bridge = useSolanaBridge(client, "my-title-id", adapter);
  // bridge.depositToken({ network, mint, amountRaw }) / bridge.withdrawToken({ currencyID, networkID, amount })
}

Failure & recovery

Every bridge call resolves to a BridgeResult<T>:

type BridgeResult<T> =
  | { ok: true; onChainTxHash: string; data: T }
  | {
      ok: false;
      stage: BridgeStage; // where it stopped
      error: string;
      onChainTxHash?: string; // set if the asset-moving tx already landed
      titleTransactionID?: string; // set if a withdrawal already debited in-game
    };

Recovery rules (the bridge never double-charges, but you drive the retry):

  • stage: "approve" | "deposit-onchain" — nothing was reported; safe to retry the whole deposit.
  • stage: "report" — the on-chain tx (onChainTxHash) landed but the backend didn't credit it; retry client.blockchain.depositToken/depositNFT with that hash.
  • stage: "withdraw-onchain" with a titleTransactionID — the withdrawal was already debited in-game but not submitted on-chain. Get a fresh signature with client.blockchain.retryWithdrawal(titleTransactionID) (while Pending) and submit it with submitEvmTokenWithdrawal / submitEvmNftWithdrawalnever call withdrawToken again (that debits twice).
  • stage: "confirm" with onChainTxHash + titleTransactionID — the tx landed but the backend confirm didn't stick; retry client.blockchain.confirmWithdrawal(titleTransactionID, onChainTxHash).

Framework-agnostic core

Not on React? Import the same flows from @idosgames/wallet and pass viem clients yourself:

import { depositTokenEvm, withdrawTokenEvm } from "@idosgames/wallet";

const clients = { publicClient, walletClient, account }; // your viem clients
await depositTokenEvm({
  client,
  clients,
  network,
  tokenAddress,
  amount,
  titleID,
});

Notes

  • The RewardPool ABI here mirrors the backend's RewardPoolEvmV2 signing (field order/names of withdrawERC20/withdrawERC1155/depositERC20 must match, or signatures fail on-chain).
  • After a deposit/withdrawal the core balance cache is fresh, but client.data.user.state.Blockchain (pending list, stats) is not — call client.blockchain.getUserState() to refresh it. See the blockchain-system skill for the full server-side surface, withdrawal gates, and gotchas.