Welcome to ElectrumSV’s documentation!

ElectrumSV is a wallet application for Bitcoin SV, a peer to peer form of electronic cash. As a wallet application it allows you to track, receive and spend bitcoin whenever you need to. But that’s just the basics, as it manages and secures your keys it also helps you to do many other things.

Important

ElectrumSV can only be downloaded from electrumsv.io.

Getting started

Before you can send and receive payments, you need to first create a wallet, and then create at least one account within it.

How do you know you have the official software and not malware?

Every person who had their coins stolen and was interested in investigating, identified that they had not downloaded from our official web site, and had instead obtained malware from some other fake site. Many swore they downloaded from the official site until their verified their download and found it to be malware. Read more about verifying your download.

How do you create a wallet?

Your wallet is a standalone container for all your bitcoin-related data. You should be able to create as many accounts as you need within it, each account containing separated funds much like a bank account. Read more about creating a wallet.

How do you create an account?

Each account in your wallet is much like a bank account, with the funds in each separated from the others. Read more about creating an account.

How do you receive a payment from someone else?

Each account has the ability to provide countless unique and private receiving addresses and by giving a different one of these out to each person who will send you coins, allows you to receive funds from them. Read more about receiving a payment.

How do you make a payment to someone else?

By obtaining an address from another person, if you have coins in one of your accounts, you should be able to send some or all of those coins to that address. Read more about making a payment.

Verifying your download

Probably a dozen people have reported having their coins stolen, and any who were willing to investigate found they had downloaded a malware version of ElectrumSV and not an official download. More than one asserted that they had downloaded from our web site, but what they meant was that they had downloaded from a fake web site that had stolen our design.

Downloading an executable from a web site and running it is risky, and what you are putting your trust in, is that because you download from our official web site you are getting an executable you can safely run. Despite this, well meaning people have downloaded from fake versions of our web site, and paid the price for it.

It is in your best interests to verify your download is the official one. The goal of this page is to try and show you how to do that.

What are you verifying?

You will be checking the checksum (also known as a hash) of the file you downloaded. This is a standard algorithm that you can get lots of different software for, which will give you a series of letters and numbers that represent the uniqueness of your file. The algorithm we use for ElectrumSV is called SHA256 and we provide an official checksum for each file we make available. You will be comparing that official checksum to the one generated for your file. If it is the same, you should have the official version of that file. If it is different, you have downloaded malware instead.

The official checksums

We do not provide the checksums on the official web site where you find our download links, because this allows any attacker who manages to compromise the web site, to also replace the official checksums. Additionally, if there is a fake web site that offers both download links and checksums you should know something is fishy.

The official checksums are available from Github, where our open source code is located. You do not need to compare against the illustrative screenshot below, just click on the Github link and view them there.

The list SHA256 hashes for the official downloads.

The list SHA256 hashes for the official downloads.

Verifying your download

There is no easy way to check a download. Some level of technical competence is useful, although if you do not consider yourself technically competent and can follow instructions you should still be able to do it. Others have managed to do it, and as we get these instructions into a more approachable state over time, you should be able to as well.

Find your operating system below, and check out the options listed for it. Some of them may be better than others, but some assurance that your download is legitimate is better than nothing.

Windows

Several methods of verifying your download on Windows are provided below. Any one should be good enough, but if you are a user who primarily uses a web browser you may need to learn to use the explorer or console.

Using the digital signatures

Thanks to the kindness of the Bitcoin Association, we now have the ability to sign our Windows executables from version 1.3.12 and above. In theory the presence of our signature on the executable you downloaded should be just as reliable as checking the checksum. You can check if the executable you downloaded has our signature, and if it is present you can assume that the file should be legitimate. Your first step is to find the executable you downloaded with the Windows explorer. You can open the Windows explorer with the windows and e key, then locate the directory your executable is located in.

Windows explorer.

Windows explorer.

Right click on the file, and select Properties. This should open the properties window for the file, where you should select the Digital Signatures tab to see the signature.

The digital signature.

The digital signature.

From there click on Details and then View Certificate. You should see a certificate with the following information for the given version.

1.3.12 and above

The certificate should be issued to Bitcoin Association for BSV, be issued by COMODO RSA Extended Validation Code Signing CA and as of the time of writing be valid from 10/11/2020 to 11/11/2022.

The digital certificate.

The certificate the file was signed with.

Using certutil

certutil is already present in your Windows installation already. However, it requires opening a command prompt to run it, which might be something beyond some users. Press the Windows key and the s key at the same time, this will open the Windows searchy thing and there you can type cmd and then press the enter key to open a command prompt.

Opening a command prompt

Opening a command prompt.

Then you need to change the directory until you are in the same directory as the file you wish to get a checksum for. The cd command is used for this. Then you can use the certutil command to generate a SHA 256 checksum for that file. The syntax is certutil --hashfile <filename> SHA256, but remember you need to replace <filename> with the actual file name. You can see an illustration of this in the image below.

The certutil checksum result

The certutil checksum result.

If you find the ElectrumSV-1.3.12.exe entry in the linked Github list, you can see it matches the certutil checksum result. The case of the letters does not matter, both lower case and upper case are equivalent. If you get a different result, and the command complains that it cannot find the file, then the file is not in the current directory. You need to use the cd command to change the current directory as mentioned above.

Using 7-Zip

This requires that you download the 7-Zip installer. Any of the non-standalone executables from the 7-Zip web site, should be fine. Download one and install it. Once it is installed, you should have a handy context menu available that can give you the SHA 256 checksum for your file. Simply select your file, open the context menu and generate the checksum. Do not reflect on the fact that no-one in their life ever wanted to “Share with Skype” and that they put it up the top before all the useful stuff.

The 7-Zip context menu

The 7-Zip context menu.

In this case, we selected the SHA-256 menu option for the ElectrumSV-1.3.12.exe file and the following image shows the resulting checksum.

The 7-Zip checksum result

The 7-Zip checksum result.

If you find the ElectrumSV-1.3.12.exe entry in the linked Github list, you can see it matches the 7-zip checksum result. The case of the letters does not matter, both lower case and upper case are equivalent.

MacOS

The following approaches require the user to deal with the terminal. If you are unable to work out how to do this, remember you can always file a support request on the official ElectrumSV issue tracker.

shasum

This approach requires no application installation, but it does involve you being willing to use the terminal application. If you do not know how to locate this, start by opening the launchpad application using it’s rocket icon in the dock.

Open the launchpad application search.

Open the launchpad application search.

You should see the screen shown below. Enter terminal and it should show you one matching application which you should open.

Search for the 'terminal' application.

Search for the ‘terminal’ application.

Work out what directory the terminal is looking at, and change it using the cd command. In the case shown below, the downloaded file was conveniently located in the Downloads folder and as this should also be the case for you the required commands should be the same. Type cd Downloads followed by shasum -a 256 <filename> where you replace <filename> with the actual file name of your download. Shown below, the file name was ElectrumSV-1.3.12.dmg and if you downloaded this file you also would use shasum -a 256 ElectrumSV-1.3.12.dmg as shown.

Run the 'shasum' application on your downloaded file.

Run the ‘shasum’ application on your downloaded file.

