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

@openzeppelin/adapter-stellar

v2.0.0

Published

Stellar Adapter for UI Builder

Downloads

485

Readme

Stellar Adapter (@openzeppelin/adapter-stellar)

This package provides the Stellar ecosystem definition for OpenZeppelin UI: Soroban-focused capability factories, network metadata, and createRuntime to obtain an EcosystemRuntime for Stellar networks.

It is responsible for:

  • Exposing ecosystemDefinition (EcosystemExport) with networks, capabilities, and createRuntime(profile, networkConfig, options) aligned with @openzeppelin/ui-types.
  • Defining and exporting Stellar network configurations (Public Network and Testnet) as StellarNetworkConfig objects in src/networks/ (Horizon URL, Soroban RPC URL, network passphrase, explorer URL, icon, etc.).
  • Loading Stellar contract definitions and metadata and transforming them into the builder’s chain‑agnostic ContractSchema.
  • Mapping Soroban value types to builder form fields and validating user input.
  • Parsing user inputs into Soroban ScVal types for transaction execution and formatting view results.
  • Transaction execution using an execution strategy pattern (EOA and Relayer strategies).
  • Wallet integration and UI via the src/wallet/ module.
  • Adapter‑specific configuration and validation helpers (RPC resolution, explorer URLs, execution configuration validation).

Transaction Execution

The Stellar adapter uses an execution strategy pattern similar to the EVM adapter to handle transaction submissions.

Supported Strategies

  1. EOA (Externally Owned Account): Uses the connected Stellar wallet (via Stellar Wallets Kit) to sign and submit Soroban transactions directly.
  2. Relayer: Uses the OpenZeppelin Relayer service to submit transactions. The adapter exposes a StellarRelayerOptions React component to configure strategy‑specific options in the Builder UI.

The adapter selects the strategy at runtime based on the ExecutionConfig provided by the application.

Configuration in the Builder

The Builder application’s “Customize” step passes an ExecutionConfig into the execution capability’s transaction flow (signAndBroadcast on the runtime’s execution capability for transactor-style profiles). The implementation uses a factory to instantiate the appropriate strategy and reports live status updates via the provided onStatusChange callback.


Access Control Support

The Stellar adapter includes first-class support for OpenZeppelin Access Control and Ownable contracts through a dedicated service module.

Features

  • Feature Detection: Automatically detects contracts implementing AccessControl, Ownable, or both
  • Role Management: Query current roles, grant/revoke roles, check permissions
  • Ownership Management: Transfer ownership, query current owner
  • Dynamic Role Discovery: Automatically discover role IDs via indexer when not explicitly provided
  • Historical Queries: View complete history of role changes and ownership transfers via SubQuery indexer
  • Server-Side Filtering: Filter events by contract, role, account, and limit (when indexer is available)

Role Discovery

Since OpenZeppelin's Stellar contracts don't expose a get_all_roles() method, the adapter supports multiple ways to obtain role identifiers:

1. Explicit Role IDs (Recommended for known contracts)

const accessControl = runtime.accessControl;
if (!accessControl) {
  throw new Error('Access control capability not available for this profile');
}
accessControl.registerContract(contractAddress, schema, ['admin', 'minter', 'burner']);

2. Dynamic Discovery via Indexer

If no role IDs are provided, the access control capability automatically queries the indexer for historical ROLE_GRANTED and ROLE_REVOKED events:

// Register without role IDs - discovery happens automatically
accessControl.registerContract(contractAddress, schema);

// Or explicitly discover roles
const roles = await accessControl.discoverKnownRoleIds(contractAddress);
// => ['admin', 'minter', 'burner']

3. Adding Roles Manually

For newly created roles that haven't been granted yet (no historical events), you can add them manually:

// Add roles that may not exist in historical events
accessControl.addKnownRoleIds(contractAddress, ['new_role', 'another_role']);

