My first Solana Project π
So, I've decided to participate in Solana Hackathon. Here I'm going to write down my journey. Part 1 - "Hello world".
So, the first thing to do is to install Solana.
sh -c "$(curl -sSfL https://release.solana.com/v1.7.11/install)"
from the official guide. And update PATH accordingly.
Then let's download the hello-world example. I'm not going to follow it though. Because it uses server-side JavaScript client, and I want to have a browser-side client.
So, skipping CLI part of a readme, straight to building the on-chain part:
npm run build:program-rust
While it is building, let's have a look what we actually have there.
The on-chain program starts with some imports and entrypoint specification. Straightforward.
Ok, we are ready do deploy. So, at first we need to start a local Solana "cluster", consisting of our own host. I did that by launching solana-test-validator
in tmux.
Now, it is useful to familiarize yourself with your wallet id, which can be obtained in this way:
$ solana config get Config File: $HOME/.config/solana/cli/config.yml RPC URL: http://localhost:8899 WebSocket URL: ws://localhost:8900/ (computed) Keypair Path: $HOME/.config/solana/id.json Commitment: confirmed $ solana-keygen pubkey $HOME/.config/solana/id.json # Keypair Path 9FRakBFwajAdRhfqwLFWAWUuEySs7rcRviMA5xnrHqST
By default your key does not have any money, but because the cluster is yours, you can fund it πΈπ·π€
$ solana airdrop 100 $ solana balance 100 SOL
Now we have enough resources to deploy the application. The built process has already generated a random "account" for our program. Account is just an "address" of a program, it's ID, or whatever. It is a random ID which Solana and other participants will use to refer to our program. This is how to get it:
$ solana-keygen pubkey dist/program/helloworld-keypair.json 3cbqMCdkwiTbWyCv3i7gss8STqGw6ggzvg8ztt5msnD4
And now we can deploy our binary, and assign it that program ID.
$ solana program deploy $HOME/example-helloworld/dist/program/helloworld.so --program-id dist/program/helloworld-keypair.json Program Id: 3cbqMCdkwiTbWyCv3i7gss8STqGw6ggzvg8ztt5msnD4
Great!. Something has happened. Now, let's have some fun.
First thing is to forward your ports, because my Solana runs on a remote host, and there is no way to setup a custom RPC address, only "localhost" in the wallet.
(localhost) $ ssh -L 8899:127.0.0.1:8899 MY.IP.ADD.RESS
BTW. Wallet. Just install Phantom wallet in your browser. Set network to be 127.0.0.1:8899 and import your key (private key is a contents of $$HOME/.config/solana/id.json)
on your remote host.
Sorry, guys, can not resist a temptation:
Airdrop 100 makes you feel happy :) Haha!
So, we are almost there. The last thing to do is to make a JavaScript call to your on-chain program.
Some trivial JavaScript to make it work was:
<html> <head> <script src="https://unpkg.com/@solana/web3.js@latest/lib/index.iife.js"></script> </head> <body> <button id="btn-connect" disabled>Connect</button> <span id="connection-status"></span>| <button id="btn-send" disabled>Send</button> <script type="text/javascript"> window.addEventListener('load', function() { const btn_connect = window.document.getElementById("btn-connect"); btn_connect.disabled = false; btn_connect.addEventListener('click', () => { const connection_status = window.document.getElementById("connection-status"); connection_status.innerHTML = "Connecting"; window.solana.on("connect", () => { connection_status.innerHTML = `Connected as ${solana.publicKey.toString()}`; const btn_send = document.getElementById("btn-send"); btn_send.disabled = false; btn_send.addEventListener('click', async () => { const connection = new solanaWeb3.Connection("http://127.0.0.1:8899"); const instruction = new solanaWeb3.TransactionInstruction({ keys: [{pubkey: new solanaWeb3.PublicKey("9FRakBFwajAdRhfqwLFWAWUuEySs7rcRviMA5xnrHqST"), isSigner: false, isWritable: true}], // All instructions are hellos programId: new solanaWeb3.PublicKey("3cbqMCdkwiTbWyCv3i7gss8STqGw6ggzvg8ztt5msnD4"), // data: Buffer.alloc(0), }); const bh = ( await connection.getRecentBlockhash() ).blockhash; console.log(bh); const transaction = new solanaWeb3.Transaction({ feePayer: window.solana.publicKey, recentBlockhash: bh, }); transaction.add(instruction); const signedTransaction = await window.solana.signTransaction(transaction); await connection.sendRawTransaction(signedTransaction.serialize()); alert('done'); }); }); window.solana.connect(); }); }); </script> </body> </html>
Sorry for the codestyle, it is really highly experimental.
I found those resources very useful:
- https://solana-labs.github.io/solana-web3.js/classes/Transaction.html
- https://github.com/phantom-labs/docs/blob/866e96237d8b2addcd5a58dc31b314237b40ea4f/integrating/sending-a-transaction.md
Hope you found your answers here!
The second part is ready!