If you find the ElectrumSV-1.3.12.dmg entry in the linked Github list, you can see it matches the shasum checksum result. The case of the letters does not matter, both lower case and upper case are equivalent. If you get a different result, and the command complains that it cannot find the file, then the file is not in the current directory. You need to use the cd command to change the current directory as mentioned above.

GNU Privacy Guard

By installing GNU Privacy Guard (GPG) you have a way to verify that the signatures provided by the developers for the files you download, prove those files came from those developers. This is quite involved to do, but it might be that you are more comfortable with this approach.

Start by downloading and installing GPG from the GPGTools web site. This gives you a way to check signatures for files. The next step is to obtain the keys for the ElectrumSV developers, and to register them with GPG. This is a little complicated so you need to follow these steps.

Open the pubkeys folder from the official ElectrumSV Github repository in Safari. You should see two files listed, rt121212121.asc and kyuupichain.asc. For each file perform the following key import actions.

Key import

Remember that this has to be done for all of the listed public keys in the ElectrumSV Github folder. Once you are viewing the raw page for a key, select (press Command with a) and copy (press Command and c) the key text.

Select and copy the public key text.

Select and copy the public key text.

As soon as you have copied the key text, the GPG application you installed will signal that it has detected a public key was copied. You will see it’s icon in your dock jumping up and down. Click on it to import the key.

Observe the GPG icon in the dock indicating that it can act on the copied key.

Observe the GPG icon in the dock indicating that it can act on the copied key.

The GPG application will require you to approve the import, so go ahead and do that.

Approve the public key import.

Approve the public key import.

Once the public key is imported, you will see another sheet drop down to tell you if it was imported successfully or not. It will of course be successful.

Observe the successful public key import.

Observe the successful public key import.

You can confirm the key was imported successfully, by observing that it is now present in the list in the GPG application.

Observe the imported public key is present in your GPG application.

Observe the imported public key is present in your GPG application.

Go ahead and import any keys you haven’t imported already, then you are all set to verify the signature of an ElectrumSV download when you need to.

Verify a download

Let’s say you have downloaded ElectrumSV-1.3.12.dmg from the official ElectrumSV downloads page. You now need to find and download the signature for that file, so that you can verify it was created by the ElectrumSV developers. The signatures are located on the official ElectrumSV web site, under it’s download folder. The .dmg you downloaded was for version 1.3.12 so locate the folder by that name, and look inside it. You should see the signature file ElectrumSV-1.3.12.dmg.sig, which is what you need to download ElectrumSV-1.3.12.dmg.

Confirm you have downloaded both the .dmg and the matching .dmg.sig files.

Confirm you have downloaded both the .dmg and the matching .dmg.sig files.

Open the context menu for the ElectrumSV-1.3.12.dmg file (press Control when you click on the file). You will see a Services sub-menu, with an additional OpenPGP: Verify Signature of File beneath it. Click on this verify sub-menu.

Open the context menu and select the OpenPGP verify entry.

Open the context menu and select the OpenPGP verify entry.

The GPG application will verify the .dmg using the detected matching .dmg.sig file and let you know the result.

Observe the verification result.

Observe the verification result.

As you can see the signature was verified. If you want to go through the process of trusting the ElectrumSV keys, there is a link there you can use for next time.

Creating a wallet

From ElectrumSV 1.3 and beyond, a wallet is now a container for your accounts. This guide shows you how to create an empty wallet with no accounts. After creating the wallet, you will of course want to add an account to it, in order to be able to start using it.

Choosing the location and file name

The first step is to choose where to store your wallet, and what it’s file name should be. If you choose not to store your wallet in the default location that ElectrumSV uses, it is likely that you will quickly be able to find it again in the “Recently Opened Wallets” list when you open it again in the future.

Start off at the wallet selection page.

blah

The wallet selection page.

You will be presented with a file dialog that lets you choose where your wallet will be stored, and what it will be named. It defaults to the standard ElectrumSV wallet location on your operating system. Enter a file name, and click “Save” (or press the enter key).

blah

The wallet file name dialog.

Add a mandatory password

The next step is setting a password for your new wallet. We require a password and there is no way to opt out, but you can always enter something like “password” or “123456” if you wish. This is also required for hardware and watch-only wallets, where there is no key or seed word data to encrypt.

blah

The wallet file name dialog.

Once you have entered a password, and confirmed it, the “OK” button will become enabled and you can click it (or just press the enter key) to open the new wallet.

blah

The new wallet’s wallet window.

Congratulations, you have created a new empty wallet. It will not be usable until you have created an account, and various parts of the user interface will indicate this.

blah

The receiving tab is disabled.

Creating an account

If you are reading this, you likely have a new wallet that has no accounts, and you want to add one to it. We support addition of a wide variety of account types:

  • A new “Standard” account. This is the equivalent of creating a new ElectrumSV seed-word based wallet in 1.2.5 and earlier.

  • A multi-signature account. Use this if you are creating a new multi-signature account, or restoring an existing one from master public keys, seed words and so on.

  • Importing from text. Use this to import your seed words, whether Electrum seed words, BIP39 seed words from another wallet, private keys, public keys, master public keys, master private keys, and so on.

  • Importing a hardware wallet. If you have an existing hardware wallet that has a seed set up on it, then you can use this to add an account that links to it and uses it to sign. If you have a hardware wallet that does not have a seed set up on it, you should also be able to use this to set it up unless the device is a Ledger. Do not buy a Ledger.

This guide solely covers creating a “Standard” account.

Adding an account

In the top-left-hand corner of your wallet window, you will see the “Add Account” button. Click it and it will open the account wizard which allows all supported types of accounts to be created.

The "Add Account" button highlighted.

The “Add Account” button highlighted.

The account wizard offers four different types of account addition, at the time of writing.

The Account Types page in the Account Wizard.

The Account Types page in the Account Wizard.

Creating a new “Standard” Account

Double-click on the “Standard” entry to proceed. Or if you prefer to work for it, click the “Next” button or press the enter key. You will be asked for your password so that the generated seed words and private key data can be encrypted into your wallet. This also verifies you have the ability to really use this wallet, and should able to add an account.

The password dialog.

The password dialog.

You will immediately see that the account has been added to your wallet. You will note that at no point did you have to copy down your new seed words, or confirm them. You will be reminded to back them up by the wallet, and can do so at your leisure and own risk.

The new account's receiving tab.

The new account’s receiving tab.

Backing up your seed words

The wallet window now has a notification center, which is used to remind you to deal with important events, and point out how you can do it.

The wallet's notifications indicator.

The wallet’s notifications indicator.

The initial backup notification

Clicking the notification icon will make the new “Notifications” tab the active one and show the initial notification about backing up your data.

The initial backup notification in the wallet's notifications tab.

The initial backup notification in the wallet’s notifications tab.

Receiving a payment

There are a number of ways in which you can receive payments to a given account in your ElectrumSV wallet. At this time, they all involve having the other party pay to a new address obtained from your account’s receive tab.

The receiving tab in a standard account.

The receiving tab in a standard account.

Two ways that someone can make a payment are:

  1. You copy the displayed address and give it out.

  2. The other party takes a photo of the displayed QR code and their wallet software lets them pay to it.

Giving out an address

The oldest way to receive a payment is to give out an address from your wallet to the other party, and then wait for them to pay you. In the future, this will not be supported, but for now it is. The shown address is automatically replaced with another address, as the wallet detects that the shown address was used in an incoming payment. This kind of works, but not really, to assist the user in always giving out a new fresh previously unused address.

