Provider 与事件
发现 Provider
getInjectedProvider() 立即返回 window.stashwallet 或 undefined;detectProvider(timeoutMs = 5000) 等待注入,返回 Provider 或 null。非浏览器环境下分别返回 undefined / null。
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()发现 Provider 不代表已授权。优先通过客户端的 connect() 请求站点连接。SDK 监听 stashwallet#initialized 并轮询处理延迟注入,通常无需自己轮询。
Provider 契约
标识与版本
isStashWallet:固定为true。protocolVersion:协议版本字符串。
请求与查询
provider.request({ method, params })
// Promise<unknown>
provider.isConnected()
// Promise<boolean>
provider.getCapabilities()
// Promise<ProviderCapabilities>method 为方法名字符串,params 是可选参数。
监听与移除
provider.on(event, handler)
provider.removeListener(event, handler)订阅和移除时必须使用同一个 handler 引用。
直接 request() 的返回值为 unknown,应使用类型化客户端或自行校验数据。桥接只允许公开方法,不应调用扩展内部消息。
事件订阅与清理
事件在 Provider 上订阅,StashWalletClient 没有 on()。公开事件名称为 accountsChanged、networkChanged、disconnect,SDK 将 payload 定义为 unknown,未提供稳定结构保证。
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)
}
}组件卸载时调用返回的清理函数。将事件作为重新查询账户、网络、会话和能力的信号,不要猜测 payload 格式或仅依赖事件完成资金结算判断。
Transport 与超时
默认请求超时为 120,000 ms,默认 Provider 发现等待为 5,000 ms。
StashWalletClient.connect({ timeoutMs }) 将显式超时同时传给发现等待和请求 Transport。如果希望分别配置,请先发现 Provider,再创建 Transport:
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:首选,通过注入 Provider 通信,不依赖externally_connectable白名单;能否注入仍取决于扩展、浏览器、站点和用户权限。ChromeExtensionTransport(extensionId?, options?):兼容旧 Chrome 通信方式,需要 origin 满足扩展externally_connectable配置。未显式传 ID 时从页面扩展标记中发现。- 自定义
Transport:实现send<TPayload, TResult>(type, payload?): Promise<TResult>;必须保持协议、安全与错误语义。
超时不等于取消
超时只表示调用方停止等待,不会取消链上或闪电网络操作。不得因超时自动重试付款、发行或兑换。