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

rn-latam-anchor-kit

v0.1.1

Published

React Native SDK for fiat-crypto ramp (BRL/PIX on Stellar) via Etherfuse — hooks and themable UI

Readme

rn-latam-anchor-kit helps React Native apps onboard Brazilian customers and move value between BRL via PIX and Stellar assets through Etherfuse. Use the complete themed flows, compose individual screens, or build your own interface on top of the same typed hooks and client.

  • Onboarding: identity, documents, hosted IDV, KYC status, wallet, and PIX account.
  • On-ramp: BRL via PIX to a Stellar asset.
  • Off-ramp: Stellar asset to BRL via PIX, including wallet preflight and XDR refresh.
  • ESM, CommonJS, and TypeScript declarations.
  • Zero runtime dependencies; native capabilities are injected by the host app.
  • Portuguese UI copy by default, with theme and copy overrides.

Installation

npm install rn-latam-anchor-kit

Compatibility

| Requirement | Supported | | ------------ | ----------- | | React | >= 19.0.0 | | React Native | >= 0.78.0 | | Blockchain | Stellar | | Fiat rail | BRL via PIX |

React and React Native are peer dependencies. The SDK does not install a WebView, wallet, document picker, QR renderer, or clipboard implementation. Add only the native packages used by your app.

Security model

Read this section before integrating the SDK.

Production API keys must not be embedded in the app

An Etherfuse API key is organization-scoped. A key bundled into an APK or IPA can be extracted and may expose every ramp customer under that organization.

  • Direct API access is supported for sandbox development.
  • Production traffic should go through infrastructure you control by injecting a custom Transport into EtherfuseClient.

Hosted IDV tokens must be minted by your backend

Etherfuse's hosted /idv flow uses a short-lived partner-signed JWT. The signing key must stay on your backend. The SDK receives only a launchTokenProvider callback that requests the token from your server.

Wallet keys stay with the host app

The SDK receives unsigned Stellar XDRs. Your wallet integration signs and submits them through signAndSubmitTransaction; the SDK never reads or stores private keys.

Configure the providers

The example below is intentionally configured for Etherfuse sandbox. Replace the placeholder adapters with your app's implementations.

import type { PropsWithChildren } from 'react';
import { WebView } from 'react-native-webview';
import {
  EtherfuseClient,
  EtherfuseProvider,
  EtherfuseThemeProvider,
  SANDBOX_BASE_URL,
  type LaunchTokenProvider,
  type SignAndSubmitStellarTransaction,
} from 'rn-latam-anchor-kit';

const client = new EtherfuseClient({
  apiKey: 'YOUR_SANDBOX_API_KEY',
  baseUrl: SANDBOX_BASE_URL,
});

const launchTokenProvider: LaunchTokenProvider = async (customerId) => {
  const response = await fetch(
    'https://your-api.example/etherfuse/launch-token',
    {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ customerId }),
    }
  );

  if (!response.ok) throw new Error('Could not create the launch token');
  const body = (await response.json()) as { token: string };
  return body.token;
};

const signAndSubmitTransaction: SignAndSubmitStellarTransaction = async (
  unsignedXdr
) => {
  // Your wallet owns signing and Horizon submission.
  return walletAdapter.signAndSubmit(unsignedXdr); // => { hash: string }
};

export function SdkRoot({ children }: PropsWithChildren) {
  return (
    <EtherfuseProvider
      client={client}
      WebViewComponent={WebView}
      launchTokenProvider={launchTokenProvider}
      signAndSubmitTransaction={signAndSubmitTransaction}
    >
      <EtherfuseThemeProvider>{children}</EtherfuseThemeProvider>
    </EtherfuseProvider>
  );
}

react-native-webview is required only when rendering hosted Etherfuse content. The document picker, QR code, and clipboard integrations are supplied to the specific screens that use them.

Use the flows

Each flow exposes one hook as its state machine. Render a screen from the hook's current step, or ignore the provided screens and build your own UI.

Onboarding

const onboarding = useEtherfuseOnboarding({
  customerId,
  displayName: 'Ana Silva',
  email: '[email protected]',
});

| onboarding.step | Provided screen | | ----------------- | ------------------------ | | identity | IdentityScreen | | documents | DocumentsScreen | | launch | LaunchScreen | | awaiting | AwaitingApprovalScreen | | rejected | RejectedScreen | | approved | ApprovedScreen | | bank-account | BankAccountScreen | | done | Return to your app |

DocumentsScreen receives a host-supplied pickDocuments() callback. Files are uploaded as multipart form data, never base64 JSON.

On-ramp: BRL to Stellar

const onramp = useEtherfuseOnramp({
  customerId,
  bankAccountId,
  walletAddress,
  assetSymbol: 'TESOURO',
});

