Skip to content

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.

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 // primary
window.tap_wallet
window.TapWallet
window.tapWallet
window.Tap_Wallet
window.universe
window.universewallet
window.UniverseWallet
window.bitcoinuniverse
window.bitcoinUniverse

The 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.

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 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.

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.

requestAccounts()

Connect the current account. Opens an approval the first time.

Returns Promise<string[]>, holding one address, or empty.

getAccounts()

Returns Promise<string[]>. Empty when not connected or locked.

disconnect()

Ends this site’s connection.

Returns Promise<undefined>.

getPublicKey()

Returns Promise<string>, the compressed public key of the current account as hex. Returns an empty string when the wallet is locked.

getNetwork()

Returns Promise<string>. Exactly one of:

ValueMeaning
'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(network)

Parameters

  • network string: 'livenet', 'mainnet', or 'testnet'. The value 0 is 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()

Returns Promise<Object>:

  • enum string: the chain type, for example BITCOIN_MAINNET
  • name string: the human label, for example Bitcoin or Bitcoin Testnet4 (Beta)
  • network string: 'livenet' or 'testnet'

switchChain(chain)

Parameters

  • chain string: one of BITCOIN_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().

getBalance()

Marked deprecated in the source. Prefer getBalanceV2.

Returns Promise<Object> or null:

  • confirmed number: confirmed satoshis
  • unconfirmed number: unconfirmed satoshis
  • total number: total satoshis

getBalanceV2()

Returns Promise<Object> or null:

  • available number: satoshis that can fund an ordinary payment
  • unavailable number: satoshis held back, including protected coins
  • total number

The split matters. See Protected outputs.

getInscriptions(cursor = 0, size = 20)

List the inscriptions of the current account, one page at a time.

Parameters

  • cursor number: where to start. Non-negative integer. Default 0.
  • size number: how many to return. Integer from 1 to 100. Default 20.

Returns Promise<Object>:

  • total number
  • list Object[], each carrying inscriptionId, inscriptionNumber, address, outputValue, content, contentLength, contentType, preview, timestamp, offset, genesisTransaction, output, and location.

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(cursor = 0, size = 20)

Returns Promise<Array> of unspent outputs for the current account.

sendBitcoin(toAddress, satoshis, options?)

The user reviews and approves in the wallet before anything is signed or broadcast.

Parameters

  • toAddress string: up to 128 characters
  • satoshis number: positive integer
  • options Object, optional:
    • feeRate number: positive, up to 1000000
    • memo string, optional: up to 256 characters
    • memos string[], optional: up to 20 entries

Returns Promise<string>, the txid.

sendInscription(toAddress, inscriptionId, options?)

Returns Promise<string>, the txid.

sendRunes(toAddress, runeid, amount, options?)

amount is a string. Returns Promise<string>, the txid.

pushTx(rawtx)

Parameters

  • rawtx string: the raw transaction hex. Not an object.

Returns Promise<string>, the txid.

const txid = await window.tapwallet.pushTx('0200000000010135bd7d...');

signMessage(text, type)

Parameters

  • text string: up to 10000 characters
  • type string: 'ecdsa' or 'bip322-simple'. Anything else throws unsupported 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(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

  • address string: up to 128 characters
  • message string
  • signature string: up to 512 characters
  • network number, optional: 0 for mainnet, 1 for 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(messages)

Parameters

  • messages Array<{ 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(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(psbtHex, options?)

Signs the inputs that match the current account.

Parameters

  • psbtHex string: hex, or base64. Up to 8 MiB.
  • options Object, optional:
    • autoFinalized boolean: whether to finalize after signing. Defaults to true.
    • approvalAction string, optional: only 'listing' is accepted.
    • toSignInputs Array, optional, up to 10000 entries:
      • index number: which input to sign. Non-negative integer, 0 to 10000, unique within the array.
      • address string: the current account’s address. Supply this or publicKey.
      • publicKey string: the current account’s compressed public key, as hex. Supply this or address.
      • sighashTypes number[], optional: up to 8 entries.
      • disableTweakSigner boolean, optional: when signing Taproot inputs the tweaked signer is used by default. Enabling this signs with the untweaked key.
      • useTweakedSigner boolean, optional.
      • tapLeafHashToSign string, optional: hex, up to 64 characters.
    • contracts Array, 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(psbtHexs, options?)

Parameters

  • psbtHexs string[]: up to 20 entries, 16 MiB total
  • options Object[], optional: a parallel array, up to 20 entries, each the same shape as signPsbt options

Returns Promise<string[]>.

signAndPushPsbt(psbtHex, options?)

Returns Promise<Object>: psbtHex, rawtx, txid, and bip110.

signAndBroadcastPsbt(psbtHex, options?) is an alias for this method.

pushPsbt(psbtHex)

Returns Promise<string>, the txid.

These carry protocol and operation gates, so they can be unavailable in a build. Check getCapabilities() first.

MethodSignature
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

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.

EventPayload
accountsChangedstring[], the exposed addresses. An empty array on disconnect.
networkChangedstring, the network name
chainChangedthe chain object, the same shape getChain() returns
connectconnection data
disconnect, closea provider error object
ecosystemChangedecosystem state
const onAccounts = (accounts) => { /* re-read state, never cache an address forever */ };
window.tapwallet.on('accountsChanged', onAccounts);
// later
window.tapwallet.removeListener('accountsChanged', onAccounts);

Rejections carry { code, message }.

CodeMeaningWhen
4001User rejected the requestThe 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.
4100UnauthorizedThe site is not connected, or its permission was revoked while the request was pending.
4900DisconnectedThe extension context was invalidated, usually by a reload or an update.
-32601Method not foundNo handler for that method name.
-32600Invalid requestA malformed payload.
-32603Internal errorAn 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.