Role IDs are validated against Soroban Symbol constraints:

  • Must start with a letter or underscore
  • Can contain only alphanumeric characters and underscores
  • Maximum 32 characters

Indexer Integration

For historical queries (e.g., getHistory()), the adapter integrates with the Stellar Access Control Indexer, a SubQuery project that indexes Access Control and Ownable events.

Configuring the Indexer

Add indexerUri to your StellarNetworkConfig:

const stellarTestnet: StellarNetworkConfig = {
  // ... other config
  indexerUri: 'https://api.subquery.network/sq/openzeppelin/stellar-access-control-indexer',
};

Deployment

The indexer is production-ready and compatible with:

  • SubQuery Network (decentralized, recommended for production)
  • Self-hosted infrastructure (Docker)

For deployment instructions, see the Indexer Deployment Guide.

Graceful Degradation

If no indexer is configured or the indexer is unavailable:

  • On-chain queries (roles, ownership) work normally
  • Historical queries return an empty array with a warning
  • UI remains functional for all current-state operations

Wallet Integration & UI

All wallet integration logic, UI components, facade hooks, and the UI context provider for Stellar are located in src/wallet/.

Stellar wallet and UI kit behavior is exposed through the wallet and uiKit entries on the EcosystemRuntime from createRuntime (for example StellarWalletUiRoot, facade hooks, and wallet components resolved via the UI kit capability).

For full documentation on the wallet module, see src/wallet/README.md.


This adapter follows the standard module structure outlined in the main project Adapter Architecture Guide.

Package Structure

adapter-stellar/
├── src/
│   ├── access-control/          # Access Control & Ownable support (service, indexer)
│   ├── configuration/           # Adapter-specific configuration (RPC, explorer, execution)
│   ├── contract/                # Contract loading & metadata
│   ├── mapping/                 # Soroban ↔ form field mapping & generators
│   ├── networks/                # Stellar network configurations
│   ├── query/                   # View function execution
│   ├── transaction/             # Transaction execution system (EOA, Relayer)
│   │   ├── components/                # React components for configuration
│   │   ├── formatter.ts               # Build Soroban tx data from form inputs
│   │   ├── execution-strategy.ts      # Strategy interface
│   │   ├── eoa.ts / relayer.ts        # Strategy implementations
│   ├── transform/               # Input parsing and output formatting
│   ├── types/                   # Adapter-specific types
│   ├── utils/                   # Utilities (artifact handling, formatting, etc.)
│   ├── validation/              # Validation utilities (addresses, configs)
│   ├── wallet/                  # Wallet integration (see wallet/README.md)
│   │   ├── components/                # Wallet UI components
│   │   ├── context/                   # Wallet context
│   │   ├── hooks/                     # Facade & low-level hooks
│   │   ├── implementation/            # Stellar Wallets Kit implementation
│   │   ├── services/                  # Config resolution for wallet UI
│   │   ├── stellar-wallets-kit/       # Kit-specific helpers
│   │   ├── README.md                  # Detailed wallet documentation
│   ├── adapter.ts               # Internal composition helpers (not the primary public API)
│   └── index.ts                 # ecosystemDefinition, createRuntime, networks, capabilities
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
└── README.md

Usage (runtime creation)

Consumers should use ecosystemDefinition.createRuntime with a ProfileName and a StellarNetworkConfig. That returns an EcosystemRuntime whose optional fields (wallet, query, accessControl, …) depend on the profile.

import type { ProfileName } from '@openzeppelin/ui-types';
import { ecosystemDefinition, stellarTestnet } from '@openzeppelin/adapter-stellar';

const profile: ProfileName = 'composer';
const networkConfig = stellarTestnet; // or stellarPublic

const runtime = await ecosystemDefinition.createRuntime(profile, networkConfig, {
  /* optional: UI kit overrides, indexer options, etc. */
});

// Example capabilities
const { wallet, networkCatalog, accessControl } = runtime;

