-
-
Save andrerfneves/9892aa618803768b6dea31ff0d4a07d8 to your computer and use it in GitHub Desktop.
Backend implementation using adonis.js framework for Lightning Network withdrawals straight to wallet using LNURL
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const Logger = use('Logger') | |
const bech32 = require('bech32') | |
const Hash = use('Hash') | |
const lnService = require('ln-service') | |
const NonceHashMap = {}; | |
const k1HashMap = {}; | |
async requestWithdrawal ({auth, response}) { | |
try{ | |
if (auth.user.unique_id){ | |
// create random nonce for the user | |
const nonce = Math.floor(Math.random() * 1000000) // TODO: stronger source of randomness | |
// add item to hashmap | |
NonceHashMap[Hash.make(nonce)] = auth.user.id | |
return response.json({ | |
data: bech32.encode('LNURL', "https://satoshis.games/withdrawal/confirmation?q="+nonce).toLocaleUpperCase() | |
}) | |
} | |
}catch(error){ | |
Logger.error(error) | |
return response.json({error}) | |
} | |
} | |
async confirmWithdrawal ({response, request}) { | |
const { q } = request.all() | |
if (Hash.make(q) in NonceHashMap){ | |
const existingUserId = NonceHashMap[Hash.make(q)] | |
delete NonceHashMap[Hash.make(q)]; // Invalidate a QR | |
const secondLevelNonce = Math.floor(Math.random() * 1000000) // TODO: stronger source of randomness | |
// k1HashMap[Hash.make(k1)] = Hash.make(auth.user.id) | |
k1HashMap[Hash.make(secondLevelNonce)] = existingUserId | |
return response.json({ | |
callback = "https://satoshis.games/withdrawal/execute", | |
k1 = secondLevelNonce, | |
maxWithdrawable = 2000, // msat | |
defaultDescription = "withdraw from satoshis.games", | |
tag = "withdrawRequest", | |
}) | |
} | |
} | |
async executeWithrawal ({request}) { | |
const { k1 } = request.all() | |
const { pr } = request.all() | |
if (Hash.make(k1) in k1HashMap){ | |
const existingUserId = k1HashMap[Hash.make(k1)] | |
delete k1HashMap[Hash.make(k1)]; | |
this.makePayment({pr}) | |
response.ok() | |
} else { | |
return json({ status: "ERROR", reason: "Second level nonce not found" }) | |
} | |
} | |
async makePayment ({pr}) { | |
try { | |
const lnd = await LndService.getLndInstance() | |
// Payment to encoded invoice request | |
await lnService.pay({ | |
lnd, | |
request: pr | |
}, (error, result) => { | |
Logger.info(result) | |
Logger.error('Error:', error) | |
}) | |
}catch(error){ | |
Logger.error(error) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment