Home

Awesome

Threefold Electron Wallet

:information_source: More information about this desktop application and its positioning as a product.

A desktop application that allows you to manage all your Threefold wallets. We support four types of tokens, Threefold token (TFT), Goldchain token (GFT), EuroToken (EUR), Free Flow token (FFT) and Threefold Bonus token (TFB). Each wallet is linked to an account, and an account is identified by a seed (mnemonic phrase). An account can have multiple wallets. Each wallet can have up to 8 addresses and requires a minimum 1 address (the default).

The mnemonic phrase (used as seed for an account) is compatible with the Threefold mobile application, JumpscaleX light client and official Threefold binary tools. This allows you to recover your wallets created in these clients as an account of this client. Accounts created with this client can also recovered with the other clients. Do note that the the Threefold mobile application and JumpscaleX light client will only recover the default wallet of your account. In these other clients there is also no concept of account, but just a single wallet. The JumpscaleX light client does allow you to load as many addresses as you want in a single wallet, the the Threefold mobile application is limited to just one address of just one wallet.

:warning: This project is currently still in alpha-mode. No direct support is offered at this point. Do feel free to report issues if you encounter a problem or have suggestions. Pull requests are also welcome. As this is also not an official Threefold product, it is not expected that direct support will ever be offered. It might also mean that while some features could be useful for this App, it won't be added due to time constraints.

Index

Download

GitHub release

:exclamation: macOS and Windows users will have to do some extra steps to be able to use our application, given it will be marked as an untrusted application (or at least an application from an untrusted developer).

Usage

While we hope that the Application is intuitive and easy to use, it might very well be possible that it is still not clear to you on what to do. Should this be the case feel free to open an issue so we can improve our user experience (UX). In the meanwhile, hopefully this Usage chapter allows you to figure out how to achieve what you want to do.

Index:

Home

screenshot of home page

When you start the application you'll have the option between creating a new account, by recovering an account using your own seed or by creating a new account using a generated seed, or logging into a stored account.

Account Creation

screenshot of account creation page

This page allows you to create a new account and store it on your local disk:

Account Recovery

screenshot of account recovery page

Similar to account creation, except that you'll provide the seed (mnemonic phrase, a 24-word list) yourself, instead of opting to generate one.

Account Login

screenshot of account login page

Provide the password you choose at account creation or account-recovery to start using your account. This is required in order to decrypt your account details from the local disk.

Account Overview

screenshot of account overview page

Shows an overview of your wallets as well as your account's total balance. On the left pane you'll find your regular (personal) wallets separated by the multi-signature wallets (wallets co-owned by you and others) below.

Account settings can be found at the top right, next to the "Account Logout" button.

Receive, Transfer and Sign buttons go to the same pages as those available on the wallet overview page, using/selecting the default (first personal/regular wallet) as the wallet of choice.

Account Settings

screenshot of account settings page

Allows you to change the account's name and delete the account. You'll also find shortcuts to the wallet settings page as well as a shortcut for each wallet to delete it.

Wallet Overview

screenshot of wallet overview page

Similar to the account overview page but with a focus on a specific (regular/personal) wallet.

Additionally you'll also find a transaction history on this page, sorted from newest to oldest.

MultiSignature Wallet Overview

screenshot of multi-sig wallet overview page

Similar to the wallet overview page but with a focus on a specific multi-signature wallet.

Transfer

screenshot of wallet transfer page

Allows you to transfer tokens from one wallet to another. The destination can be a regular (personal) wallet, multi-signature wallet as well as one of your own wallets. Depending on which destination wallet you want to send you, you'll need to select the correct tab.

You cannot transfer 0 tokens or more tokens (+ the minimum transaction fee of 0.1 TFT or 0.1 GFT) than available in your account.

Optionally you can attach a timelock to your transfer, meaning the transfered funds are locked in the destination wallet until the specified date (and time). If no time is specified 00:00 is used. Note that the funds will immediately be taken from your wallet and sent to the destination wallet.

Receive

screenshot of wallet receive page

Allows you to copy your wallet address(es).

The provided QR Code (for single signature wallets) is compatible with the official Threefold Mobile App, meaning you can use that app to scan this QR code and immediately transfer tokens to this wallet (Please ensure that you're on the same network as this account, or your tokens won't arrive where you expect them).

Sign

screenshot of wallet sign page

Allows you to sign the transaction and if possible send it. This page is currently only required for co-signing a transaction that could be not be send yet after trying to transfer from a Multi-signature wallet which requires multiple signatures.

For example: if you and your partner co-own a 2-of-2 wallet, meaning you 2 are the only owners and both of you have to sign. Than you'll see that if you try to transfer funds from that wallet to another wallet that it will direct you to a page complaining it required more signatures. At that point you need to copy the provided JSON (transaction) output to your clipboard and send it to your partner (e.g. via an IM application). When receiving this JSON (transaction) output from you, your partner will paste the content on this page and press the "Sign and Send" button. The transaction will now succesfully be signed and sent to the official explorer nodes.

:exclamation: ensure that you sign from the correct wallet or it will give you an error that it failed to sign and submit.

Wallet Settings

screenshot of wallet settings page

Allows you to change the wallet's name and delete the wallet.

For regular (personal) wallets you can also update the start index and address length. You can have no more than 8 addresses per wallet, and at least 1 is required. This allows you to provide aliases for different purposes to the same wallet. The start index defines what addresses are generated. In short, each address is generated using the seed of your account plus an index as the input for the private/public cryptographic key pair that is used to sign with a wallet and from which an address is generated. As an example if you have start index 1, and address length 3, than the wallet will use the indices 2, 3, 4 and 5.