Network configurations for Stellar networks are exported from src/networks/index.ts (stellarPublic, stellarTestnet, arrays stellarMainnetNetworks, stellarTestnetNetworks, and stellarNetworks).

Note: Legacy docs or examples may still reference the old monolithic adapter class, but npm documentation and app code should treat ecosystemDefinition + createRuntime as the stable integration surface.

Soroban RPC URL Configuration

Each StellarNetworkConfig specifies a default sorobanRpcUrl.

This URL can be overridden at runtime by the consuming application through the central AppConfigService. Configuration is loaded from environment variables (for the Builder app) or a public/app.config.json file (for exported apps).

To override a RPC URL, define an entry in rpcEndpoints keyed by the network’s string ID (e.g., "stellar-testnet").

In .env for the Builder app: VITE_APP_CFG_RPC_ENDPOINT_STELLAR_TESTNET="https://your-custom-soroban-rpc.testnet.example"

In public/app.config.json for an exported app:

{
  "rpcEndpoints": {
    "stellar-testnet": "https://your-custom-soroban-rpc.testnet.example",
    "stellar-public": "https://your-custom-soroban-rpc.public.example"
  }
}

The Stellar runtime resolves Soroban RPC in this order:

  1. User-provided RPC config from UserRpcConfigService (advanced user input)
  2. RPC override via AppConfigService.getRpcEndpointOverride(networkId)
  3. Default sorobanRpcUrl from the active StellarNetworkConfig

Explorer URLs

Stellar explorers are used for display only. The runtime constructs URLs using explorerUrl from the network config:

  • getExplorerUrl(address).../account/{address} or .../contract/{id} (Soroban contracts)
  • getExplorerTxUrl(txHash).../tx/{hash}

No explorer API keys are required for adapter functionality.

Network Configurations

Stellar networks are exported from src/networks/. Each StellarNetworkConfig includes:

  • id: Unique network identifier (e.g., "stellar-public", "stellar-testnet")
  • name: Display name
  • ecosystem: Always "stellar"
  • network: Always "stellar"
  • type: "mainnet" or "testnet"
  • isTestnet: boolean
  • horizonUrl: Horizon endpoint for the network
  • sorobanRpcUrl: Soroban JSON-RPC endpoint
  • networkPassphrase: The network passphrase used by Wallets Kit / SDK
  • explorerUrl: Base URL for the explorer (display only)
  • icon: Icon identifier

See src/networks/README.md for details on adding networks and overriding RPC.

Stellar Asset Contract (SAC) Support

The adapter fully supports Stellar Asset Contracts (SACs), which are special contracts that wrap native Stellar assets. SACs are automatically detected via RPC ledger entries and their specifications are loaded dynamically.

How SAC Support Works

  1. Detection: When loading a contract, the adapter checks its executable type via RPC
  2. Specification Loading: For SAC contracts, the adapter fetches the official SAC specification from GitHub
  3. XDR Encoding: The JSON spec is converted to XDR format using @stellar/stellar-xdr-json
  4. UI Generation: The contract-loading / schema pipeline generates the same UI fields as regular WASM contracts

Technical Implementation Details

WASM Loading Strategy

The @stellar/stellar-xdr-json library requires a ~3MB WebAssembly module for XDR encoding. After extensive testing with various Vite bundling approaches (including vite-plugin-wasm, vite-plugin-top-level-await, and ?url imports), we encountered persistent issues where Vite would serve HTML instead of the WASM binary, resulting in WebAssembly instantiation errors.

Solution: The WASM module is loaded from CDN (unpkg.com) rather than bundled. This approach:

  • Avoids Vite bundling complexities and errors
  • Reduces bundle size by 3MB for users who don't use SAC contracts
  • Loads the WASM only when a SAC contract is actually detected (lazy loading)
  • Simplifies the build configuration

This adapter generally follows the standard module structure and developer experience provided by the EVM adapter, while keeping the core app chain‑agnostic.