Provider API
For developers building web applications that integrate Universe Wallet. Every signature below was read from the extension source at 1.7.5.8. Where the source declares no return type, the runtime shape is given and marked as such.
Read Integrating with the wallet first for the rules that come before any code.
The provider object
Section titled “The provider object”With the extension installed, every page gets a provider object. The
primary name is window.tapwallet.
if (typeof window.tapwallet !== 'undefined') { console.log('Universe Wallet is available');}The same object is also defined under nine aliases, all non-writable, all pointing at one proxy:
window.tapwallet // primarywindow.tap_walletwindow.TapWalletwindow.tapWalletwindow.Tap_Walletwindow.universewindow.universewalletwindow.UniverseWalletwindow.bitcoinuniversewindow.bitcoinUniverseThe object carries identity flags you can branch on: isUniverse, isBitcoinUniverse, and
isTapWallet are all true; isUniSat and isUnisat are both false. The namespace string reported
by getCapabilities() is bitcoinuniverse.
Waiting for injection
Section titled “Waiting for injection”The content script sets data-tapwallet-injected="true" and data-universe-wallet-injected="true" on
the <html> element, and dispatches an initialization event on window for every alias, twice: once
immediately and once when initialization completes.
function whenWalletReady(cb) { if (window.tapwallet) return cb(window.tapwallet); window.addEventListener('tapwallet#initialized', () => cb(window.tapwallet), { once: true });}Properties whose names begin with an underscore return undefined through the proxy, apart from the
EventEmitter internals. Do not rely on any of them.
Connecting
Section titled “Connecting”Connecting means asking to see the user’s selected account address. It never authorizes spending. Every later transaction or message opens its own approval, and idle connections expire on their own.
Call requestAccounts from a control the user clicked. Disable the control while the promise is
pending.
try { const accounts = await window.tapwallet.requestAccounts(); console.log('connected', accounts);} catch (e) { console.log('rejected or unavailable', e.code, e.message);}requestAccounts resolves to a string[] holding one address, or an empty array when no account is
available.
Availability, before anything else
Section titled “Availability, before anything else”const caps = await window.tapwallet.getCapabilities();// caps.namespace === 'bitcoinuniverse'// caps.capabilitiesVersion === 2// caps.bitcoin, caps.dogecoin, caps.zcash, caps.bip110, caps.atomicals,// caps.protocols, caps.protocolOperations are boolean maps.getFeatures() returns the same object.
Account and network
Section titled “Account and network”requestAccounts
Section titled “requestAccounts”requestAccounts()
Connect the current account. Opens an approval the first time.
Returns Promise<string[]>, holding one address, or empty.
getAccounts
Section titled “getAccounts”getAccounts()
Returns Promise<string[]>. Empty when not connected or locked.
disconnect
Section titled “disconnect”disconnect()
Ends this site’s connection.
Returns Promise<undefined>.
getPublicKey
Section titled “getPublicKey”getPublicKey()
Returns Promise<string>, the compressed public key of the current account as hex. Returns an
empty string when the wallet is locked.
getNetwork
Section titled “getNetwork”getNetwork()
Returns Promise<string>. Exactly one of:
| Value | Meaning |
|---|---|
'livenet' | Bitcoin mainnet |
'testnet' | Bitcoin Testnet or Testnet4 |
'unknown' | The active chain is Signet, Fractal, Dogecoin, or Zcash |
const network = await window.tapwallet.getNetwork();console.log(network);// 'livenet'switchNetwork
Section titled “switchNetwork”switchNetwork(network)
Parameters
networkstring:'livenet','mainnet', or'testnet'. The value0is also accepted for mainnet.
Returns Promise<string>, the resulting network name, 'livenet' or 'testnet'.
Rejects with a message naming the supported networks if the value is not one of them. No approval is shown when the requested network already matches the active one.
const network = await window.tapwallet.switchNetwork('livenet');console.log(network);// 'livenet'getChain
Section titled “getChain”getChain()
Returns Promise<Object>:
enumstring: the chain type, for exampleBITCOIN_MAINNETnamestring: the human label, for exampleBitcoinorBitcoin Testnet4 (Beta)networkstring:'livenet'or'testnet'
switchChain
Section titled “switchChain”switchChain(chain)
Parameters
chainstring: one ofBITCOIN_MAINNET,BITCOIN_TESTNET,BITCOIN_TESTNET4,BITCOIN_SIGNET,FRACTAL_BITCOIN_MAINNET,FRACTAL_BITCOIN_TESTNET,DOGECOIN_MAINNET,DOGECOIN_TESTNET,ZCASH_MAINNET,ZCASH_TESTNET.
Returns the same object shape as getChain().
Balances and holdings
Section titled “Balances and holdings”getBalance
Section titled “getBalance”getBalance()
Marked deprecated in the source. Prefer getBalanceV2.
Returns Promise<Object> or null:
confirmednumber: confirmed satoshisunconfirmednumber: unconfirmed satoshistotalnumber: total satoshis
getBalanceV2
Section titled “getBalanceV2”getBalanceV2()
Returns Promise<Object> or null:
availablenumber: satoshis that can fund an ordinary paymentunavailablenumber: satoshis held back, including protected coinstotalnumber
The split matters. See Protected outputs.
getInscriptions
Section titled “getInscriptions”getInscriptions(cursor = 0, size = 20)
List the inscriptions of the current account, one page at a time.
Parameters
cursornumber: where to start. Non-negative integer. Default0.sizenumber: how many to return. Integer from1to100. Default20.
Returns Promise<Object>:
totalnumberlistObject[], each carryinginscriptionId,inscriptionNumber,address,outputValue,content,contentLength,contentType,preview,timestamp,offset,genesisTransaction,output, andlocation.
Returns { list: [], total: 0 } when the wallet is locked.
const page = await window.tapwallet.getInscriptions(0, 20);console.log(page.total, page.list.length);getBitcoinUtxos
Section titled “getBitcoinUtxos”getBitcoinUtxos(cursor = 0, size = 20)
Returns Promise<Array> of unspent outputs for the current account.
Sending
Section titled “Sending”sendBitcoin
Section titled “sendBitcoin”sendBitcoin(toAddress, satoshis, options?)
The user reviews and approves in the wallet before anything is signed or broadcast.
Parameters
toAddressstring: up to 128 characterssatoshisnumber: positive integeroptionsObject, optional:feeRatenumber: positive, up to 1000000memostring, optional: up to 256 charactersmemosstring[], optional: up to 20 entries
Returns Promise<string>, the txid.
sendInscription
Section titled “sendInscription”sendInscription(toAddress, inscriptionId, options?)
Returns Promise<string>, the txid.
sendRunes
Section titled “sendRunes”sendRunes(toAddress, runeid, amount, options?)
amount is a string. Returns Promise<string>, the txid.
pushTx
Section titled “pushTx”pushTx(rawtx)
Parameters
rawtxstring: the raw transaction hex. Not an object.
Returns Promise<string>, the txid.
const txid = await window.tapwallet.pushTx('0200000000010135bd7d...');Signing
Section titled “Signing”signMessage
Section titled “signMessage”signMessage(text, type)
Parameters
textstring: up to 10000 characterstypestring:'ecdsa'or'bip322-simple'. Anything else throwsunsupported message type.
Returns Promise<string>, the signature, base64 encoded. For ECDSA it is the standard 65-byte
Bitcoin signed-message form: a one-byte recovery header followed by a 64-byte compact signature.
const signature = await window.tapwallet.signMessage('abcdefghijk123456789', 'ecdsa');verifyMessageOfBIP322Simple
Section titled “verifyMessageOfBIP322Simple”verifyMessageOfBIP322Simple(address, message, signature, network?)
Verification without leaving the wallet. This method is public: it needs no connection, no unlock, and no approval, and it is not gated by a release authorization.
Parameters
addressstring: up to 128 charactersmessagestringsignaturestring: up to 512 charactersnetworknumber, optional:0for mainnet,1for testnet. This is the numeric network type, not the'livenet'string.
Returns Promise<number>: 1 when the signature is valid, 0 when it is not. A number, not a
boolean.
const valid = await window.tapwallet.verifyMessageOfBIP322Simple( 'bc1p...redacted', 'abcdefghijk123456789', 'AkcwRAIgeHUcjr0jODaR7GMM8cenWnIj0MYdGmmr...',);console.log(valid === 1);multiSignMessage
Section titled “multiSignMessage”multiSignMessage(messages)
Parameters
messagesArray<{ text: string, type: string }>: 1 to 20 entries
Returns Promise<string[]>.
Every message in the batch is still a separate commitment. See What a signature authorizes.
signData
Section titled “signData”signData(data, type)
Signs data that is not readable text.
Returns Promise<string>.
Throws unless the user has enabled raw data signing in Advanced settings, which is off by default and requires a typed confirmation. Treat a request for this as unusual and explain to your users, on your own page, why you need it.
signPsbt
Section titled “signPsbt”signPsbt(psbtHex, options?)
Signs the inputs that match the current account.
Parameters
psbtHexstring: hex, or base64. Up to 8 MiB.optionsObject, optional:autoFinalizedboolean: whether to finalize after signing. Defaults totrue.approvalActionstring, optional: only'listing'is accepted.toSignInputsArray, optional, up to 10000 entries:indexnumber: which input to sign. Non-negative integer, 0 to 10000, unique within the array.addressstring: the current account’s address. Supply this orpublicKey.publicKeystring: the current account’s compressed public key, as hex. Supply this oraddress.sighashTypesnumber[], optional: up to 8 entries.disableTweakSignerboolean, optional: when signing Taproot inputs the tweaked signer is used by default. Enabling this signs with the untweaked key.useTweakedSignerboolean, optional.tapLeafHashToSignstring, optional: hex, up to 64 characters.
contractsArray, optional: up to 100 entries.
Returns Promise<string>, the signed PSBT as hex.
const signed = await window.tapwallet.signPsbt('70736274ff01007d...', { autoFinalized: false, toSignInputs: [ { index: 0, address: 'tb1q...redacted' }, { index: 1, address: 'tb1q...redacted', sighashTypes: [1] }, { index: 2, publicKey: '02062...8779693f' }, ],});signPsbts
Section titled “signPsbts”signPsbts(psbtHexs, options?)
Parameters
psbtHexsstring[]: up to 20 entries, 16 MiB totaloptionsObject[], optional: a parallel array, up to 20 entries, each the same shape assignPsbtoptions
Returns Promise<string[]>.
signAndPushPsbt
Section titled “signAndPushPsbt”signAndPushPsbt(psbtHex, options?)
Returns Promise<Object>: psbtHex, rawtx, txid, and bip110.
signAndBroadcastPsbt(psbtHex, options?) is an alias for this method.
pushPsbt
Section titled “pushPsbt”pushPsbt(psbtHex)
Returns Promise<string>, the txid.
Protocol methods
Section titled “Protocol methods”These carry protocol and operation gates, so they can be unavailable in a build. Check
getCapabilities() first.
| Method | Signature |
|---|---|
inscribeTransfer | (ticker: string, amount: string), returns {inscriptionId, inscriptionNumber, ticker, amount} |
requestMint | (options?: Object), returns {status, orderId, txid, psbtHex?} |
requestArc20Mint | (options?: Object), delegates to requestMint |
getBip110DeploymentState | () |
analyzeBip110 | ({ psbtHex }) or ({ rawtx }), exactly one of the two |
isAtomicalsEnabled | (), returns boolean |
getDogecoinMarketplaceAccount | (), returns {address, publicKey, network} or null |
getDogecoinMarketplaceFundingInputs | (minimumValueSats: string, maxInputs = 20) |
signDogecoinMessage | (message: string), returns string |
signDogecoinMarketplaceAction | (preparedAction) |
getZcashAccount, getZcashBalance | (), returns an object or null |
signZcashTransaction, broadcastZcashTransaction, signZcashMarketListing | (request) |
getVersion | (), returns the build version string |
Events
Section titled “Events”The provider extends Node’s EventEmitter, so on, once, off, addListener,
removeListener, and removeAllListeners are all available. The listener limit defaults to 100.
Events are delivered only after initialization completes.
Clean up when your component unmounts, or handlers pile up across renders.
| Event | Payload |
|---|---|
accountsChanged | string[], the exposed addresses. An empty array on disconnect. |
networkChanged | string, the network name |
chainChanged | the chain object, the same shape getChain() returns |
connect | connection data |
disconnect, close | a provider error object |
ecosystemChanged | ecosystem state |
const onAccounts = (accounts) => { /* re-read state, never cache an address forever */ };window.tapwallet.on('accountsChanged', onAccounts);// laterwindow.tapwallet.removeListener('accountsChanged', onAccounts);Errors
Section titled “Errors”Rejections carry { code, message }.
| Code | Meaning | When |
|---|---|---|
4001 | User rejected the request | The user declined or closed the approval. Also raised when a second approval is requested while one is pending, and when the account or signing context changed while a request was in flight. |
4100 | Unauthorized | The site is not connected, or its permission was revoked while the request was pending. |
4900 | Disconnected | The extension context was invalidated, usually by a reload or an update. |
-32601 | Method not found | No handler for that method name. |
-32600 | Invalid request | A malformed payload. |
-32603 | Internal error | An internal rejection. |
Validation failures surface as plain Error objects with a descriptive message and no code. So does
Too many chained approval requests, which is raised above five chained approvals.