UNPKG

accounts

Version:

Tempo Accounts SDK

108 lines 5.4 kB
import { Hex, Provider as core_Provider } from 'ox'; import { custom } from 'viem'; import { z } from 'zod/mini'; import * as Adapter from '../../Adapter.js'; import * as Rpc from '../../zod/rpc.js'; import * as u from '../../zod/utils.js'; /** * Builds an adapter that forwards wallet RPC to a remote wallet through a * single request function. * * Shared core for adapters whose wallet lives behind a request/response * session (e.g. Wata mobile web auth or postMessage). Access keys are * generated locally; every other wallet action round-trips through * `request`. */ export function fromRequest(options) { const { actions, bind, cleanup, close, icon, keystores, name, rdns, request: requestRemote, } = options; return Adapter.define({ ...(icon ? { icon } : {}), name, rdns, schema: z.object({ address: u.address() }) }, ({ getAccount, getClient, store }) => { // Late-bind the store so the request channel can reconcile local // connection state (e.g. a wallet `accountsChanged` notification). bind?.({ store }); const provider = core_Provider.from({ async request(request) { const { accounts, activeAccount, chainId } = store.getState(); if (request.method === 'eth_chainId') return Hex.fromNumber(chainId); // Forward the active account + chain as request context so the wallet // acts against the session the app believes it is using rather than // whatever the wallet last selected for itself. const account = accounts[activeAccount]?.address; return await requestRemote({ method: request.method, params: request.params, context: { chainId, ...(account ? { account } : {}) }, }); }, }); // Connect capabilities are read from the first account only: the remote // wallet connects a single account per exchange. function toConnectReturn(result) { const capabilities = result.accounts[0]?.capabilities; return { accounts: result.accounts.map((account) => ({ address: account.address })), ...(capabilities?.auth ? { auth: capabilities.auth } : {}), ...(capabilities?.identity ? { identity: capabilities.identity } : {}), ...(capabilities?.keyAuthorization ? { keyAuthorization: capabilities.keyAuthorization } : {}), ...(capabilities?.personalSign ? { personalSign: capabilities.personalSign } : {}), ...(capabilities?.signature ? { signature: capabilities.signature } : {}), ...(capabilities?.username !== undefined ? { username: capabilities.username } : {}), }; } return { forwardsAuth: true, ...(keystores ? { accessKey: { keystores } } : {}), actions: { async createAccount(_parameters, request) { return toConnectReturn((await provider.request(request))); }, async loadAccounts(_parameters, request) { return toConnectReturn((await provider.request(request))); }, async deposit(_parameters, request) { return (await provider.request(request)); }, async depositZone(parameters, request) { return (await provider.request({ ...request, params: [z.encode(Rpc.wallet_depositZone.parameters, parameters)], })); }, // `disconnect` (when `close` is set) only tears down the local // wallet session — it is never forwarded. No `switchChain` action: // chain selection is local state the provider handles itself, and // forwarding it would open a wallet session for nothing. ...(close ? { disconnect: close } : {}), async swap(_parameters, request) { return (await provider.request(request)); }, async transfer(parameters, request) { return (await provider.request({ ...request, params: [z.encode(Rpc.wallet_transfer.parameters, parameters)], })); }, async withdrawZone(parameters, request) { return (await provider.request({ ...request, params: [z.encode(Rpc.wallet_withdrawZone.parameters, parameters)], })); }, ...actions?.({ getClient, request: requestRemote, store }), }, ...(cleanup ? { cleanup } : close ? { cleanup: () => void close() } : {}), getAccount(parameters = {}) { return { account: { address: parameters.address ?? getAccount({ signable: false }).address, type: 'json-rpc', }, transport: custom(provider), }; }, }; }); } //# sourceMappingURL=fromRequest.js.map