Getting Started With Solana

June 28 2022


The purpose of this post is not to reproduce what is already out there in the official docs for Solana and phantom but to fill in some of the blanks, and explain what causes some of the common pitfalls. By the end of this post we will have gone through the following:


These last two are where most of the problems lie, and are a result of the many ways that you can derive a public key from a mnemonic seed phrase. Phantom and the Solana CLI employ slightly different standards, and use language that can be easily conflated, which can lead to confusion when people first start getting involved with Solana. Hopefully by the end of this post that confusion will be cleared up, and you'll be ready to start interacting with your first dApps! As a small check that everything is set up, there is a simple 'AirDrop' app at the bottom of the post which you can use to pay yourself fake SOL that can be used on the development network.

Setting Up A File System Wallet


When working within a single ecosystem, getting set up with a wallet is (typically) quite straight forward. The official docs will take you through installing the CLI, so we won't repeat that here. We will only add we recommend just going with the stable version of the tool, so for example on MacOS and Linux that would mean running:

sh -c "$(curl -sSfL https://release.solana.com/stable/install)"


And then following the last steps as described in their guide. With the tools installed you can then straight forwardly create a file system wallet with one of the following commands:

# creates a new keypair in the file my-keypair.json
solana-keygen new --outfile my-keypair.json
# creates a new keypair in the file ~/.config/solana/id.json
solana-keygen new


When you enter this you will then be presented with the following prompt, which will be one possible source of conflict between the CLI and Phantom:

For added security, enter a BIP39 passphrase
NOTE! This passphrase improves security of the recovery seed phrase NOT the
keypair file itself, which is stored as insecure plain text
BIP39 Passphrase (empty for none):


The official docs don't have much too say about the BIP39 passphrase, so this will be the first topic we dive into with a bit more detail. The 39th Bitcoin Improvement Proposal (BIP), which you can read here defined the process both for producing a mnemonic seed phrase, and converting it into a binary seed from which wallets could be generated (more on that last point later). The advantage of having some standard protocol by which to generate these phrases and produce wallets means that in principle, if you want to change your wallet provider (say, from a file system wallet to a Phantom wallet) you should be able to do this simply by knowing your mnemonic seed phrase.

The BIP39 passphrase is an additional layer of security, as it means that even if your seed phrase is revealed it will still be very difficult for anyone to actually determine what your private key is as long as you have a good passphrase. As the passphrase is defined by the user, this can be easier to remember than the random string of words, and likely doesn't need to be written down anywhere. The problem with the passphrase is that not all wallets support it (at least at time of writing). This means that if you use a passphrase now, you won't be able to import your file system wallet into something like Phantom using just your seed phrase. If you try you will just find that the public key Phantom derives is totally different from the one you were using in the file system case (though there can be more reasons for this which we will come to later).

Make sure also to note in this message that the file system wallet is just stored in plain text. This is one of the main disadvantages of such a wallet, and seems a bit of a strange choice. If anyone gains control of the hardware on which the file is stored, they will have access to your private key, so in general file system wallets are only recommended for learning about Solana, and not for keeping accounts with large amounts of value in them.

Setting Up A Phantom Wallet


This is pretty straight forward. Just head over to the phantom app website and install the extension, after that you will see the following screens, although this is mostly self explanatory there is one thing we want to point out.

banner


If you want to you can try and import the file system wallet you made previously to observe the futility of such action, as even if you didn't use the BIP39 passphrase this won't generate the right keys. For now we would recommend creating a new wallet, it will be easy to import your file system wallet into Phantom later.

banner


Note that this password is not the same thing as the BIP39 passphrase you used earlier for the file system wallet. This password won't impact the key you get, but is used to encrypt the key on your disk. You will also need this to authorize any transactions.

phantom_1


Normally you wouldn't show this to anyone, as this is your new seed phrase that will generate your private keys, but we will use this as an example sentence to try and dig into why the file system wallets and Phantom wallets give different public keys even if you don't use the BIP39 passphrase.


That is it for setting up the Phantom wallet. If you want to you can skip ahead to the bottom of the page to try it out and Airdrop yourself some devnet SOL. In the next two sections we will try and reconcile these two accounts, which especially in the final case (importing a Phantom wallet into the file system) is a bit of a rabbit hole.

Import File System Wallet into Phantom


This will be quick. If you click the hamburger icon on the top left of the Phantom app you'll see there is the option to add or connect a wallet. From there click "import private key".

Potentially because of the uncertainty around using seed phrases between different wallet providers, Phantom asks for your private key directly rather than the seed phrase. You can find this in the file you generated previously using the Solana CLI, as an example one we created looks like the following:

[192,96,164,99,23,119,105,230,160,29,141,157,1,161,139,60,198,151,120,93,147,69,183,204,1,97,217,252,78,64,227,152,255,8,57,146,150,179,49,61,5,4,57,95,119,98,146,110,7,233,148,224,53,12,88,223,192,44,227,128,43,4,245,220]

All you have to do is copy this, brackets included, into the box give it a name and you are done. You can then easily swap between your two wallets by clicking the hamburger icon and selecting the one you want.

Import Phantom Wallet into File System


This will not be quick. The CLI provides a means of recovering a keypair from a seed phrase using the command:

solana-keygen recover -o test.json

Enter your "secret recovery phrase" that you got when setting up the Phantom wallet. The CLI will then ask you to enter the associated passphrase. As Phantom doesn't support this, just hit enter. You will then be shown a public key and asked if you want to continue. Comparing that public key to the one displayed on the phantom app though, they are not the same! The reason they aren't the same is down to something called 'Hierarchical Derivation' of keypairs. Here is what the official docs have to say on the subject:


The solana-cli supports BIP32 and BIP44 hierarchical derivation of private keys from your seed phrase and passphrase by adding either the ?key= query string or the ?full-path= query string. By default, prompt: will derive solana's base derivation path m/44'/501'. To derive a child key, supply the ?key=<ACCOUNT>/<CHANGE> query string.
To use a derivation path other than solana's standard BIP44, you can supply ?full-path=m/<PURPOSE>/<COIN_TYPE>/<ACCOUNT>/<CHANGE>. Because Solana uses Ed25519 keypairs, as per SLIP-0010 all derivation-path indexes will be promoted to hardened indexes -- eg. ?key=0'/0', ?full-path=m/44'/2017'/0'/1' -- regardless of whether ticks are included in the query-string input.

I think even a seasoned crypto veteran might find this hard to parse without at least a few re-reads, so we will try and break it down and explain why it is relevant to the issue at hand. Both BIP32 and BIP44 describe a means of deriving many keypairs from a single seed phrase, without requiring that each requires it's own separate phrase. This means you only need to remember a single seed phrase, but can manage many different accounts.
In order to derive different keypairs, you need to define the derivation path which has the form

path=m/<PURPOSE>/<COIN_TYPE>/<ACCOUNT>/<CHANGE>


PURPOSE is always set to the value 44, which simply denotes that we are using the BIP44 standard for defining the path
COIN_TYPE is always 501, which is the index of Solana in the SLIP-0044 register
ACCOUNT is an integer from 0, and is incremented each time you want to derive a new account
CHANGE should be 0 for any account that you want to be visible outside the wallet, and therefore be able to receive funds

By default, the Solana CLI provides the derivation path m/44'/501' which actually generates the master keypair for your seed phrase. The two BIPs suggest that in general you shouldn't actually use this one, because if someone gains control of your master key, they will gain access to all your derived accounts, whereas losing a derived keypair means losing only that account. This is where the reference to the indices being hardened comes in. If you generate non-hardened derived keys, then knowledge of any descended keypair will allow you to determine the master key. If the path is hardened then even with knowledge of any number of derived keypairs it is impractical on any reasonable time frame to determine that those derived keypairs came from the same master, and therefore impractical to determine what that master was.

While the Solana CLI will generate the root keypair by default, wallets like Phantom will give you the first keypair along the derivation path, i.e they start with m/44'/501'/0'/1', and increment from there every time you add a new account from the same seed phrase.

sollet
To visualize this you can head over to sollet.io. At the bottom of the page you can click "Restore existing wallet", and copy your phantom seed phrase into box. You don't need to enter a password (this isn't referring to a BIPM39 passphrase anyway), so just click next.

You will be presented with a list of derivable accounts, starting with 0 (this should match your phantom pubkey) and incrementing the account index in the path by one for each subsequent line.

You should now be armed with everything you need to know to finally import one of your phantom accounts into a file system wallet! On the command line you can enter:

solana-keygen recover "prompt://?full-path=m/44'/501'/0'/0'" -o phantom_0.json

And at last the public keys will match.

Use Your Phantom Wallet In A Simple DApp


At this stage you should hopefully have your Phantom wallet set up, and at least one of your phantom wallets imported as a file system wallet, so as a last step let's actually make use of them! Firstly make sure that your wallet is connected to the devnet rather than the mainnet. You can do this by going to the settings in the app, clicking "Change Network" and selecting devnet.

Once you've done that, just click the big purple button below to connect to your Phantom wallet.


Connect a wallet to get started!

Once it has connected you should see the account pubkey to the right of the button, and the current balance below. Clicking the Airdrop button will pay yourself 1 SOL on the devnet, which you can then spend on testing your own dApps, or interacting with other devnet programs. If you want to swap between different Phantom accounts (via the hamburger icon in the app), just hit disconnect and then reconnect once you've switched.

As one last thing, if you have imported one of your phantom accounts into a file system wallet, you can confirm that they are all pointing to the same place. First, as with Phantom you will need to point the Solana CLI to the devnet, which can be done by entering the following on the command line:


solana config set --url https://api.devnet.solana.com

You can then check the balance on your account with the following, replacing the json file with whatever you named your imported file system wallet:


solana balance phantom_0.json

That should give the same balance, and confirm that everything has worked as expected.

On that note we will bring this post to a close. Hopefully you have learnt something about the way your keypairs are generated, and if nothing else have paid yourself some fake SOL to spend on future projects. If you did find this useful feel free to follow us on Twitter to keep up to date with future posts, and the release of our first proper Solana DApp!