The new address offered in the receiving tab.

The new address offered in the receiving tab.

Important

The flaw in paying to addresses is that the other party has no way to know that the address they get, is the one that you tried to give them. Because they look like random letters and numbers it is possible that they can be replaced without either party knowing before it is too late. While reports of this happening are rare, it might be worth taking precautions to make sure this does not happen to you.

You can copy the address, paste it in an email and send it to the recipient. Paste it into a chat application. Or get it to them in any number of possible ways.

Using a QR code

If the other party is standing there with you, you can show them the receiving tab and they can take a photo of the QR code with their wallet. Their wallet will extract the address and streamline the payment process. You can fill out the fields with a requested amount to also include that in the QR code, which further streamlines the process.

The QR code provided in the receiving tab.

The QR code provided in the receiving tab.

Identifying incoming payments

In the legacy model, which is still the most common one, payments are fire and forget. The payer constructs a transaction and broadcasts it to the blockchain. Then when your wallet gets a notification a payment of interest has appeared in the blockchain, it retrieves that transaction and factors it into the related account.

The history tab when awaiting an incoming payment.

The history tab when awaiting an incoming payment.

With this model, the wallet has no idea a payment is incoming until it arrives out of the blue. A new and better model is available in the form of Paymail, but ElectrumSV does not have the service infrastructure to support it at this time. We are however working towards it.

Making a payment

If you are reading this, you probably want to know how to make a payment. We currently only support making payments in the following ways:

  • Payment to a Bitcoin address.

  • Payment to a BIP276 address.

  • Payment to a Bitcoin script.

This guide solely covers payment to an address. It is not recommended you pay to a Bitcoin script unless you are an expert.

Paying to yourself

At this point you should have a wallet with a standard account. You should also have an address from another party, that you can make a payment to. However for the purpose of this guide, you can make a payment to yourself, if you have no-one else to currently pay.

Start off on the receiving tab.

Highlighted areas on the receiving tab.

Highlighted areas on the receiving tab.

As you will be paying to yourself, copy the shown address. The best way to do this is to click on the copy button, which will copy it to the clipboard. You will use this address as you would the address for any other party.

Paying to an address

Ensure your wallet window is now showing the send tab. Select the “Pay to” field and paste in the address you wish to make a payment to.

Highlighted areas on the send tab.

Highlighted areas on the send tab.

After pasting in the address, enter a nominal amount of Bitcoin SV to send, where your wallet has sufficient funds to do so.

The filled out send tab.

The filled out send tab.

Important

If you are paying to addresses a good practice is to make what is called a pilot payment first, where you pay a small amount you can afford to lose, before paying the larger full amount.

Click the “Send” button to start the payment process.

The password confirmation dialog.

The password confirmation dialog.

Ensure that both the amount you are sending and the mining fee are the appropriate amounts, then enter your password and click “OK”. The “OK” button only becomes enabled when you have entered your password correctly. The transaction will broadcast, and you should receive a confirmation that the payment was made.

The payment sent dialog.

The payment sent dialog.

The confusing sequence of letters and numbers is actually the ID of the transaction that contained your payment. This can be used to look up your payment, if you were to take it and paste it into a web site that indexes the Bitcoin SV blockchain.

The record of payment

At it’s current state of development, the wallet does not have much context about payments made. But you can see the transactions this account is involved in, in the history tab.

The highlighted payment transaction in the history tab.

The highlighted payment transaction in the history tab.

If you had provided a description when making the payment, it would appear here in much the same way as the existing transactions with their “ElectrumSV coin splitting: Your split coins” descriptions.

Problem solving

Why doesn’t my hardware wallet work?

Hardware wallet makers do not provide anywhere near enough support for their devices, and some have a history of making breaking changes that stop them working in ElectrumSV. If your hardware wallet does not work then this is where you should look for some pointers, whether the device is a Trezor, a Ledger, a Keepkey or a Bitbox. Read more about hardware wallet issues.

How do I split my coins?

If you have coins you have not touched since before Bitcoin SV and Bitcoin Cash split from each other, you might want to make sure that you can send one of these without accidentally sending the other. Read more about coin splitting.

Hardware wallet issues

Ledger

While Ledger as a company do not support Bitcoin SV as a coin on their device, users have been able to use their Ledger devices with ElectrumSV through compatibility with the Bitcoin Cash support.

The Ledger device reports “unverified inputs”

You go to sign your transaction and your Ledger device has a confusing series of screens talking about “unverified inputs” and updating your device and/or software. You can simply step through these screens and select continue. These screens will be shown below, and then a detailed explanation of why you are seeing them will be provided.

The short version is that you can continue past these screens to signing your transaction as you signed it before you started seeing these messages, and it will be as secure as it was then. Just make sure you only sign it once, and if ElectrumSV asks you to resign it over and over not recognising that you did it once, you are probably using malware. Again, see below the screens for an explanation of this in more detail.

Unverified inputs

It should not be necessary to update your Ledger firmware and applications to deal with this.

Update Ledger Live

It should not be necessary to update ElectrumSV, although you should always be using the latest version.

Or third party software

You can cancel the signing of the transaction if you want.

The cancel option

But if you select the “continue” option, the Ledger device will go through the normal transaction signing process.

The continue option

As you might recall, the first step of the correct signing process is to confirm where you are sending funds. And this is where the process is now at. You can go ahead and sign the transaction as you would have in the past before this confusing message.

Now you are past that, the real signing process begins with address confirmation.
Why do I see this “unverified inputs” message?

A theoretical but unlikely exploit was discovered where wallet malware could direct a user to sign a transaction several times, and extract the signed spends from each and combine them into a new transaction which gave a large fee to miners. Trezor wrote an article about it which you can read if you wish. You see this warning because ElectrumSV is not providing the previous transactions in which the spent coins were originally received to the Ledger device.

The simple reason we do not provide the previous transaction data is because Ledger cannot handle it and will break. You can see in the Trezor hardware issues a “DataError: bytes overflow” error, which their users may encounter. We have to provide these transactions to the Trezor devices but they cannot handle them and they break, this means that Trezor users have to be careful not to spend anything other than the simplest of received payments in their transactions themselves and work out what they can and can’t spend themseves. If any of their coins is not simple and cannot be handled by Trezor, they need to bypass their hardware wallet and spend them in an unsafe way by entering their seed words.

Back to Ledger devices. Ledger allow the transaction to be signed without the spent transaction data, and on detecting they do not have it, they show an “unverified inputs” message. This makes it a little lot for Ledger users. They can still sign a spend they are confident is going to the correct places, and not bypass their hardware wallet to do so. Let’s be honest, if someone is going to all the effort of writing malware it has never in the history of malware been to give the stolen coins to miners. The chances of downloading malware are slight, and the chances of downloading malware that gives coins to anyone other than the thief are even slighter.

Trezor

While Trezor as a company do not support Bitcoin SV as a coin on their device, generally Bitcoin SV users have been able to use their Trezor devices with ElectrumSV by having it in the Bitcoin Cash coin mode. However, users are encountering situations where the limitations of the Trezor device result in it no longer being sufficient to work with Bitcoin SV transactions. This likely means that if a user is planning to continue to use a Trezor device, it may require them to jump through hoops to do so.

