Last active
October 23, 2019 02:21
-
-
Save whiteyhat/85048e46db618c697e1e9a9f8b49426b 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