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

@d0fi/checkout-react

v0.3.1

Published

React bindings for @d0fi/checkout-core

Readme

@d0fi/checkout-react

Hosted checkout UI (D0fiCheckoutExperience), modal/provider helpers, and embed protocol wiring on top of @d0fi/checkout-core.

For order-funded on-chain withdrawals, use D0fiWithdrawalExperience with a browser-safe D0fiWithdrawalClient implemented against the merchant's own authenticated backend. See Withdrawal SDK integration.

Connect Wallet payments (no D0 merchant account)

D0fiConnectWalletPayment is the sessionless wallet-to-wallet interface. The customer application owns the payment intent, receiving address, transaction adapter and on-chain confirmation. The payer's funds never pass through D0.

import {
  D0fiConnectWalletPayment,
  type D0fiConnectWalletPaymentAdapter,
  type D0fiConnectWalletPaymentIntent,
} from "@d0fi/checkout-react";
import "@d0fi/checkout-react/styles.css";

export function WalletPayment({
  intent,
  adapter,
  registerSubmittedHash,
}: {
  intent: D0fiConnectWalletPaymentIntent;
  adapter: D0fiConnectWalletPaymentAdapter;
  registerSubmittedHash: (payment: {
    reference: string;
    transactionHash: string;
  }) => void;
}) {
  return (
    <D0fiConnectWalletPayment
      intent={intent}
      adapter={adapter}
      onSubmitted={registerSubmittedHash}
    />
  );
}

No D0 Checkout Session or browser-side D0 credential is used. onSubmitted means the wallet adapter returned a transaction hash; the customer backend must still verify the network, asset, recipient, amount and finality before crediting the order. Use D0fiCheckoutExperience when D0 should own Session policy, merchant records, status and webhooks.

The active intent owns one stable idempotency key for uncertain retries. An adapter must deduplicate that key before broadcasting. Register the returned hash from onSubmitted; a registration outage must not be presented as if the wallet transfer failed. See the runnable EVM setup and the Solana/TRON adapter requirements at https://docs.d0fi.com/connect-wallet.

Wallet connection

@d0fi/checkout-react includes a namespaced EVM and Solana wallet connection layer for merchant applications. It discovers installed EIP-6963 wallets, Solana Wallet Standard wallets (Phantom, Solflare, Fordefi, Backpack, OKX, Coinbase, Trust, Magic Eden, Jupiter, and others), using browser wallet interfaces. Phantom, Jupiter, Fordefi, Ledger, and Solflare are always shown in the Solana list: installed Wallet Standard wallets connect directly and carry an INSTALLED badge, while uninstalled fallbacks open their official websites. Ledger is presented as a hardware-wallet setup option and normally connects to Solana DApps through a compatible software wallet such as Phantom or Solflare.

import {
  D0fiCheckoutExperience,
  D0fiConnectButton,
  D0fiWalletProvider,
  createD0fiWalletConfig,
  useD0fiAccount,
  useD0fiSignMessage,
} from "@d0fi/checkout-react";
import "@d0fi/checkout-react/styles.css";
import "@d0fi/checkout-react/wallet.css";

const walletConfig = createD0fiWalletConfig({
  appName: "Website A",
  // Opt in so existing merchant UIs do not change after an SDK upgrade.
  solana: { enabled: true },
});

function Profile() {
  const account = useD0fiAccount();
  const { signMessageAsync, isPending, error } = useD0fiSignMessage();
  return account.isConnected ? (
    <div>
      <button
        disabled={isPending}
        onClick={() => void signMessageAsync("Sign in to Website A").catch(() => undefined)}
      >
        Sign test message for {account.address}
      </button>
      {error ? <p role="alert">{error.message}</p> : null}
    </div>
  ) : null;
}

export function App() {
  return (
    <D0fiWalletProvider config={walletConfig}>
      <D0fiConnectButton />
      <Profile />
      <D0fiCheckoutExperience
        sessionId="YOUR_SESSION_ID"
        walletHttpBase="https://api.d0.fi"
        embedded
      />
    </D0fiWalletProvider>
  );
}

Public hooks: useD0fiAccount, useD0fiNetwork, useD0fiSignMessage, useD0fiSolanaTransaction, useD0fiSwitchChain, useD0fiDisconnect, useD0fiWalletClient, and useD0fiConnectModal.

