mirror of
https://github.com/aljazceru/landscape-template.git
synced 2025-12-29 12:04:23 +01:00
merge: branch 'graphql-functions' of github.com:bumi/makers.bolt.fun into graphql-functions
This commit is contained in:
@@ -1,3 +1,34 @@
|
||||
const { parsePaymentRequest } = require('invoices');
|
||||
const axios = require('axios');
|
||||
const { createHash } = require('crypto');
|
||||
|
||||
function hexToUint8Array (hexString) {
|
||||
const match = hexString.match(/.{1,2}/g);
|
||||
if (match) {
|
||||
return new Uint8Array(match.map((byte) => parseInt(byte, 16)));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO validate responses
|
||||
function getPaymetRequest(lightning_address, amount_in_sat) {
|
||||
const [name, domain] = lightning_address.split("@");
|
||||
const lnurl = `https://${domain}/.well-known/lnurlp/${name}`;
|
||||
return axios.get(lnurl)
|
||||
.then((response) => {
|
||||
console.log(response.data);
|
||||
const callbackUrl = response.data.callback;
|
||||
const amount = amount_in_sat * 1000; // msats
|
||||
return axios.get(callbackUrl, { params: { amount }} )
|
||||
.then(prResponse => {
|
||||
console.log(prResponse.data);
|
||||
return prResponse.data.pr;
|
||||
});
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.error(error);
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
Query: {
|
||||
allCategories: async (_source, args, context) => {
|
||||
@@ -17,13 +48,33 @@ module.exports = {
|
||||
Mutation: {
|
||||
vote: async (_source, args, context) => {
|
||||
const project = await context.prisma.project.findUnique({where: { id: args.project_id }});
|
||||
console.log(project)
|
||||
const pr = await getPaymetRequest(project.lightning_address, args.amount_in_sat);
|
||||
const invoice = parsePaymentRequest({ request: pr });
|
||||
return context.prisma.vote.create({
|
||||
data: {
|
||||
project_id: project.id,
|
||||
amount_in_sat: args.amount_in_sat,
|
||||
payment_request: pr,
|
||||
payment_hash: invoice.id,
|
||||
}
|
||||
});
|
||||
},
|
||||
confirmVote: async (_source, args, context) => {
|
||||
const paymentHash = createHash('sha256').update(hexToUint8Array(args.preimage)).digest('hex');
|
||||
// look for a vote for the payment request and the calculated payment hash
|
||||
const vote = await context.prisma.vote.findFirst({where: { payment_request: args.payment_request, payment_hash: paymentHash}});
|
||||
// if we find a vote it means the preimage is correct and we update the vote and mark it as paid
|
||||
if (vote) {
|
||||
return context.prisma.vote.update({
|
||||
where: { id: vote.id },
|
||||
data: {
|
||||
paid: true,
|
||||
preimage: args.preimage,
|
||||
}
|
||||
});
|
||||
} else {
|
||||
throw new Error("Invalid preimage");
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
@@ -7,6 +7,7 @@ module.exports = gql`
|
||||
thumbnail_image: String!
|
||||
title: String!
|
||||
website: String!
|
||||
lightning_address: String!
|
||||
votes_count: Int!
|
||||
category: Category!
|
||||
}
|
||||
@@ -21,6 +22,7 @@ module.exports = gql`
|
||||
project: Project!
|
||||
amount_in_sat: Int!
|
||||
payment_request: String!
|
||||
payment_hash: String!
|
||||
paid: Boolean!
|
||||
}
|
||||
|
||||
@@ -31,5 +33,6 @@ module.exports = gql`
|
||||
}
|
||||
type Mutation {
|
||||
vote (project_id: Int!, amount_in_sat: Int!): Vote!
|
||||
confirmVote (payment_request: String!, preimage: String!): Vote!
|
||||
}
|
||||
`;
|
||||
|
||||
38091
package-lock.json
generated
38091
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,10 @@
|
||||
"@types/react-dom": "^17.0.10",
|
||||
"apollo-server": "^3.5.0",
|
||||
"apollo-server-lambda": "^3.5.0",
|
||||
"axios": "^0.24.0",
|
||||
"framer-motion": "^5.3.0",
|
||||
"graphql": "^16.0.1",
|
||||
"invoices": "^2.0.2",
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"prisma": "3.5.0",
|
||||
"react": "^17.0.2",
|
||||
|
||||
@@ -16,6 +16,7 @@ CREATE TABLE "Project" (
|
||||
"cover_image" TEXT,
|
||||
"category_id" INTEGER NOT NULL,
|
||||
"votes_count" INTEGER NOT NULL DEFAULT 0,
|
||||
"lightning_address" TEXT,
|
||||
|
||||
CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
@@ -14,16 +14,17 @@ model Category {
|
||||
}
|
||||
|
||||
model Project {
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String
|
||||
website String
|
||||
thumbnail_image String?
|
||||
cover_image String?
|
||||
category Category @relation(fields: [category_id], references: [id])
|
||||
category_id Int
|
||||
votes_count Int @default(0)
|
||||
Vote Vote[]
|
||||
id Int @id @default(autoincrement())
|
||||
title String
|
||||
description String
|
||||
website String
|
||||
thumbnail_image String?
|
||||
cover_image String?
|
||||
lightning_address String?
|
||||
category Category @relation(fields: [category_id], references: [id])
|
||||
category_id Int
|
||||
votes_count Int @default(0)
|
||||
Vote Vote[]
|
||||
}
|
||||
|
||||
model Vote {
|
||||
|
||||
@@ -14,6 +14,7 @@ async function main() {
|
||||
description: "HQ on a VULCANO lake",
|
||||
website: "https://github.com/peakshift",
|
||||
category_id: category.id,
|
||||
lightning_address: "johns@getalby.com",
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user