There are two complications:

  • Later versions of firmware (starting with 1.9.1 for One and 2.3.1 for Model T) require ElectrumSV to pass in parent transactions with the transaction you are signing. ElectrumSV only started supporting this in ElectrumSV 1.3.8 or newer. What this means is that if you are using these later versions of firmware, you must be using ElectrumSV 1.3.8 or newer - or it will error.

  • Bitcoin SV transactions can have large output scripts, larger than what Trezor can handle. Trezor can only sign simple payments and nothing else, but this does not prevent payments from being made into the wallet with additional output scripts added for other reasons that exceed Trezor’s size limit of 15 kilobytes. The parent transaction processing in the Trezor device will error when it encounters these.

Trezor devices are becoming problematic for Bitcoin SV users to use. While they are polished and enjoyable devices to use, unless the large output problem is solved by Trezor, we cannot recommend users buy these devices unless they accept they have to own and deal with these problems. For this reason it is recommended that Trezor users downgrade their devices.

Downgrading your Trezor device

These are Trezor’s firmware version pages, for users who plan to downgrade:

You will need to visit those pages and download the firmware file. Trezor provide instructions on how to downgrade, and let you know how and where to use the file.

Problem: You see a random looking series of numbers and letters
What this problem looks like..

What this problem looks like..

You are using ElectrumSV 1.3.7 or earlier, and your Trezor device has a later version of the firmware. It expects ElectrumSV to have provided the transaction associated with those numbers and letters, but the ElectrumSV version you are using does not know how to or even that it should. You can take the risk of updating to a more recent version of ElectrumSV that supports these parent transactions, and possibly encounter the “DataError: bytes overflow” problem. Or you can downgrade your Trezor firmware to the version listed above.

Problem: You see the message “DataError: bytes overflow”
What this problem looks like..

What this problem looks like..

One of your parent transactions contains not only the coin you are trying to spend, but a large output script. Your Trezor device has a later version of firmware where parent transactions are required to be provided, and the device is choking on the large output. This is a limit in the device itself, and ElectrumSV can do nothing about this. To spend the coin associated with the problem parent transaction, you need to downgrade your firmware to the versions listed above.

Coin splitting

Important

ElectrumSV can only be downloaded from electrumsv.io.

When users have coins that existed before Bitcoin Cash became a separate blockchain from Bitcoin SV, those coins are linked on both blockchains. When they are sent in a wallet on one blockchain, that action can also send them on the other blockchain. Users have had this accidentally happen to them, and the recipient has refused to refund the coins from the blockchain the user did not intend to send on.

If you think you have unsplit coins in your wallet, you can use ElectrumSV’s coin-splitting feature to split them. But keep in mind that you are responsible for your own coins, you should verify for yourself that the splitting worked. And if you are unsure whether your coins need to be split, you can always split them anyway.

How does splitting work?

The process is simple, if the coins are sent on Bitcoin SV in a way that is incompatible with Bitcoin Cash, then the coins are split. Any usage of those specific coins that have been split will from then on be independent on either blockchain.

In order to keep it simple, we only do the simplest case. We make your wallet do a payment to itself that combines all the available coins within it in a way that should be valid on Bitcoin SV and not Bitcoin Cash. This results in one single split coin combining all the individual coins that you had in your wallet before the split.

How you split your coins

Unfortunately, all the coins in the wallet used here are already split. So the following is just going through the process to show you how it works. You can see that this wallet contains a small amount of Bitcoin SV.

Let’s start by changing to the coin-splitting tab:

Selecting the coin-splitting tab.

Selecting the coin-splitting tab.

Once you are looking at the coin-splitting tab, you have two options. Either direct splitting or faucet splitting. We recommend the direct splitting, and do not really support the faucet splitting any more. Direct splitting does not work for hardware wallets, which due to inherent limitations can only work in simple ways.

The coin-splitting tab.

The coin-splitting tab.

Clicking on the direct splitting button will ask you for your password. You will see that the balance of the splitting transaction is the balance of the available coins in the wallet.

Approve the splitting payment.

Approve the splitting payment.

After you enter your password, it will sign and broadcast your transaction. This will happen pretty quickly, and once it is done you will see a dialog letting you know the splitting transaction was broadcast.

The split action completion message.

The split action completion message.

You can now go back to the history tab and see the splitting transaction there, which has an automatic description noting what it was created for.

The history tab with the splitting transaction.

The history tab with the splitting transaction.

In theory, your coins should be split. But again, you are responsible for using them safely and you should ensure that they are really split.

Ensuring your coins are split

Bitcoin is complicated, and in order to really know for yourself that your coins are split, you need to have some level of technical understanding. It’s a lot simpler to just send them to different places on both blockchains, especially safe places like your own wallet’s receiving addresses and check that they get there - so just do that!

Here is one way to do it:

  1. Do a direct split in ElectrumSV.

  2. Open your Bitcoin Cash wallet with the coins that were linked to Bitcoin SV, that you just split in ElectrumSV.

  3. Create a new empty Bitcoin Cash wallet.

  4. Send the coins in your existing Bitcoin Cash wallet to the new Bitcoin Cash wallet.

You can then observe that your Bitcoin Cash is in a new fresh wallet, and your Bitcoin SV is in the old wallet. Neither moved because the other moved, but rather both were moved by you. You might wonder why you need to create a second Bitcoin Cash wallet, and the reason is that this ensures that your Bitcoin SV and Bitcoin Cash are using different keys and it both helps verify they are unlinked and gives you better security going forward.

Hardware wallets

Hardware wallets are extremely limited devices with not much flexibility. They only allow certain types of transactions to be signed, and this does not include the type that the direct splitting method uses.

If you have a hardware wallet, you can try and use faucet splitting. Faucet splitting works by adding a very small Bitcoin SV coin to your wallet, then combining all the available coins in your wallet with that Bitcoin SV coin. This creates a new Bitcoin SV coin which is of course incompatible with the Bitcoin Cash blockchain, and so the coins in the wallet have been split.

Alternatively, if the faucet is not working you can get someone to send you a very small amount of Bitcoin SV and you can accomplish the same thing yourself by sending all the coins in your wallet to one of your own addresses (including that very small amount of Bitcoin SV).

Increasing differences between blockchains

There are an increasing number of changes between Bitcoin Cash and Bitcoin SV. While it is good practice to split your coins just in case you lose your Bitcoin SV when sending your Bitcoin Cash, or lose your Bitcoin Cash when sending your Bitcoin SV, it is possibly becoming easier to avoid it.

High minimum fee on Bitcoin Cash

The Bitcoin Cash servers for the Electron Cash wallet rejected any attempt to broadcast a transaction containing unsplit coins that had 0.5 satoshis per byte fee as too low. Experiments suggest that it is very difficult to get a transaction at this fee level to propagate, maybe nearing impossible.

As the default fee in ElectrumSV is 0.5 satoshis per byte, this could mean that if you send unsplit coins in ElectrumSV the Bitcoin Cash network will completely ignore them. Should you rely on this? No, but it might provide a coincidental safety net for people who do not know they should split their coins.

Schnorr signatures

By default Electron Cash and likely all Bitcoin Cash wallets now use Schnorr signatures. What this means is that the transactions they make should be incompatible with Bitcoin SV as long as the user has not opted out of using Schnorr. So in theory you can just send your coins on Bitcoin Cash and because those Schnorr signatures are used, the coins on Bitcoin Cash have been sent in a way that is incompatible with Bitcoin SV.

