add forgetten lnurl-auth files

This commit is contained in:
keyan 2021-06-26 22:18:32 -05:00
parent 2e26e421e7
commit 9a15c228dc
8 changed files with 143 additions and 1 deletions

26
api/resolvers/lnurl.js Normal file
View File

@ -0,0 +1,26 @@
import { randomBytes } from 'crypto'
import { bech32 } from 'bech32'
export default {
Query: {
lnAuth: async (parent, { k1 }, { models }) => {
return await models.lnAuth.findUnique({ where: { k1 } })
}
},
Mutation: {
createAuth: async (parent, args, { models }) => {
const k1 = randomBytes(32).toString('hex')
return await models.lnAuth.create({ data: { k1 } })
}
},
LnAuth: {
encodedUrl: async (lnAuth, args, { models }) => {
const url = new URL(process.env.LNAUTH_URL)
url.searchParams.set('tag', 'login')
url.searchParams.set('k1', lnAuth.k1)
// bech32 encode url
const words = bech32.toWords(Buffer.from(url.toString(), 'utf8'))
return bech32.encode('lnurl', words, 1023)
}
}
}

19
api/typeDefs/lnurl.js Normal file
View File

@ -0,0 +1,19 @@
import { gql } from 'apollo-server-micro'
export default gql`
extend type Query {
lnAuth(k1: String!): LnAuth!
}
extend type Mutation {
createAuth: LnAuth!
}
type LnAuth {
id: ID!
createdAt: String!
k1: String!
pubkey: String
encodedUrl: String!
}
`

31
components/lnqr.js Normal file
View File

@ -0,0 +1,31 @@
import QRCode from 'qrcode.react'
import { CopyInput, InputSkeleton } from './form'
import InvoiceStatus from './invoice-status'
export default function LnQR ({ value, statusVariant, status }) {
const qrValue = 'lightning:' + value.toUpperCase()
return (
<>
<div>
<QRCode className='h-auto mw-100' value={qrValue} renderAs='svg' size={300} />
</div>
<div className='mt-3 w-100'>
<CopyInput type='text' placeholder={value} readOnly />
</div>
<InvoiceStatus variant={statusVariant} status={status} />
</>
)
}
export function LnQRSkeleton ({ status }) {
return (
<>
<div className='h-auto w-100 clouds' style={{ paddingTop: 'min(300px, 100%)', maxWidth: '300px' }} />
<div className='mt-3 w-100'>
<InputSkeleton />
</div>
<InvoiceStatus variant='default' status={status} />
</>
)
}

17
lib/lnurl.js Normal file
View File

@ -0,0 +1,17 @@
import { randomBytes } from 'crypto'
import { bech32 } from 'bech32'
export function lnurlAuth (params) {
// generate secret (32 random bytes)
const secret = Buffer.from(randomBytes(32), 'hex')
// create url
const url = new URL(process.env.LNAUTH_URL)
url.searchParams = new URLSearchParams({
...params,
k1: secret
})
// bech32 encode url
const words = bech32.toWords(Buffer.from(url.toString(), 'utf8'))
const encodedUrl = bech32.encode('lnurl', words, 1023)
return { secret, encodedUrl }
}

View File

@ -94,7 +94,7 @@ const options = {
})
],
adapter: Adapters.Prisma.Adapter({ prisma }),
secret: process.env.SECRET,
secret: process.env.NEXTAUTH_SECRET,
session: { jwt: true },
jwt: {
signingKey: process.env.JWT_SIGNING_PRIVATE_KEY

21
pages/api/lnauth.js Normal file
View File

@ -0,0 +1,21 @@
// verify it's signed
// store pubkey in db
// create user with pubkey and name truncated pubkey
import secp256k1 from 'secp256k1'
import models from '../../api/models'
export default async ({ query }, res) => {
const sig = Buffer.from(query.sig, 'hex')
const k1 = Buffer.from(query.k1, 'hex')
const key = Buffer.from(query.key, 'hex')
const signature = secp256k1.signatureImport(sig)
try {
if (secp256k1.ecdsaVerify(signature, k1, key)) {
await models.lnAuth.update({ where: { k1: query.k1 }, data: { pubkey: query.key } })
return res.status(200).json({ status: 'OK' })
}
} catch (error) {
console.log(error)
}
return res.status(400).json({ status: 'ERROR', reason: 'signature verification failed' })
}

View File

@ -0,0 +1,25 @@
/*
Warnings:
- A unique constraint covering the columns `[pubkey]` on the table `users` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE "users" ADD COLUMN "pubkey" TEXT;
-- CreateTable
CREATE TABLE "LnAuth" (
"id" SERIAL NOT NULL,
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"k1" TEXT NOT NULL,
"pubkey" TEXT,
PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "LnAuth.k1_unique" ON "LnAuth"("k1");
-- CreateIndex
CREATE UNIQUE INDEX "users.pubkey_unique" ON "users"("pubkey");

3
svgs/lightning.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19 10.1907L8.48754 21L12.6726 12.7423H5L14.6157 3L11.5267 10.2835L19 10.1907Z" fill="black"/>
</svg>

After

Width:  |  Height:  |  Size: 207 B