:bulb: For multi-signature wallets this is not used, and thus it is not available in the settings page of a multi-signature wallet.

Address Book

screenshot of account creation page

This page allows you to create, delete and modify contacts. A contact is identified by a name and can represent a single-signature wallet as well as a multi-signature wallet.

Scripted Transactions

No matter how many transaction forms we'll provide the user, there will always be use cases that cannot be achieved using the GUI. That is where the Scripted Transactions Send page comes in.

It allows you to use modern ES6 javascript directly to define your logic, using our internal JS API. It is currently still undocumented, but you can view the API code at /src/api.py.

Your script will have access to the following two global variables exposed by the eval code:

Besides our exposed tfchain globals you can also access the standard builtin JS globals (e.g. Date).

Examples

This is an example script allowing you to transfer a total amount of tokens to someone, spreaded over several months (default is 24), where each of those months 1/24 of the total amount will unlock:

function() {

// script constants
const destination = '<ENTER WALLET ADDRESS HERE>'
const periodMonthCount = 24
const startUnlockDateTime = '2020.01.01 00:00:00'
const amount = new Currency('<ENTER AMOUNT HERE, e.g: 42.345>')
const message = ''

// generate periodic pay info
const startUnlockDate = new Date(startUnlockDateTime)
let unlockInfo = []
const periodicAmount = amount.divided_by(periodMonthCount)
for (let i = 0; i < periodMonthCount; i++) {
    var m, d = (date = new Date(+startUnlockDate)).getUTCDate()
    date.setUTCMonth(date.getUTCMonth() + i, 1)
    m = date.getUTCMonth()
    date.setUTCDate(d)
    if (date.getUTCMonth() !== m) date.setUTCDate(0)
    unlockInfo.push({
        timestamp: date.getTime() / 1000,
        amount: new Currency(periodicAmount),
    })
}

// correct first payment in case rounding errors have occured
const totalAmount = periodicAmount.times(periodMonthCount)
const difference = amount.minus(totalAmount)
if (difference.not_equal_to(0)) {
    unlockInfo[0].amount = unlockInfo[0].amount.plus(difference)
}

// ensure our total amount equals the desired amount
let newTotalAmount = new Currency()
unlockInfo.forEach((unlockPair) => newTotalAmount = newTotalAmount.plus(unlockPair.amount))
if (amount.not_equal_to(newTotalAmount)) {
    throw 'unexpected total amount of ' + newTotalAmount.str({unit: true})
}

// build transaction
const builder = wallet.transaction_new()
unlockInfo.forEach((unlockPair) => {
    builder.output_add(destination, unlockPair.amount.str(), { lock: unlockPair.timestamp })
})

// send the transaction and return the result promise
const resprom = builder.send({ message: message ? message : null }).then(result => {
    return {
        output: `successfully sent ${amount.str({unit: true})} to ${destination} unlocked over ${periodMonthCount} month(s) starting at ${startUnlockDateTime} as Txn ${result.transaction.id}`,
    }
})

// return our resulting promise
return {
    output: resprom,
}

}()

This is an example script that allows you to ensure your wallet only has a limited amount of coin outputs, doing paid merge transactions if required:

function() {

// script constants
const maxOutputsPerWalletCount = 32

// callback used to merge
let txs = []
const merge_callback = (result) => {
    if (result) {
        if (!result.submitted) {
            // special case in case no transactions were submitted
            if (txs.length == 0) {
                return { output: 'No merge transactions have been submitted!' }
            }

            // get the total merged value
            let mergeTotal = new Currency()
            txs.forEach(tx => {
                tx.coin_outputs.forEach(co => {
                    mergeTotal = mergeTotal.plus(co.value)
                })
            })

            // return the merge info
            let output = `Successfully merged ${mergeTotal.str({unit: true})} in ${txs.length} merge transaction(s). All Transactions: `
            output += txs.map(tx => tx.id).join(', ')
            return { output }
        }

        // add submitted transaction
        txs.push(result.transaction)
    }

    // send next merge transaction
    const builder = wallet.transaction_new()
    return builder.send({ merge: true, mergeMinOutputCount: maxOutputsPerWalletCount+1 }).then(merge_callback)
}

// merge & report
return { output: merge_callback() }

}()

Developer Docs

Debug a Production Build

Debug a Production Build on MacOS

  1. open App through lldb (required Xcode command-line tools, which can be installed using xcode-select --install)
lldb /Applications/Threefold-Wallet.app
  1. Using the opened debugger open a window of your app:
run --remote-debugging-port=8315
  1. Open Chrome at http://localhost:8315/
  2. Click on the name of the App "Threefold Wallet"
  3. Many of the regular dev tools that you are used to in dev builds are now available. To check warnings and errors you can for example open the console.

Run as developer

Install dependencies

$ yarn

Start the app in the dev environment. This starts the renderer process in hot-module-replacement mode and starts a webpack dev server that sends hot updates to the renderer process:

$ yarn dev

If you don't need autofocus when your files are changed, then run dev with env START_MINIMIZED=true:

$ START_MINIMIZED=true yarn dev

Packaging

To package apps for the local platform:

$ yarn package

To package apps for all platforms:

First, refer to the Multi Platform Build docs for dependencies.

Then,

$ yarn package-all

To package apps with options:

$ yarn package --[option]

Linux packaging

$ yarn package-linux

Will generate AppImage, snap, deb, rpm packages. We recommend using AppImage

Running AppImage

Just Download the application, make it executable, and run! No need to install. No system libraries or system preferences are altered.