Pear Worklet WDK Configuration
Configure Pear Worklet HRPC and JSON-RPC contexts, WDK payloads, and generic modules
This page explains how to build the worklet context, shape the worklet config payload, initialize WDK, call generic modules, and choose a transport.
Worklet Context
You can bind the shipped RPC handlers to your Bare worklet using registerRpcHandlers():
require('bare-node-runtime/global')
const { registerRpcHandlers } = require('@tetherto/pear-wrk-wdk/worklet')
const wdkModule = require('@tetherto/wdk', { with: { imports: 'bare-node-runtime/imports' } })
const { createModule: createPreferencesModule } = require('@your-org/wdk-module-preferences')
const WDK = wdkModule.default || wdkModule.WDK || wdkModule
const walletCache = {}
function loadWalletManager(network) {
if (walletCache[network]) return walletCache[network]
let walletModule
if (network === 'ethereum') {
walletModule = require('@tetherto/wdk-wallet-evm', { with: { imports: 'bare-node-runtime/imports' } })
}
if (network === 'spark') {
walletModule = require('@tetherto/wdk-wallet-spark', { with: { imports: 'bare-node-runtime/imports' } })
}
if (walletModule) walletCache[network] = walletModule.default || walletModule
return walletCache[network] || null
}
const walletManagers = new Proxy({}, {
get: (_, network) => loadWalletManager(network),
has: (_, network) => ['ethereum', 'spark'].includes(network)
})
const context = {
wdk: null,
WDK,
walletManagers,
protocolManagers: {},
moduleManagers: {
preferences: {
createModule: createPreferencesModule,
events: ['changed']
}
},
capabilities: {},
wdkLoadError: null
}
module.exports = (rpc) => {
registerRpcHandlers(rpc, context)
Bare.on('suspend', async () => {
await context.moduleRuntime?.suspendAll()
})
Bare.on('resume', async () => {
await context.moduleRuntime?.resumeAll()
})
}Required Context Fields
wdk: The current WDK instance. Set this tonullbefore the first initialization.WDK: The WDK constructor used to create the seeded instance.walletManagers: A map from blockchain name to wallet manager implementation.protocolManagers: A map from protocol name to protocol manager implementation.wdkLoadError: Any startup error captured while loading WDK. Usenullwhen there is no load failure.
For HRPC generic modules, moduleManagers optionally maps module names to { createModule, events? }. The factory receives { seed, config, capabilities, emit } and can return an instance or a promise. capabilities is an optional host-supplied object and is empty by default. The runtime manages moduleRuntime and moduleInstances; do not initialize those fields yourself. Manual integrations must forward Bare suspend and resume events as shown if module instances should receive those lifecycle calls. Worklet Bundler-generated HRPC entrypoints wire them automatically.
Worklet Config Payload
Both initializeWDK() and resetWdkWallets() expect config to be a JSON string. The decoded object must contain at least one entry under networks.
const workletConfig = {
networks: {
ethereum: {
blockchain: 'ethereum',
config: {
provider: 'https://rpc.ankr.com/eth_sepolia'
}
}
},
protocols: {
moonpay: {
blockchain: 'ethereum',
protocolName: 'moonpay',
config: {
environment: 'sandbox'
}
}
},
modules: {
preferences: {
storagePath: '/app-data/preferences'
}
}
}Payload Rules
networksis required and must contain at least one network entry.- Each network entry must include
blockchainand an objectconfig. protocolsis optional during initialization.modulesis optional and contains runtime config for named generic modules. Each key must match amoduleManagerskey in the HRPC context and the corresponding build-time Worklet Bundler module name.resetWdkWallets()reads only thenetworksportion of the decoded config.
Generic modules are HRPC-only in beta.10. The JSON-RPC handler does not construct modules or expose module calls and events.
Initialize WDK
You can create and register the WDK instance inside the worklet using initializeWDK():
const { HRPC } = require('@tetherto/pear-wrk-wdk')
const hrpc = new HRPC(ipcStream)
await hrpc.initializeWDK({
encryptionKey: secrets.encryptionKey,
encryptedSeed: secrets.encryptedSeedBuffer,
config: JSON.stringify(workletConfig)
})Initialization Rules
- Pass both
encryptionKeyandencryptedSeed, or omit both together. - On first initialization, the worklet must receive an encrypted seed pair so it can create
context.wdk. - If
context.wdkalready exists, a laterinitializeWDK()call disposes the existing instance and closes its generic modules before re-registering wallets and protocols from the new config. - In beta.10, generic modules are constructed only when that
initializeWDK()request includes bothencryptionKeyandencryptedSeed. A seedless reinitialization closes existing module instances but does not rebuild them, even whenconfig.modulesis present. Supply the seed pair on every initialization that must construct or reconstruct modules. - Module
close()is called during full disposal or reinitialization. Targeted blockchain disposal leaves generic modules running. Optionalsuspend()andresume()methods run only when the host forwards Bare lifecycle events; the manual context above and Worklet Bundler-generated HRPC entrypoints do so.
Reset Selected Wallets
You can selectively dispose and re-register wallet modules using resetWdkWallets():
await hrpc.resetWdkWallets({
config: JSON.stringify({
networks: {
ethereum: {
blockchain: 'ethereum',
config: {
provider: 'https://rpc.ankr.com/eth_sepolia'
}
}
}
})
})Reset Rules
resetWdkWallets()requires an existing initializedcontext.wdk.- The handler calls
wdk.dispose(targetChains)with the blockchains extracted fromconfig.networks. - Only wallets listed in the request
networksobject are re-registered. - The reset flow does not re-register protocols.
- The reset flow does not close or reconstruct generic modules; existing module instances keep running.
Call Wallet and Protocol Methods
You can execute wallet account methods through callMethod():
const result = await hrpc.callMethod({
methodName: 'getAddress',
network: 'ethereum',
accountIndex: 0
})Call Method Notes
argsis optional and must be a JSON string when provided.optionsis optional and must be a JSON string when provided.- When
argsdecodes to an array, the handler spreads the values as positional method arguments. - When
argsdecodes to an object or primitive, the handler passes it as a single argument. - Set
options.protocolTypetoswap,swidge,bridge,lending, orfiatto call a protocol wrapper. Every protocol call requires a non-emptyoptions.protocolName.
Call Generic Module Methods
On an HRPC worklet configured with matching moduleManagers and runtime modules, call a module method by name:
const response = await hrpc.callModule({
module: 'preferences',
method: 'getTheme',
args: JSON.stringify([])
})
const theme = response.result ? JSON.parse(response.result) : undefinedargs is an optional JSON string. Arrays are spread into positional arguments; a non-array value is passed as one argument. Promise results are awaited, .toArray() results are materialized, and Uint8Array values are normalized to hex before the response is serialized.
Subscribe to events declared by the module manager:
hrpc.onModuleEvent(({ module, event, payload }) => {
if (module === 'preferences' && event === 'changed') {
const value = payload ? JSON.parse(payload) : undefined
console.log('Preferences changed:', value)
}
})JSON-RPC Transport
Native hosts can register the separate framed JSON-RPC server entrypoint:
const { registerJsonRpcHandlers } = require('@tetherto/pear-wrk-wdk/jsonrpc')
module.exports = (ipc) => {
registerJsonRpcHandlers(ipc, context)
}Messages are UTF-8 JSON-RPC 2.0 objects prefixed by a four-byte unsigned big-endian payload length. Requests require an ID, and IDs must be unique while a request is in flight. The package exports no JSON-RPC host/client helper; the native host must implement framing and correlation.
JSON-RPC beta.10 supports WDK initialization and disposal, secret/mnemonic operations, wallet and protocol calls, and dynamic wallet/protocol registration. Its shared callMethod handler supports the swidge protocol type. It does not support resetWdkWallets, callModule, or module events. See the API reference for the exact method list.
INFO-level logs can contain wallet-call arguments and JSON-RPC parameters or results. Keep production logging at its default ERROR level when requests may contain sensitive values.