| onramp.step | Provided screen | | ------------- | ---------------------------- | | value | OnrampValueScreen | | review | OnrampReviewScreen | | payment | PaymentInstructionsScreen | | awaiting | AwaitingConfirmationScreen | | claim | ClaimTokensScreen | | done | OnrampCompletedScreen |

The asset symbol is resolved through GET /ramp/assets; issuer identifiers are never hardcoded. PaymentInstructionsScreen accepts optional QRCodeComponent and onCopy adapters. A claim step appears only when Etherfuse returns a stellarClaimTransaction for a first-time wallet.

Off-ramp: Stellar to BRL

const offramp = useEtherfuseOfframp({
  customerId,
  bankAccountId,
  walletAddress,
  assetSymbol: 'TESOURO',
});

Render OfframpPreflightScreen until preflightStatus === 'ok', then route by offramp.step:

| State | Provided screen | | ----------------------- | ------------------------ | | Preflight not ready | OfframpPreflightScreen | | value | OfframpValueScreen | | review | OfframpReviewScreen | | sign / broadcasting | OfframpSignBurnScreen | | settling | OfframpSettlingScreen | | done | OfframpCompletedScreen |

Off-ramp requires an existing trustline, sufficient asset balance, and enough XLM for Stellar reserves and fees. The hook checks Horizon before quoting and refreshes expiring burn XDRs while the user is signing.

Build a custom UI

The provided screens are optional. Hook results contain the state, actions, statuses, and normalized errors needed for a fully custom interface.

function CustomOnramp() {
  const ramp = useEtherfuseOnramp({
    customerId,
    bankAccountId,
    walletAddress,
    assetSymbol: 'TESOURO',
  });

  return (
    <YourAmountForm
      loading={ramp.quoteStatus === 'submitting'}
      error={ramp.error?.userMessage}
      onSubmit={ramp.requestQuote}
    />
  );
}

For lower-level control, use EtherfuseClient directly:

const { assets } = await client.listAssets({
  blockchain: 'stellar',
  currency: 'BRL',
  wallet: walletAddress,
});

const order = await client.getOrder(orderId);

The client provides retries only for transient statuses, client-generated idempotency IDs, conflict recovery, WebSocket order tracking, and polling fallback.

Customize the UI

Every exported screen reads design tokens from EtherfuseThemeProvider. Overrides merge by token group, so changing one value preserves the rest of the default theme.

<EtherfuseThemeProvider
  theme={{
    colors: {
      primary: '#00A868',
      background: '#0B0B0F',
    },
    radius: { md: 12 },
  }}
>
  <YourRampFlow />
</EtherfuseThemeProvider>

The default theme uses the ChatPay Go Labs palette. nocturneTheme is also exported as a complete alternative. Fonts default to the platform system font; load custom fonts in the host app before naming them in the theme.

Visible copy defaults to Brazilian Portuguese. Screen props expose overrides for titles, descriptions, actions, and other user-facing text.

Handle errors

All SDK errors extend EtherfuseError and expose safe fields for application logic and UI. Raw API response bodies never cross the client boundary.

try {
  await client.getOrder(orderId);
} catch (error) {
  if (error instanceof EtherfuseError) {
    console.log(error.status, error.retryable, error.userMessage);
  }
}

Available subclasses include authentication, validation, not-found, conflict, transient, network, quote-expired, and Stellar submission errors. When Horizon rejects a wallet submission, throw StellarSubmitError with its result code so the off-ramp hook can recover from tx_too_late by requesting a fresh XDR.

Sandbox notes

  • Create a business organization in the Etherfuse sandbox; personal organizations cannot create API keys.
  • Sandbox on-ramps are capped at 500 in the quoted currency.
  • Asset identifiers differ between sandbox and production. Resolve them from GET /ramp/assets.
  • A customer can have only one BRL bank account.
  • simulateFiatReceived() is guarded and unavailable against production URLs.

Public API

The root package exports:

  • Core: EtherfuseClient, EtherfuseSocket, FetchTransport, Horizon preflight helpers, environment URLs, and idempotency helpers.
  • Context: EtherfuseProvider, useEtherfuseClient, and useEtherfuseContext.
  • Flows: useEtherfuseOnboarding, useEtherfuseOnramp, and useEtherfuseOfframp.
  • UI: onboarding, on-ramp, off-ramp, quote, status, preflight, hosted launch, and signing components.
  • Theming: EtherfuseThemeProvider, useTheme, defaultTheme, nocturneTheme, mergeTheme, and all public token types.
  • Errors and request/response types used by the supported Etherfuse endpoints.

All public types are exported from the package root. See src/index.ts for the authoritative export list.

Project documentation

Development

npm ci
npm run release:check

release:check runs TypeScript, ESLint, Prettier, the full test suite, requirement traceability, and the ESM/CommonJS/type build. The same command runs automatically before every npm publish.

Issues and feature requests are tracked in the GitHub issue tracker.

License

MIT — Copyright 2026 ChatPay Go Labs.