The default Electron Cash Schnorr setting.

The default Electron Cash Schnorr setting.

Should you rely on this? Not unless you know for sure that you are using Schnorr signatures in your Bitcoin Cash wallet, and that you have used the correctly.

Thanks

Many thanks to satoshi.io who provided unsplit coins used for testing related to this article.

Building on ElectrumSV

How can I access my wallet using the REST API?

For most users, accessing their wallet with the user interface will be fine. But if you have a minimal amount of development skill the availability of the REST API gives you a lot more flexibility. The REST API allows a variety of actions among them loading multiple wallets, accessing different accounts, obtaining payment destinations or scripts from any of the accounts. Perhaps you want to add your own interface for your wallet or maybe automate how you use it. Read more about the REST API.

How would I extend ElectrumSV as a customised wallet server?

The REST API is limited in what it can do by nature. Getting the ElectrumSV development team to add what you want to it, is not guaranteed to happen, may not even be possible and if it was who knows how long it would take. An alternative is to build your own “daemon application” which is a way of extending ElectrumSV from the inside. Read more about customised wallet servers.

Do I have to develop against the existing public blockchains?

ElectrumSV provides a way for developers to do offline or local development. customised wallet servers.

The REST API

Technically, the restapi is an example ‘dapp’ (daemon application). But is nevertheless provided in a format that aims to eventually cover the majority of basic use cases.

This RESTAPI may be subject to slight changes but the example dapp source code is there for users to modify to suit your own specific needs.

Endpoints

get_all_wallets

Get a list of all available wallets

Method

GET

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets

Sample Response

{
    "wallets": [
        "worker1.sqlite"
    ]
}
get_parent_wallet

Get a high-level information about the parent wallet and accounts (within the parent wallet).

Method

GET

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite

Sample Response

{
    "parent_wallet": "worker1.sqlite",
    "accounts": {
        "1": {
            "wallet_type": "Standard account",
            "default_script_type": "P2PKH",
            "is_wallet_ready": true
        }
    }
}
load_wallet

Load the wallet on the daemon (i.e. subscribe to ElectrumX for active keys) and initiate synchronization. Returns a high-level information about the parent wallet and accounts.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite

Sample Response

{
    "parent_wallet": "worker1.sqlite",
    "accounts": {
        "1": {
            "wallet_type": "Standard account",
            "default_script_type": "P2PKH",
            "is_wallet_ready": true
        }
    }
}
get_account

Get high-level information about a given account

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1

Sample Response

{
    "1": {
        "wallet_type": "Standard account",
        "default_script_type": "P2PKH",
        "is_wallet_ready": true
    }
}
get_coin_state

Get the count of cleared, settled and matured coins.

Method

GET

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/utxos/coin_state

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/utxos/coin_state

Sample Response

{
    "cleared_coins": 11,
    "settled_coins": 700,
    "unmatured_coins": 0
}
get_utxos

Get a list of all utxos.

Method

GET

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/utxos

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/utxos

Sample Response

{
    "utxos": [
        {
            "value": 20000,
            "script_pubkey": "76a91485324d225c81d414fe8a92bf101dba1a59211e8488ac",
            "script_type": 2,
            "tx_hash": "ce7c2fbc25d25d945b4ad539d2b41ead29e1b786a8aa42b2677af28da3f231a0",
            "out_index": 49,
            "keyinstance_id": 13,
            "address": "msfERZdhGaabQmeQ1ks8sHYdCDtxnTfL2z",
            "is_coinbase": false,
            "flags": 0
        },
        {
            "value": 20000,
            "script_pubkey": "76a91488471d45666dadece7f06aca22f1a1cf9a3a534988ac",
            "script_type": 2,
            "tx_hash": "ce7c2fbc25d25d945b4ad539d2b41ead29e1b786a8aa42b2677af28da3f231a0",
            "out_index": 50,
            "keyinstance_id": 12,
            "address": "mswXPFgWJbgvyxkWBFfYjbbaD1DZmFS3ig",
            "is_coinbase": false,
            "flags": 0
        },
    ]
}
get_balance

Get account balance (confirmed, unconfirmed, unmatured) in satoshis.

Method

GET

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/balance

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/utxos/balance

Sample Response

{
    "confirmed_balance": 14999694400,
    "unconfirmed_balance": 98000,
    "unmatured_balance": 0
}
remove

Removes transactions (currently restricted to ‘StateSigned’ transactions.)

Deleting transactions in the ‘Dispatched’, ‘Cleared’, ‘Settled’ states could cause issues with the utxo set and so is not supported at this time (a DisabledFeatureError will be returned). If you require this feature, please make contact via the Atlantis Slack or the MetanetICU slack.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs

Sample Body Payload

{
    "txids": [
        "96eee07f8e2c96e33d457138496958d912042ff4ed7b3b9c74a2b810fa5c3750",
        "469ddc27b8ef3b386bf7451aebce64edfe22d836ad51076c7a82d78f8b4f4cf9",
        "e81472f9bbf2dc2c7dcc64c1f84b91b6214599d9c79e63be96dcda74dcb8103d"
    ]
}

Sample Response

{
    "items": [
        {
            "id": "96eee07f8e2c96e33d457138496958d912042ff4ed7b3b9c74a2b810fa5c3750",
            "result": 200
        },
        {
            "id": "469ddc27b8ef3b386bf7451aebce64edfe22d836ad51076c7a82d78f8b4f4cf9",
            "result": 400,
            "description": "DisabledFeatureError: You used this endpoint in a way that is not supported for safety reasons. See documentation for details (https://electrumsv.readthedocs.io/ )"
        },
        {
            "id": "e81472f9bbf2dc2c7dcc64c1f84b91b6214599d9c79e63be96dcda74dcb8103d",
            "result": 400,
            "description": "Transaction not found"
        }
    ]
}
get_transaction_history

Get transaction history. tx_flags can be specified in the request body. This is an enum representing a bitmask for filtering transactions.

The main `TxFlags` are:

StateCleared

1 << 20 (received over p2p network and is unconfirmed and in the mempool)

StateSettled

1 << 21 (received over the p2p network and is confirmed in a block)

StateReceived

1 << 22 (received from another party and is unknown to the p2p network)

StateSigned

1 << 23 (not sent or given to anyone else, but are with-holding and consider the inputs it uses allocated)

StateDispatched

1 << 24 (a transaction you have given to someone else, and are considering the inputs it uses allocated)

However, there are other flags that can be set. See electrumsv/constants.py:TxFlags for details.

In the example below, (1 << 23 | 1 << 21) yields 9437184 (to filter for only StateSigned and StateCleared transactions)

An empty request body will return all transaction history for this account. Pagination is not yet implemented.

Request

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/history

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/history

Sample Body Payload

{
    "tx_flags": 9437184
}

Sample Response

{
    "history": [
        {
            "txid": "64a9564588f9ebcce4ac52f4e0c8fe758b16dfd6fdb5bd8db5920da317aa15c8",
            "height": 0,
            "tx_flags": 1052720,
            "value": -10200
        },
        {
            "txid": "a6ec24243a79de1b51646d1a46ece854a8f682ff23b4d4afabaebc2bc10ef110",
            "height": 0,
            "tx_flags": 1052720,
            "value": -10200
        }
    ]
}
fetch_transaction

