In this article, I will guide you to make a betting game on the Lightning network
Prepare :
Clone source code here
- Polar (app to create test environment Installation instructions here )
- Joule (Lightning wallet installation instructions here )
- Reactjs
- Nodejs
Environment setup:
I chose to use polar to create an environment with just a few clicks
First we will create a network consisting of 1 bitcoind node and 3 LND nodes
Then create a channel between the nodes.
So we have temporarily set up the environment to test already.
Building the app
Target
First, we still have to solve the problem of growing what to raise first. In this article I will guide how to make simple betting games. The rule is very simple, that is, the player chooses a range of values, for example, predicts the next random number is greater than 50 and the result is 78 , we will play. However, there will be a difference in the ratio we guess for example, as in the case above we guess greater than 75 , it will gain more money than we guess is greater than 50.
The app has 2 parts Backend and Frontend. The Back End of the game will be a node LND we assume that Alice node on the environment setup on Polar. As a player we can choose Bob or Carol here we choose Bob
Wallet
After downloading joule, we only need to enter 2 values admin.macaroon and readonly.macaroon Select Local node
Enter the REST Host value of the node we choose here we choose Bob
Drag and drop the admin.macaroon and readonly.macaroon files into it
That’s it then
Backend
My Backend uses Nodejs
The backend we will use is Alice node. First we create a .env file
1 2 3 4 | LND_URL=127.0.0.1:10001 LND_MACAROON_PATH=/home/ubuntu/.polar/networks/2/volumes/lnd/alice/data/chain/bitcoin/regtest/admin.macaroon LND_CERT_PATH=/home/ubuntu/.polar/networks/2/volumes/lnd/alice/tls.cert |
We will fill in the parameters Polar provides for Alice Node
- LND_URL: GRPC Host
- LND_MACAROON_PATH: Admin Macaroon FIle path
- LND_CERT_PATH: TLS Cert File path
Then create an RPC.js file to run commands that communicate with LND through RPC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'dotenv'</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">config</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> fs <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'fs'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> grpc <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'grpc'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> protoLoader <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'@grpc/proto-loader'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> packageDefinition <span class="token operator">=</span> protoLoader <span class="token punctuation">.</span> <span class="token function">loadSync</span> <span class="token punctuation">(</span> <span class="token string">'./rpc.proto'</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> keepCase <span class="token punctuation">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> lnrpc <span class="token operator">=</span> grpc <span class="token punctuation">.</span> <span class="token function">loadPackageDefinition</span> <span class="token punctuation">(</span> packageDefinition <span class="token punctuation">)</span> <span class="token punctuation">.</span> lnrpc <span class="token punctuation">;</span> process <span class="token punctuation">.</span> env <span class="token punctuation">.</span> <span class="token constant">GRPC_SSL_CIPHER_SUITES</span> <span class="token operator">=</span> <span class="token string">'HIGH+ECDSA'</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> cert <span class="token operator">=</span> fs <span class="token punctuation">.</span> <span class="token function">readFileSync</span> <span class="token punctuation">(</span> process <span class="token punctuation">.</span> env <span class="token punctuation">.</span> <span class="token constant">LND_CERT_PATH</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> lndCert <span class="token operator">=</span> Buffer <span class="token punctuation">.</span> <span class="token keyword">from</span> <span class="token punctuation">(</span> cert <span class="token punctuation">,</span> <span class="token string">'utf8'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> sslCreds <span class="token operator">=</span> grpc <span class="token punctuation">.</span> credentials <span class="token punctuation">.</span> <span class="token function">createSsl</span> <span class="token punctuation">(</span> lndCert <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> macaroonCreds <span class="token operator">=</span> grpc <span class="token punctuation">.</span> credentials <span class="token punctuation">.</span> <span class="token function">createFromMetadataGenerator</span> <span class="token punctuation">(</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> args <span class="token punctuation">,</span> callback <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> macaroon <span class="token operator">=</span> fs <span class="token punctuation">.</span> <span class="token function">readFileSync</span> <span class="token punctuation">(</span> process <span class="token punctuation">.</span> env <span class="token punctuation">.</span> <span class="token constant">LND_MACAROON_PATH</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">toString</span> <span class="token punctuation">(</span> <span class="token string">'hex'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> metadata <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">grpc <span class="token punctuation">.</span> Metadata</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> metadata <span class="token punctuation">.</span> <span class="token function">add</span> <span class="token punctuation">(</span> <span class="token string">'macaroon'</span> <span class="token punctuation">,</span> macaroon <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token function">callback</span> <span class="token punctuation">(</span> <span class="token keyword">null</span> <span class="token punctuation">,</span> metadata <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> creds <span class="token operator">=</span> grpc <span class="token punctuation">.</span> credentials <span class="token punctuation">.</span> <span class="token function">combineChannelCredentials</span> <span class="token punctuation">(</span> sslCreds <span class="token punctuation">,</span> macaroonCreds <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> lightning <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">lnrpc <span class="token punctuation">.</span> Lightning</span> <span class="token punctuation">(</span> process <span class="token punctuation">.</span> env <span class="token punctuation">.</span> <span class="token constant">LND_URL</span> <span class="token punctuation">,</span> creds <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Note: must download 1 file ./rpc.proto (download here ) of LND and put the same path vs file rpc.js
Then you can see the RPC api https://api.lightning.community/#lnd-grpc-api-reference example I wrote the function to send Payment
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">var</span> <span class="token function-variable function">sendPayment</span> <span class="token operator">=</span> payment_request <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token class-name">Promise</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> resolve <span class="token punctuation">,</span> reject <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">var</span> request <span class="token operator">=</span> <span class="token punctuation">{</span> payment_request <span class="token punctuation">:</span> payment_request <span class="token punctuation">}</span> <span class="token punctuation">;</span> lightning <span class="token punctuation">.</span> <span class="token function">sendPaymentSync</span> <span class="token punctuation">(</span> request <span class="token punctuation">,</span> <span class="token keyword">function</span> <span class="token punctuation">(</span> err <span class="token punctuation">,</span> response <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token function">resolve</span> <span class="token punctuation">(</span> response <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">;</span> |
Then you can write APIs that run these functions
To solve the problem of trust in gambling games like this, the Bitcoin community has come up with a solution for a random number selection technique that Provably fair I also shared about it in this article .
Flow description
Frontend
Webln
To interact with Joule we use the Webln library to interact with the user.
The first is webln.sendPayment and webln.makeInvoice
- webln.sendPayment : This function to show the user a popup screen to confirm the payment when starting to play.
- webln.makeInvoice : this function will show the user a popup screen confirming the amount the player will receive when winning then create an invoice and send the token to the server
Although there are many parts that need elaborate, but basically this is a direction to develop Dapp on the Lightning network.
You can refer to my repo: https://github.com/vinhyenvodoi98/Lightning_maxbet