Use D0fiConnectWalletButton when the host wants one combined EVM/Solana picker. Its default form is a trigger plus modal; pass inline to render the same picker directly in the page without an overlay, close control, focus trap, or body scroll lock:

<D0fiConnectWalletButton inline />

For an EVM write that must run on a specific chain, use useD0fiWalletClient().getClientForChainAsync(chainId). It switches the wallet when required and returns a newly-created client pinned to that chain, so code does not reuse chain metadata captured before the switch completed.

EVM remains the default namespace, so existing calls keep their original viem-compatible types. Pass namespace: "solana" to read and sign with the independent Solana connection:

function SolanaProfile() {
  const account = useD0fiAccount({ namespace: "solana" });
  const { signMessageAsync, isPending, error } = useD0fiSignMessage({
    namespace: "solana",
  });

  if (!account.isConnected) {
    return <D0fiConnectButton namespace="solana" label="Connect Solana" />;
  }

  return (
    <>
      <p>{account.address}</p>
      <button
        disabled={isPending}
        onClick={() => {
          void signMessageAsync(`Website A nonce: ${nonce}`)
            .then(({ signedMessage, signatureBase58 }) => {
              // Send signedMessage, signatureBase58, address, and the nonce to
              // Website A's backend. Do not create a login session in-browser.
              submitProof({ signedMessage, signatureBase58, address: account.address! });
            })
            .catch(() => undefined);
        }}
      >
        Sign Solana message
      </button>
      {error ? <p role="alert">{error.message}</p> : null}
    </>
  );
}

The Solana result contains signedMessage, raw signature bytes, and signatureBase58. Verify signedMessage rather than reconstructing it: Wallet Standard allows a wallet to prefix or otherwise transform the requested bytes. A backend can decode the public key and signature with bs58 and verify the Ed25519 signature with its preferred audited crypto library. Nonce issuance, expiry, domain binding, replay protection, SIWS, and the authenticated merchant session remain the merchant's responsibility.

useD0fiProvider("solana") exposes serialized transaction signing in addition to message signing. It supports signTransaction, batched signAllTransactions, and wallet-side signAndSendTransaction when the selected wallet advertises that feature. useD0fiSolanaTransaction() exposes the same operations with shared pending/error state. useD0fiDisconnect().disconnectAsync({ namespace: "solana" }) disconnects only Solana; omitting the namespace disconnects all D0fi namespaces. EVM and Solana connections can coexist in one provider tree.

Solana DeFi and Neutral Trade-style integrations

Transaction signing is available through two optional compatibility entry points so an existing DeFi frontend can keep its transaction stack:

# Install the one already used by the application.
pnpm add @solana/web3.js
# or
pnpm add @solana/kit

For a Reown/AppKit Solana frontend that already passes walletProvider into web3.js or Anchor helpers, replace the provider hook and keep the downstream calls:

import { useD0fiAccount } from "@d0fi/checkout-react";
import { useD0fiSolanaWeb3Provider } from "@d0fi/checkout-react/solana-web3";

function DepositAction() {
  const { address, isConnected } = useD0fiAccount({ namespace: "solana" });
  const { walletProvider, error } = useD0fiSolanaWeb3Provider();

  async function deposit() {
    if (!isConnected || !address || !walletProvider) return;
    // Existing web3.js / Anchor code can continue to use:
    // walletProvider.publicKey
    // walletProvider.signMessage(bytes)
    // walletProvider.signTransaction(transaction)
    // walletProvider.signAllTransactions(transactions)
    // walletProvider.sendTransaction(transaction, connection, options)
    await existingDepositFlow({ walletProvider, userAddress: address });
  }

  return <button onClick={() => void deposit()}>{error?.message ?? "Deposit"}</button>;
}

For @neutral-trade/sdk and other @solana/kit instruction builders, pass the D0fi adapter as their TransactionSigner:

import { buildDepositInstructions } from "@neutral-trade/sdk";
import {
  useD0fiSolanaKitTransactionSigner,
} from "@d0fi/checkout-react/solana-kit";