Get the raw transaction for a given hex txid (as a hex string) - must be a transaction in the wallet’s history.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/fetch

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/fetch

Sample Request Payload

{
    "txid": "d45145f0c2ff87f6cfe5524d46d5ba14932363e927bd5a4af899a9b8fc0ab76f"
}

Sample Response

{
    "tx_hex": "0100000001e59dd2992ed46911bea87af1b4f7ab1edce8e038520f142d2aa219492664d993160000006b483045022100ec97e4887b5dd9bb3c1e0ebd0d5b2b3520aeda4d957de4bf0e06a920c7dd3fe802200be4c58192a7c67930518bf29b30ab49883fcc342ca4ee5815288c6f17d7b486412103ab06ed1f70de1524e34a4e36575993a70ff2c8800958045137d0cc2caf67ec91ffffffff0248260000000000001976a9143ef1b7677ea1ed53400da9719380b4d0373a1b5f88ac10270000000000001976a91403d0de941da4f897a7cd3828b4905fa64190a72f88acce000000"
}
create_tx

Create a locally signed transaction ready for broadcast. A side effect of this is that the utxos associated with the transaction are allocated for use and so cannot be used in any other transaction.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/create

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/create

Sample Request Payload This example is of a single “OP_FALSE OP_RETURN” output with “Hello World” encoded in Hex. The preceeding 0x0b byte represents a pushdata op code to push the next 11 bytes onto the stack (“68656c6c6f20776f726c64”).

Additional outputs for leftover change will be created automatically.

{
    "outputs": [
        {"script_pubkey":"006a0b68656c6c6f20776f726c64", "value": 0}
    ],
    "password": "test"
}

Sample Response

{
    "txid": "96eee07f8e2c96e33d457138496958d912042ff4ed7b3b9c74a2b810fa5c3750",
    "rawtx": "0100000001cfdec4ce0f10c4148b44163bf6205f53e5ab31f04a57fcaaeb33ef6487e08511000000006b483045022100873bb0dabc0b053be5602ebd1bb1ce143999221317eda8835fdf96a3197b168e022037ac7ad4c5f27beee3805e581b483b418a5298a3c467872d548accdc056321cb412103bf03fd106e69b55fc2041cc862a2c1932367899de4a734ef37b8a8f056792869ffffffff0200000000000000000e006a0b68656c6c6f20776f726c64dd250000000000001976a914c6d2e09ff211db5671ea1a9a08df13703b5a06f988acd5000000"
}
broadcast

Broadcast a rawtx (created with the previous endpoint).

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/broadcast

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/broadcast

Sample Request Payload This example is of a single “OP_FALSE OP_RETURN” output with “Hello World” encoded in Hex. The preceeding 0x0b byte represents a pushdata op code to push the next 11 bytes onto the stack (“68656c6c6f20776f726c64”).

Additional outputs for leftover change will be created automatically.

{
    "rawtx": "0100000001ab9aff89a92c011b5436a0c02eb53cf6328286e5cf5767f309cde5414f657661000000006a473044022050750ec47afa183d3c99e22bc4324c3af83115fb409f966e345f72e0bcfa780302201e5d5920e0164c26f2fee2a71b079a4c4918ec9b269df624f3fb2fd483d6dedc4121038cac099086f38c1298d745f3b67e14bc4ab29a21fab5514111c65e196d430b29ffffffff0200000000000000000e006a0b68656c6c6f20776f726c64dd250000000000001976a914ee8f1e9312200924a406e4c39a2d0685df60924988acce000000"
}

Sample Response

{
    "txid": "7ff0fcf6de91ffa71ef145e31d0bffe31467ecaa125a8db307cf9066fea55db5"
}
create_and_broadcast

Atomically creates and broadcasts a transaction. If any errors occur, the intermediate step of creating a signed transaction will be reversed (i.e. the transaction will be deleted and the utxos freed for use).

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/create_and_broadcast

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/create_and_broadcast

Sample Request Payload This example is of a single “OP_FALSE OP_RETURN” output with “Hello World” encoded in Hex. The preceeding 0x0b byte represents a pushdata op code to push the next 11 bytes onto the stack (“68656c6c6f20776f726c64”).

Additional outputs for leftover change will be created automatically.

{
    "outputs": [
        {"script_pubkey":"006a0b68656c6c6f20776f726c64", "value": 0}
    ],
    "password": "test"
}

Sample Response

{
    "txid": "469ddc27b8ef3b386bf7451aebce64edfe22d836ad51076c7a82d78f8b4f4cf9"
}
split_utxos

