Skip to content

Provider and events ​

Discover the provider ​

getInjectedProvider() immediately returns window.stashwallet or undefined. detectProvider(timeoutMs = 5000) waits for injection and returns a provider or null. Outside a browser, they return undefined / null respectively.

ts
import { detectProvider } from 'stash-wallet-sdk'

const provider = await detectProvider()
if (!provider) throw new Error('Install Stash Wallet and reload the page')
const connected = await provider.isConnected()
const caps = await provider.getCapabilities()

Detection does not imply authorization. Prefer the client's connect() to request site access. The SDK listens for stashwallet#initialized and polls for late injection; applications usually do not need their own polling.

Provider contract ​

Identity and version ​

  • isStashWallet: always true.
  • protocolVersion: protocol version string.

Requests and queries ​

ts
provider.request({ method, params })
// Promise<unknown>

provider.isConnected()
// Promise<boolean>

provider.getCapabilities()
// Promise<ProviderCapabilities>

method is a method name string; params is optional.

Add and remove listeners ​

ts
provider.on(event, handler)
provider.removeListener(event, handler)

Use the same handler reference when subscribing and removing a listener.

Direct request() results are unknown. Prefer the typed client or validate results yourself. The bridge permits only public methods; do not invoke internal extension messages.

Subscribe and clean up ​

Subscribe on the provider, not StashWalletClient, which has no on() method. Public event names are accountsChanged, networkChanged, and disconnect. SDK event payloads are unknown, without a stable shape guarantee.

ts
import { detectProvider } from 'stash-wallet-sdk'
import type { ProviderEventHandler } from 'stash-wallet-sdk'

async function subscribe(refreshState: () => Promise<void>): Promise<() => void> {
  const provider = await detectProvider()
  if (!provider) throw new Error('Provider not found')
  const onChanged: ProviderEventHandler = () => {
    void refreshState().catch((error: unknown) => {
      console.error('Failed to refresh wallet state', error)
    })
  }
  provider.on('accountsChanged', onChanged)
  provider.on('networkChanged', onChanged)
  provider.on('disconnect', onChanged)
  return () => {
    provider.removeListener('accountsChanged', onChanged)
    provider.removeListener('networkChanged', onChanged)
    provider.removeListener('disconnect', onChanged)
  }
}

Call the returned cleanup function when the component unmounts. Treat events as signals to refresh accounts, network, session, and capabilities. Do not assume payload structure or use events alone as proof of settlement.

Transports and timeouts ​

Default request timeout: 120,000 ms. Default provider discovery wait: 5,000 ms.

StashWalletClient.connect({ timeoutMs }) applies an explicit timeout to both discovery and the request transport. To configure them separately, discover first and construct the transport:

ts
import {
  detectProvider,
  InjectedProviderTransport,
  StashWalletClient,
} from 'stash-wallet-sdk'

const provider = await detectProvider(5000)
if (!provider) throw new Error('Provider not found')
const client = new StashWalletClient(
  new InjectedProviderTransport({ timeoutMs: 120000 }),
)
await client.connect()
  • InjectedProviderTransport: preferred injected-provider communication, without an externally_connectable allowlist requirement. Injection still depends on the extension, browser, site, and user permissions.
  • ChromeExtensionTransport(extensionId?, options?): legacy Chrome communication requiring the origin to match the extension's externally_connectable configuration. Without an explicit ID, it discovers page extension markers.
  • Custom Transport: implement send<TPayload, TResult>(type, payload?): Promise<TResult> while preserving protocol, security, and error semantics.

Timeout does not mean cancellation

Timeout only stops the caller from waiting. It does not cancel on-chain or Lightning operations. Never automatically retry payment, issuance, or swaps because of timeout.

Trade and secure your RGB assets | Unlock the full potential of the RGB protocol