function NeutralDeposit() {
  const { data: user, error } = useD0fiSolanaKitTransactionSigner();

  async function buildDeposit() {
    if (!user) return;
    const instructions = await buildDepositInstructions(rpc, {
      user,
      // Existing vault and amount arguments stay unchanged.
      vault,
      amount,
    });
    await existingKitTransactionPipeline(instructions);
  }

  return <button onClick={() => void buildDeposit()}>{error?.message ?? "Deposit"}</button>;
}

The Kit bridge intentionally implements a partial signer and rejects a wallet response that changes the compiled transaction message. This prevents a modified transaction from being merged under the wrong Kit signer contract. Both compatibility packages are optional peers and separate bundle entry points; applications that only use Checkout do not load web3.js or Kit through D0fi.

Browser wallet connections do not require a project ID or a remote wallet directory.

  • Connecting never signs a message or sends a transaction automatically.
  • signMessage proves wallet control only. The merchant remains responsible for nonce issuance, signature verification, replay protection, and its authenticated session.
  • Solana can be configured with the exported d0fiSolanaMainnet, d0fiSolanaDevnet, and d0fiSolanaTestnet constants. D0fi supplies cluster-aware connection and signing, while the merchant keeps its RPC, transaction construction, simulation, submission/confirmation policy, SIWS, and backend login session.
  • D0fi does not automatically sign, submit, or retry a transaction. Every signing call must originate from an explicit merchant-controlled user action.
  • Wallet prompts can be rejected or fail. Catch returned promises and render the hook's error; do not treat a connection, signature, or submitted transaction as successful before its promise resolves.
  • The defaults are Ethereum Mainnet and BNB Chain. Pass chains and transports to use production RPC endpoints or more EVM networks.
  • For SSR, create the config with ssr: true in a client-safe module and render D0fiWalletProvider from a client component. Browser wallet discovery runs only on the client.
  • Shared state works when merchant UI and D0fiCheckoutExperience are in the same React tree. Cross-origin Hosted iframes intentionally do not receive the parent provider.

RainbowKit and Reown compatibility

RainbowKit 2.2 migrations use @d0fi/checkout-react/rainbowkit and keep the website's existing WagmiProvider and QueryClientProvider. Reown AppKit 1.8 migrations use @d0fi/checkout-react/appkit, keep the explicit createAppKit result, and wrap the root with <AppKitProvider instance={appKit}>. See the migration guide for complete examples, supported APIs, codemod usage, and blockers such as Para or embedded login.

For a purpose="deposit" experience, when enabledMethods.connectWallet is true and D0fiCheckoutExperience receives a partnerContractDeposit adapter, Checkout shows a separate direct-contract entry. Its confirmation calls only the host adapter; it never falls back to the D0 session depositAddress. The existing Checkout wallet transfer method remains EVM-only and sends to the D0 session depositAddress. See docs/deposit-integration.md for the two trust boundaries and end-to-end partner gateway contract.

Pay vs deposit

  • purpose="pay" (default): same POST /v1/checkout/sessions (omit or set purpose: "pay"); bootstrap and polling use GET /v1/checkout/sessions/:id via getSession / refreshSession.
  • purpose="deposit": create with POST /v1/checkout/sessions and purpose: "deposit" (or createDepositSession in core); bootstrap and polling still use GET /v1/checkout/sessions/:id. Recovery retry uses createDepositSession.

The merchant backend only needs /v1/checkout/sessions for both flows; distinguish with the purpose field on create.

Embed events keep the same type names (payment.completed, etc.); payload.purpose is "pay" | "deposit" (see docs/checkout-embed-protocol.md).

Glide-inspired flows (Embed Pay, Embed Deposit)

| Glide | D0fi widget | |-------|-------------| | Backend createWidgetSession (mode, amount) | Merchant backend POST /v1/checkout/sessions (purpose, amount, …); returns sessionId. | | useGlidePay({ app, sessionId, onSuccess }) | D0fiCheckoutExperience with sessionId, walletHttpBase, onSuccess / onFailure (terminal states). | | useGlideDeposit({ recipient, onSuccess, mode? }) | purpose="deposit" + same checkout API; the generated session depositAddress is the destination for manual or connected-wallet funding. | | openGlidePay() iframe/modal | useD0fiHostedIframe() (alias of useD0fiCheckout) + D0fiCheckoutModal / openEmbedded toward Hosted origin configured on D0fiCheckoutProvider. | | Optional skip first screen | initialFlow="crypto" on D0fiCheckoutExperience lands on the manual QR/address flow without the payment-method tiles (pay flow only). |

