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!