-
Notifications
You must be signed in to change notification settings - Fork 12
Wallet
- We separate the product specs into use cases / requirements guides and visual design / interaction design guides. The use cases describe
what
flows should be supported by the wallet. The interaction design guides describehow
the features that implement the use cases should look and feel on desktop and mobile screen classes. - The wallet app runs in the context of the
Spacemesh App
in a web browser, natively on a mobile device (iOS or Android), or in the Spacemesh App native cross-platform desktop app (on OS X, Windows or Linux). The app and the wallet are implemented in Javascript and can use npm modules, including modules that contain wasm code.
-
Wallet App
orWallet
- the Spacemesh Wallet app. It includes the wallet, dashboard and additional features. -
Network
- mainnet, testnet1, testnet2, etc… identified by an id. -
Spacemesh Wallet
(Wallet
)- Passphrase / pin (or bio-auth on supported platforms) protected with optional paper backup phrases
- Contains one or more accounts. One default account and optional additional accounts
- Has a friendly display name with a reasonable default. e.g. 'Main Wallet'
- Has a backup-able data file which contains passphrase encrypted wallet and account data
- Implemented using the
BIP44 HD Wallet
spec and additional related BIPs - Associated with only one network id.
-
Account
- Has one BLS signature key-pair (private and public key)
- Has an account public address which is its public key
- Has a friendly display name with a reasonable default. e.g. 'Main Account'
- Always belongs to a specific wallet
- An account private key should be only accessible by account owner (by unlocking the account’s wallet)
- Associated with only one specific network id
Network Id -> Wallet (random seed) -> Default Account + Optional additional accounts.
-
Signatures Scheme
- Accounts should use BLS signatures
- We need to implement support for deriving BLS signatures from one master random seed by extending BIP32 key derivation, which only supports
secp256k1
signatures
-
Default Account
- a key pair at index 0 of a Spacemesh Wallet (BIP32 account
is constant 0 in the wallet). Additional accounts may be created following the BIP32 addresses scheme (extended to support BLS)
-
User creates a new
wallet
- a new
BIP44 HD Wallet
with BLS support is created for each new wallet - Each new wallet has a
default account
which is created from the wallet's first address key-pair (at BIP44 account 0) - User may create additional accounts in the wallet for the wallet's network id
- User may create additional wallets - each wallet is secured with a different passphrase and optionally with a 12 words mnemonic for paper backups
- Each wallet is associated with a specific network id. e.g. mainnet, testnet1, etc... To work with multiple networks, user is expected to switch between wallets
- Note that it is highly-likely that the vast majority of users will only need one wallet with one account and will never need to create additional accounts or wallets or to switch from the mainnet to a testnet
- We are likely to automate the implementation of this use case for the first time user experience. So, when a new user opens the app for the first time, a new wallet on mainent is automatically created and the interaction starts from the next step
- a new
-
User provides and confirms a passphrase / PIN for securing access to the wallet on his or her device
- User is strongly encouraged to store the passphrase in a password manager such as 1Password
- The wallet is persisted to local storage with a private key derived from the passphrase using a key derivation algorithm (to mitigate brute force attacks against wallet files)
- Each wallet should be saved to a stand-alone wallet data file so the user can easily backup each wallet individually and identify files by his friendly wallet names.
- Technically, an
BIP44 HD Wallet
is created from a random generated BIP32 specified seed and the user provided passphrase - Alternatively, user can use a biometric authentication method instead of a passphrase. e.g. FaceId on iPHone X or newer, and TouchID on new MacBook Pro devices. This should only be supported when the wallet runs on a device that supports such auth method
-
Continue to the optional backup wallet use case from here
-
User tells the app he'd like to backup his wallet or the app determines that it needs to prompt the user to backup his wallet
-
App displays the wallet's randomly generated
12 words mnemonic
and instruct user to write them on paper and store in a safe place. User may chose to backup at a later time -
App asks the user to confirm his written down 12 words mnemonic by challenging him to provide some of them (see UX)
Note: we may force user user to perform and verify a backup once he or she has a minimum Spacemesh Coin
balance in the wallet, or maybe even on the start of the app's second user session before allowing him or her to transact with Spacemesh Coins
User needs to provide a coinbase account for his 'Spacemesh full p2p node'.
-
User unlocks a wallet using the passphrase (or bio auth on supported platforms) or has just created a new wallet (first app user session)
-
The default user account is presented (account at index 0 for the wallet) as well as means to copy it (copy address icon)
-
User copies the account public address and sets it as the
coinbase account
for aSpacemesh Node
Note: think about automated setup using the node's https-json API that is secure. e.g. user needs to confirm the account in the node REPL to avoid attacks which set a rough coinbase account for a node.
Background There are 2 main options to connect to the Spacemesh network, which technically means connect to a Spacemesh json-http API endpoint. On desktop, connect to a locally running Spacemesh mode, or to the Spacemesh gateway api endpoint. On mobile connection is always through the Spacemesh gateway api endpoint. Note that an API end point always provides the API for a specific network id.
The app has a notion of a default network
. For the testnet release, before the mainnet is released, this should be setup to the Spacemesh testnet1. When the mainent is released, the default network should be the Spacemesh mainent and developer will be able to switch to the testnet for testing purposes.
The app will be pre-configured with gateway endpoints for all supported networks, e.g. testnet1, testnet2, mainnet.
On app startup, the app should try to connect to an API using the following rules:
First App Run - new user wallet
- Attempt to connect to the default network via a local node api endpoint by using a well-known default port.
- If connection fails, attempt to connect to the default network via a preconfigured gateway endpoint.
- If connection fails, show error and show offline connection state.
- Once connected or if connection failed create a new wallet for the user in the default network
Second Run - existing user wallet
- Load the default wallet data and get the network ID from the user's wallet
- Attempt to connect to a locally running node api endpoint
- If connected to the local api, and the api is not running the same network id as the wallet's network id then disconnect
- If disconnected or fail to connect then connect via the gateway providing the network id of the wallet
- If connection fails then warns user that he's offline, otherwise show the connection state
-
The current networkID as well as the connection state (disconnected / connecting / connected) should always be visible in the UI
-
When switching between wallets with different network id. The app should connect to the newly opened wallet network id as specified above
- User inputs the payee account address (public key), amount to transfer and the transaction fee (auto computed using default gas price and only an issue once the network is at full transactional capacity. While the network growth, fee will be set to a very low amount just to mitigate spam attacks and users won't need to modify a gas price)
- User confirms the transaction
- The transaction is generated, signed and broadcasted to the Spacemesh network via the connected Spacemesh API endpoint (gateway, localhost, etc...)
- The transaction and its receipt is recorded in the wallet's
transaction log
so the user can access it at a later time, check transaction status and resubmit failed transactions - User is notified when the transaction is confirmed by the network (most likely using the wallet's runtime platform notification capabilities)
- App prompts the user to input the wallet's seed 12 words mnemonic
- User inputs the 12 words mnemonic phrases
- User inputs a new pin code / passphrase or uses a biometric auth method to secure the new wallet data file in local storage
- The wallet is recreated and saved to local storage, protected by the passphrase or the bio auth method
- The wallet app starts pulling confirmed transactions for this wallet from the network and displayes them in the UI
The Spacemesh API provides this functionality so the wallet can display any account current Spacemesh Coins balance. So, when an account is displayed in the UI, the app should use the API endpoint to get async the current balance and display it when data was returned from the API. The API should also provide a fiat currencies conversion rate oracle so the wallet can display amounts in USD or another user specified supported fiat currency such as EURO.
- User selects to backup a wallet data file for his wallet
- If the file is not protected by a passphrase, e.g. with a bio auth method that user is asked to provide a pin / passprhase to protected the file data and the file data is encrypted with a key derived from the user's passphrase.
- On desktop, the app opens the OS file explorer (Finder, Explorer, etc...) in the file's directory and ideally selects the file
- On mobile, the app opens the save to file option as the file is in the encrypted native app local store. User can save his file to a cloud file storage or to the local file system
- User locates the data file path on his device local storage
- User is prompted to provide the wallet's pin code / passphrase
- The app imports the wallet to its local storage and adds a new wallet to its model
- User is prompt to protect the imported wallet with pin / passphrase or with a bio auth method (faceId, touchId, etc...)
- User is prompted to name the wallet (wallet friendly name)
- User names the new wallet
- User is prompted to protect the wallet with pin code / passphrase / bio auth method
- The wallet is created and protected according to the user's actions in step 3
- The app displays the wallet's default account
- User selects to open a specific wallet
- App presents a list of available wallets (previously accessed by it on that device)
- User unlocks the wallet using pin code / passphrase / bio auth
- The app display's the open wallets default account
- User selects to name a wallet and enters new name
- Wallet name is updated in the app and in the wallet's data file
Note that each wallet has a unique default name. e.g. 'My Main Wallet' for the first wallet and 'New Wallet' for advanced users who create a new wallet.
- User accesses the wallet
- User specify to add a new account in an open wallet
- User is prompted to name the new account
- The new account is added to the wallet (data file and app ui)
- User accesses an account
- User specify to name the account and inputs the new unique account name
- Account is renamed in the wallet's data file
Note that each wallet has a default account named My Main Account
.