CSS

Import @d0fi/checkout-react/styles.css once (e.g. in app entry). Tailwind utilities used by the UI require this stylesheet.

Appearance / theming (appearance prop)

Merchants customize the widget at integration time through the appearance prop on D0fiCheckoutExperience. It is resolved into --d0fi-* CSS variables injected on the checkout root; any token you omit keeps its built-in dark/light default.

import { D0fiCheckoutExperience, type D0fiAppearance } from "@d0fi/checkout-react";

const appearance: D0fiAppearance = {
  mode: "auto",              // "dark" | "light" | "auto" (system)
  accent: "#8B5CF6",         // brand accent (icons, brand surfaces, legacy --brand-color)
  accentText: "#FFFFFF",
  font: "'Inter', sans-serif",
  colors: {
    dark: { bg: "#0B0B0F", card: "#15151B", textPrimary: "#FFFFFF" },
    light: { bg: "#F4F4F7", card: "#FFFFFF" },
  },
  radius: { card: 20, list: 14, modal: 20 }, // px
  border: { cardWidth: 1, cardColor: "#26262B" },
  components: {
    card: { title: "#FFFFFF", subtitle: "#9AA0AB", background: "#15151B" },
    list: { rowBackground: "#1C1C22", sectionTitle: "#7A8090" },
  },
  general: { modalTitle: "Pay Order #A1234" },
};

<D0fiCheckoutExperience sessionId={id} walletHttpBase="https://api.d0.fi" appearance={appearance} embedded />;

| Field | Effect | |-------|--------| | mode | dark / light / auto. auto tracks prefers-color-scheme and syncs the shared theme store. | | accent / accentText | Brand accent color + text on accent. | | font | Any CSS font-family string. | | colors.{dark,light} | Per-mode base palette overrides (keys are ThemeTokenKey; only the active mode is emitted). | | radius | Corner radius per surface: card / list / modal (px). | | border | cardWidth (px) + cardColor. | | components | Per-component overrides layered on the base palette (e.g. card.title, list.rowBackground). | | general.modalTitle | Header title text on the checkout card. |

Helpers buildAppearanceVars, resolveAppearanceMode, THEME_DEFAULTS, tokenVarName are exported for SSR pre-rendering or building your own editor. Payment-method visibility remains controlled by CheckoutFeaturesProvider (enabledMethods), not appearance.

Recovery defaults

recoveryDefaults on D0fiCheckoutExperience retains the deposit destination needed by the “expired → try again” experience. Session recreation remains a merchant-backend responsibility; the browser never selects a tenant principal:

  • depositAddress — required when recovery is enabled.
  • depositReferencePrefix — optional; used when building referenceId for deposit retries if orderId is empty.

Re-exported types: WalletCheckoutPurpose and the Merchant-scoped Checkout experience types from @d0fi/checkout-core.

Deposit with Wallet

The wallet payment-method row connects directly to installed EVM browser extensions (MetaMask, Coinbase Wallet, OKX, Phantom EVM, Rabby, Trust Wallet, and Brave Wallet). After connection, the payer selects an enabled EVM asset/network pair, receives the session payment address, enters an amount, reviews the full transfer, and confirms it in the wallet.

Each widget-config.crypto.pairs[] row used by this flow must include chain-neutral wallet metadata:

| Field | Role | |-------|------| | walletFamily | Transfer adapter family. evm uses the EVM browser-wallet path; solana uses Wallet Standard and requires mainnet mint, decimals, and a browser-safe RPC URL. | | networkReference | Wallet network identifier, e.g. eip155:1 or eip155:56. | | assetReference | Token contract/mint identifier; omitted for native assets. | | decimals | Amount precision used to build the wallet transaction. | | isNative | Whether the transfer sends the network's native asset rather than a token contract call. |

The client-returned transaction hash is a non-authoritative submitted-state hint. Checkout status only advances after backend chain scanning verifies the actual deposit.