Twetch Wallet is a wallet and browser extension that can be used to manage digital assets and access decentralized applications on the Bitcoin SV blockchain.

It works by creating and managing private keys on behalf of its users, allowing them to store funds and sign transactions.

The extension injects a bitcoin object into the javascript context of every web application the user visits. The application may then interact with the wallet, such as asking for permission to perform a transaction, through this injected object.

Pages

The Twetch Wallet browser extension will inject an object called bitcoin on the window object of any web application the user visits. The bitcoin object is also available on window.twetch to prevent namespace collisions.

To detect if a browser extension using this API is installed, you can check for the existence of the bitcoin object.

To make it easy to detect Twetch Wallet specifically, the extension adds an additional isTwetch flag.

const isTwetchInstalled = window.bitcoin && window.bitcoin.isTwetch

If Twetch Wallet is not installed, we recommend you redirect your users to our website. Altogether, this may look like the following.

const getProvider = () => {
  if ("bitcoin" in window) {
    const provider = window.bitcoin;
    if (provider.isTwetch) {
      return provider;
    }
  }
  window.open("https://twetch.com/downloads", "_blank");
};

In order to start interacting with Twetch Wallet you must first establish a connection. This connection request will prompt the user for permission to share their public key and paymail, and indicate that they are willing to interact further.

Once permission is established the first time, the web application's domain will be whitelisted for future connection requests. The user may also indicate that they are willing to auto-approve certain transactions from the application as well.

Similarly, it is possible to terminate the connection both on the application and the user side.

Connecting

The way to connect to Twetch Wallet is by calling window.bitcoin.connect().

connect()

try {
  const resp = await window.bitcoin.connect();
  resp.publicKey.toString();
  // 26qv4GCcx98RihuK3c4T6ozB3J7L6VwCuFVc7Ta2A3Uo
  resp.paymail.toString();
  // 1@twetch.me
} catch (err) {
  // { code: 4001, message: 'User rejected the request.' }
}

The call will return a Promise that resolves when the user has accepted the connection request, and reject (throw when awaited) when the user declines the request or closes the pop-up. See Errors for a breakdown of error messages Twetch Wallet may emit.

Eagerly Connecting

After a web application connects to Twetch Wallet for the first time it becomes trusted, and it is possible for the application to automatically connect to Twetch Wallet on subsequent visits, or page refreshes. This is often called "eagerly connecting".

To implement this, Twetch Wallet allows an onlyIfTrusted option to be passed into the connect() call.

connect()

window.bitcoin.connect({ onlyIfTrusted: true });

When using this flag, Twetch Wallet will only connect and emit a connect event if the application is trusted. Therefore, this can be safely called on page load for new users, as they won't be bothered by a pop-up window even if they have never connected to Twetch Wallet.

Here is an example of how you might use this to implement "eagerly connecting" in a React application

import { useEffect } from "react";

useEffect(() => {
    // Will either automatically connect to Twetch Wallet, or do nothing.
    window.bitcoin.connect({ onlyIfTrusted: true })
        .then(({ publicKey }) => {
            // Handle successful eager connection
        });
        .catch(() => {
            // Handle connection failure as usual
        })
}, []);
Twetch Wallet Browser Extension ScreenShot
Connection and transaction approval dialog for rarecandy.io

When you are Establishing a Connection, or Sending a Transaction to a user with Twetch Wallet, they are presented with the dialogs above. Twetch Wallet will inspect the HTML of the application's page itself in order to display the title and icon for the dialogs.

ValuePrimary LookupSecondary LookupFallback
TitleOpen Graph TitleDocument Title ElementNone
IconApple Touch IconFaviconA default icon

To make payments in the Twetch wallet you can call the payment contract. It will look a little something like this:

const response = await window.twetch.abi({
  contract: 'payment',
  outputs: [{
    to: '1@twetch.me',
    sats: 2180
  }]
});

Response

{
    "action": "APPROVE_ABI",
    "actionId": "27df164f-7979-4f92-835c-89fe7510bbc0",
    "origin": "https://rarecandy.io",
    "portId": "b16acb88-8beb-47ae-8aaa-cf367f1ae272",
    "rawtx": "a46776657273696f6e0266696e7075747381a46a707265765f74785f696478406338363236643933316631303365363739656131663531363831396633363139383437386366303431613633636235386663373466303366336238316432333264766f7574016a7363726970745f73696782789033303435303232313030633634396535333035393935633236663638326461323562613166326539363762643235396163656466386362366162623137643238666562636533346362303032323037383938363165663362653533633266383833383764316236363436333131306530313135323532613233623836313864313261326531323435376636333762343178423032343639666337313765326530356439333031386130663435656639333366353438633032323439313362623163636361393063616238656332356235653139616873657175656e63651affffffff676f75747075747382a26576616c75651908846e7363726970745f7075625f6b657985664f505f4455506a4f505f484153483136307828626338313761363631353661323062353332623862653661313639383965356232643165633864616e4f505f455155414c5645524946596b4f505f434845434b534947a26576616c75651a3ac3949d6e7363726970745f7075625f6b657985664f505f4455506a4f505f484153483136307828353833303633353836643033343366626138623664353136336537353433636265366131393463316e4f505f455155414c5645524946596b4f505f434845434b5349476a6e5f6c6f636b74696d6500",
    "txid": "84bff4395e7d006f390a0e417545d753e919ae1c5c3b42e4fd8a090fed07707f"
}

Outputs

An array of one or many outputs must be specified when calling the payment contract. The types parameter types are as follows:

KeyTypeDescription
tostringaddress or paymail
satsnumbersatoshis

To sign messages using BSM call the sign-message contract. It will look a little something like this:

const response = await window.twetch.abi({
  contract: 'sign-message',
  method: 'sign-message',
  payload: {
    message: 'good morning'
  }
});

Response

{
  "action": "APPROVE_ABI",
  "actionId": "dde23e3f-0baa-4148-8460-6060f5de7248",
  "address": "12tDncQvFZaZzqanupmtXpDUm42Wd4Cn4W",
  "message": "good morning",
  "origin": "https://wallet-docs.twetch.app",
  "portId": "b0fa5bc9-572a-4626-affd-97b16f8aa354",
  "sig": "Hz2pGEN3rI0mPevs3o5rseqZcefbOMwb6MECUj5KJ1TQVKQATiACKdrj29aGfq+1ofNcjvtWZpyKS0iO2Erg7r4="
}

Derivation Paths

Wallets use the two following derivation paths:

  1. Account Private Key = m/0/0
  2. Wallet Private Key = m/44'/0'/0'/0

Account Private Key

A single private key used for the majority of actions like signing in, signing your Twetch data and ECIES key exchanges in encrypted chat. The corresponding public key is used when depositing funds into your account via address/qr code

Note: When importing into 3rd party wallet softwares, you may need to only input the derivation path as m/0 or even just m.

Wallet Private Key

A rotating extended private key used to create new private keys for each transaction you make. Each time you receive funds on Twetch or via paymail, the corresponding public key is used to create a new address