Creates and broadcasts a coin-splitting transaction i.e. it breaks up existing utxos into a specified number of new utxos with the desired “split_value” (satoshis). “split_count” represents the maximum number of splitting outputs for the transaction. “desired_utxo_count” determines when the desired utxo count has been reached (i.e. if you have 200 utxos but “desired_utxo_count” is 220 then the next coin splitting transaction will create 20 more utxos.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/txs/split_utxos

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/txs/split_utxos

Sample Request Payload

{
    "split_value": 10000,
    "split_count": 100,
    "password": "test",
    "desired_utxo_count": 1000
}

Sample Response

{
    "txid": "42329848db94cb16379b0c8898eb2b98542fb25d9257a47663c3fac7b0f49938"
}

Regtest only endpoints

If you try to access these endpoints when not in RegTest mode you will get back a 404 error because the endpoint will not be available.

topup_account

Tops up the RegTest wallet from the RegTest node wallet (new blocks may be generated to facilitate this process).

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/topup_account

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/topup_account

Sample Request Payload

{
    "amount": 10
}

Sample Response

{
    "txid": "8f3dfe9b9e84c1d0b6d6ead8700be4114bb2d3ca1f97e1e84c64ea944415c723"
}
generate_blocks

Tops up the RegTest wallet from the RegTest node wallet (new blocks may be generated to facilitate this process).

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/generate_blocks

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/1/generate_blocks

Sample Request Payload

{
    "nblocks": 3
}

Sample Response

{
    "txid": [
        "72d1270d0b3ad4c71d8257db8d6f880186108152534658ae6a127b616795530d"
    ]
}
create_new_wallet

This will create a new wallet - in this example “worker1.sqlite”. This example was produced via the electrumsv-sdk which allows a convienient method for running a RegTest node, electrumX instance (pre-configured to connect) and an ElectrumSV instance with data-dir=G:\electrumsv_official\electrumsv1.

Method

POST

Content-Type

application/json

Endpoint

http://127.0.0.1:9999/v1/{network}/dapp/wallets/{wallet_name}/{account_id}/create_new_wallet

Regtest example

http://127.0.0.1:9999/v1/regtest/dapp/wallets/worker1.sqlite/create_new_wallet

Sample Request Payload

{
    "password": "test"
}

Sample Response

{
    "new_wallet": "G:\\electrumsv_official\\electrumsv1\\regtest\\wallets\\worker1.sqlite"
}

Wallet as a service

As the Bitcoin SV ecosystem matures services will become available that allow businesses to outsource the wallet management and the services necessary for their products. There is a sizeable advantage to this, as it allows the business to focus on the products and avoid complicated and rather standard work that there is a benefit to outsourcing.

For the businesses that want or even need to be in control of their own wallet and infrastructure, they can treat ElectrumSV as a common open source base, and extend it with their own proprietary functionality. An starting point for this approach can be found in the example application on Github.

This documentation will be fleshed out as time allows.

Local or offline development

An command-line based environment is provided for local Bitcoin SV development. There is no requirement that any developer using it needs to be online while they use it, which is fully compatible with the very flexible ability to do offline development.

More details will be provided as polishing is completed.

The ElectrumSV project

Perhaps you are a developer who already helps out on the ElectrumSV project, or you who would like to get involved in some way, or you are just curious about the processes and information related to project management and development. If so, this is the information you want.

How can you contribute?

There are many ways that you can help the ElectrumSV project improve. If you want something to work in a different way, you can work on making it different and offer us the changes. If you feel the documentation could be better, you can improve it and offer us the changes. If you want ElectrumSV or anything related to it in your native language, you can offer to do the work to translate it. And that’s just a few of the possibilities. Read more about contributing.

Where is the continuous integration and how is it used?

We use Microsoft’s Azure DevOps services for continuous integration. Microsoft provide generous levels of free usage to open source projects hosted on Github. This is used to do a range of activities for every change we make to the source code, from running the unit tests against each change on each supported operating system, to creating a packaged release for each system that can be manually tested. Read more about our use of continuous integration.

What is the process of releasing a new version?

Because we generate packaged releases for every change we make, with a bit of extra work we can generate properly prepared public releases. This involves changing the source code so that the release has the content changes required for new version, and also publishing the release and updating the web site to have the content changes required to offer it for download. Read more about the release process.

How you can contribute

What are some of the ways you might contribute to ElectrumSV?

  • Contributing translations.

  • Contributing new features.

  • Contributing bug fixes.

  • Reporting problems.

Translations

Anyone wishing to contribute translations of the text in the ElectrumSV user interface, can do so by the ElectrumSV project on Crowdin. Once you’ve done entering translations let us know, and we’ll do the process of exporting the latest data from Crowdin so that your transaction work gets used.

New features

Be aware that you should check with us before starting work on a feature you are hoping we will accept into ElectrumSV. If we accept a new feature, we then have to maintain it and accept the extra work involved on top of that required for support requests, current features and bug fixes. And it may be that depending on the feature we cannot remove it later, if users become reliant on it or have data that requires it to be present.

Bug fixes

We welcome bug fixes for existing problems, whether they are problems you encounter yourself or ones that you see others have reported that have not already been fixed. You can find our existing bugs in our issue tracker on Github.

Reporting problems

Even if you do not have the experience, skill or inclination to attempt to fix problems you encounter, it would be appreciated if you could report them to us. And if you can take the time to describe what you were doing when you encountered the problem, it helps us fix the problems much more easily. You can report bugs using our template in our issue tracker on Github.

Continuous integration

As Microsoft provide generous levels of free usage to open source projects hosted on Github through their Azure DevOps service, ElectrumSV makes use of it for a range of purposes. Every time changes are pushed to Github, the following tasks are run:

  • Unit tests on Windows, MacOS and Linux.

  • Linting.

  • Type checking.

  • Code coverage analysis.

  • Producing releases.

While Azure DevOps will do these things against each individual commit, we have configured the project to only do it against the latest commit.

Releases

There are two goals in having CI produce build files:

  • We can use it to produce the build files we release publically.

  • Members of the public can access and download build files for any build.

Using CI to produce official release files

By having CI produce the build files, this allows a developer to offload the processing work from their own computer and carry on working on other tasks. In addition there is some security in having the build files made within CI, where the CI obtains the source code directly from the latest commit on Github. And on generating the build files, also produces SHA256 hashes that can be used to validate the content at any later time.

Benefits of public build access

If a user is experiencing a bug, a developer can fix it and push the fix to Github. This will result in an automatic build on Azure DevOps, and if it succeeds will produce build files. The developer can point the user to the build, and although the user may not have an account with Azure DevOps they still have enough access that they can download build artifacts like the build files.

Release process

There are a lot of steps to releasing a new version of ElectrumSV. This document is intended to lay out the entire proces and some of the reasoning behind it, so that any developer can jump in and do a release if necessary. In addition, formalising the release process ensures that nothing is accidentally left out due to any informal and casually documented process leading to an oversight of various steps.

Initial preparation

When it is time to release a new version, the first step is to freeze the release branch in Github and prevent introduction of any changes that introduce new functionality or change existing functionality. This is an exercise in self restraint, rather than anything that is done to programmatically disallow these changes to be made.

Writing an article

An initial outline of a release article is written, including the featured changes that will be highlighted. Mostly this involves taking the last article, removing all the changes that were included in the previous version, and putting the new version’s changes in their place using the same format. The key goal of these articles is to illustrate these changes and help users visualise them even if they skim through the article, and it should include screenshots at every possible opportunity.

For each change featured in a release article:

  • A link should be provided to any issue that exists in relation to that change.

  • A link should be provided to every code change made to the source code in the making of the given change.

Updating the version

The version number is increased to the new version number, and the approximate release date is updated to be approximately what it will be when the release is made. If the release process is protracted over many days due to the testing, and any subsequent changes they require, then the date may be modified later.

If the last version was 1.3.6:

  • Find all 1.3.6 references and replace them with the new version 1.3.7.

  • Find all 1-3-6 references. These will be in links to the release article for the previous version. The link should be replaced with the link to the new article.

Writing release notes

There are two places that changes are documented in the source code. The first is a HTML-based summary that is accessible from the splash screen that ElectrumSV shows when it starts up. The second is the text-based formal RELEASE-NOTES file in the top level of the source code.

The HTML-based summary is intended to be a list of user focused descriptions of the main changes in the release. It lists the same changes as those chosen for the release article.

The RELEASE-NOTES file is intended to be developer oriented, and should attempt to list all the changes made and included in the release.

Pre-build testing

There are two different kinds of pre-build testing, both manual and automatic. The manual tests are primarily those which involve a user checking the user interface works as it should. The automatic tests ensure the code is correct as it is possible for such a tool to detect, and that when asked to perform processes the outcomes of those processes are as they should be.

User interface testing

There is a checklist of common use cases for ElectrumSV that the user interface is manually stepped through. New accounts are created, keys and seeds are imported, invoices are paid, hardware wallets are plugged in and out and most if not all of the menu options are used in order to ensure they still work.

Note

TODO: Reference manual user interface testing documents.

As bugs, problems or small aspects that can be improved are identified, they are fixed and the relevant user interfaces are retested. Along these lines, if intuitively something does not quite seem like it is working, time is spent to work out why.

Code analysis

As a part of normal development, before code changes are committed to the Github source code repository, developers are expected to run code quality tools. If they push the changes to Github and they have made changes that do not meet code quality standards, then the CI process will do those same checks and error. The changes made to both prepare the release and fix any problems observed in the user interface should be tested by the developer.

mypy

Python is a programming language with optional typing. For users who choose to use typing, this tool can then try and work out if the code that uses those types is buggy or incorrect.

Running mypy on Windows, Linux or MacOS:

mypy --config-file mypy.ini --python-version 3.7
pylint

This tool checks for general code correctness and common errors, and warns the developer if it finds any.

Running pylint on Windows, Linux or MacOS:

pylint --rcfile=.pylintrc electrum-sv electrumsv
Unit testing

The existing collection of unit tests ensure that a range of processes work correctly. This includes how the code handles different kinds of accounts, migration of wallets from older versions to newer versions, old Electrum seed words, new Electrum seed words, BIP39 seed words, different key types and so on. Running these against lower level changes can often help detect regressions or oversights made in implementing those changes.

Running the unit tests on Windows:

pytest electrumsv\tests

Running the unit tests on Linux or MacOS:

pytest electrumsv/tests

Building the release

The continuous integration (CI) service is hooked up to Github. Every time a set of changes are pushed to Github it automatically triggers the CI to test and build those changes. Every build results in what are called a set of artifacts, which are the executables and archives produced as a result of that build. If the developer adds a Git tag structured in a way to designate a release version to the changes they push, then this modifies the build process and produces an official versioned set of build artifacts.

Tagging the latest code as a potential stable release of a 1.3.7 version:

git tag sv-1.3.7

The developer than pushes both the latest code and the tag to Github, both separately, and in that order:

git push
git push --tags

A build is only triggered if unpushed code changes are pushed. And the build only looks for the release tag at the start. So the developer needs to push unpushed code changes, and then the new release tag in quick succession.

Build errors

The build runs all the tests that the developer should run before they push the final changes. If they fail, or their development tools are out of date, this might mean that either the developer did not run the tests correctly or that the developer needs to update their tools.

Recapping the automated tests employed:

  • The unit tests.

  • The functional tests.

  • Pylint for style and correctness checking.

  • Mypy for type checking.

If there are build errors or the build needs to be rerun, the developer needs to delete the tag and recreate it, and push a new tag with additional code changes to trigger a new build.

Deleting the local tag for a 1.3.7 release:

git tag --delete sv-1.3.7

Deleting the remote tag for a 1.3.7 release:

git push origin --delete sv-1.3.7
Testing the build

Once a successful candidate build has been made, the build artifacts are downloaded. One artifact is deleted, the Windows installer which is named with the -setup.exe suffix. At this time we do not support this or test it, and in the longer term we will provide this in the form of a Windows Store application.

The build testing is not extensive. If a build executable runs and the wallet user interface appears, then all testing of both functionality and user interface within the pre-build testing will represent how the build behaves.

Linux

There are no Linux builds at this time, so there is no need for testing at this stage.

Note

If a member of the community creates an AppImage build process that is of sufficient quality, we would be willing to help them maintain it and use it in producing official Linux builds.

MacOS

The build is downloaded to a MacOS device, and run.

The following trivial steps are tested:

  1. Funds are sent to the wallet on the MacOS device.

  2. The funds are then sent back out to an external wallet.

Windows

There are two builds on Windows, a portable build and a non-portable build. A quick recap on the difference is that the portable build stores it’s data in a directory local to the portable build executable. The non-portable build stores it’s data in the user’s application data directory.

The following trivial steps are tested for the non-portable build:

  1. Funds are sent to the wallet on the MacOS device.

  2. The funds are then sent back out to an external wallet.

The non-portable build is merely started, and if the user interface appears and the wallet selection screen can be reached, it is deemed sufficient.

Deployment

There are a range of steps to doing the deployment.

Build files

The build files are currently hosted for download on Amazon S3 storage rather than on the web site. This was initially done in order to try and reduce the false positive flagging for Malware that ElectrumSV gets on Windows, because of it’s use of Pyinstaller. The process of uploading these is intended to be paranoid to ensure that the files uploaded are the actually the ones the CI process produced.

After the build artifacts are uploaded to Amazon S3 storage, they are re-downloaded and the SHA256 hash of each is compared to those that CI produced by redownloading the build hashes from CI.

Web site

Besides reflecting the latest release, another function of the web site is that it hosts a JSON file with signatures from at least one developer for the given release version and date. This is used by the update checker to alert users that there is a new release. The web site also hosts the GPG signatures from at least one developer, which need to be added before it is generated.

Update signatures

The keys used to verify that a release has been signed by a known developer are hard-coded into each build. This makes it difficult to add new signing developers, as users with older builds will lack the keys for those new developers, those builds will appear illegitimate. It is probably a good idea for the process to change sooner rather than later to prepare for working around this.

One or more of the developers can sign to announce the release of the build, and each should do the following:

  1. Take the release version which might be 1.3.7.

  2. Take the release date which might be 2020-10-08T20:00:00.000000+13:00.

  3. Combine them which in this case will result in 1.3.72020-10-08T20:00:00.000000+13:00.

  4. Go into the signing wallet and select the signing key.

  5. Select the Sign/verify message menu.

  6. Enter the combined text.

  7. Click the Sign button and enter the wallet password.

  8. Copy the signature and place in the release.json file.

The existing release.json file is included in the web site generation content, and should be updated and it will automatically be included in the generated web site.

GPG signatures

In addition to hashes proving the integrity of downloaded build files, there are also GPG signatures that indicate who they came from. The public keys of the developers who might sign the build files are in Github much like the SHA256 hashes for each build file.

A sub-directory should be made within the download web site content directory for the release version, and the GPG signatures for each new build file placed in there.

Generation

With GPG signatures and release version signatures in place, and also updated for the new version and build files, the final web site can be generated and put in place on the ElectrumSV web host. The generation instructions documented in the web site directory. Assuming that the developer has already been generating the web site in the past, the following commands are all they need to do one final generation.

cd docs
cd website
pelican -s pelicanconf.py

Standard deployment steps need to be followed and the new uploaded html directory needs to match the existing one in the following ways:

  1. The same owner using chown -R.

  2. The same permissions using chmod -R.

Documentation

The documentation is hosted on the Read the Docs service. As changes are pushed to the Github repository, Read the Docs is notified and they fetch the changes and trigger an update of the documentation. This mostly benefits users being able to view development documentation. The deployed documentation for a given release cannot change any time post-release development changes are made.

After the tag for the release changes is pushed to Github, a developer needs to add it to the list of tags that Read the Docs is hosting documentation for. And then they need to make it the default tag so that the documentation URL electrumsv.readthedocs.io goes there by default.

Github

At this point the documentation, the web site, and almost all other changes should be present in Github. The one thing that may be missing is the SHA256 hashes for the build files, which need to be added to the file build-hashes.txt in the source code, and pushed as well. Beyond that they need to be merged into the master branch, which is the place we recommend users go to find them.

Github releases

Github has it’s own system for projects to make releases, and we do use that, but we do not use it to release build files. It’s primary used to formally designate the release tag as a new release, and associate it with a list of the changes in the release. The changes listed there are taken directly from the build-hashes.txt file.

Release article publication

This should just be a matter of applying any final polish to the already prepared release article and pressing whatever resembles the Publish button.

Announcements

The link to the release article should be posted to the following places with some additional decorative text.

  • Twitter.

  • The Metanet.ICU slack.

  • The Atlantistic Unwriter slack.

  • Anywhere else.

Note

TODO: Guidelines to how we write the standard decorative text should be added here.

The release checklist

It is not realistic for developers to read this document when they want to make a release and step through the description of the process. Instead, they should refer to the following checklist and where necessary refer to the description of the process for context and further details.

Note

TODO: Formalise the above as a list of concrete steps.

Indices and tables