diff --git a/backend/bun.lockb b/backend/bun.lockb index 86a4af0..fb61550 100755 Binary files a/backend/bun.lockb and b/backend/bun.lockb differ diff --git a/backend/src/libs/store.ts b/backend/src/libs/store.ts index 1eaa43d..01f8917 100644 --- a/backend/src/libs/store.ts +++ b/backend/src/libs/store.ts @@ -8,6 +8,6 @@ const minioClient = new Client({ secretKey: process.env.MINIO_SECRETKEY!, }) -const bucketName = process.env.MINIO_BUCKET!; +const bucketName = process.env.MINIO_BUCKET_NAME!; export { minioClient, bucketName }; diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts index 8cc270e..f1927e5 100644 --- a/backend/src/routes/index.ts +++ b/backend/src/routes/index.ts @@ -2,7 +2,6 @@ import { Elysia } from "elysia"; import authRoutes from "@/routes/auth"; import machineRoutes from "@/routes/machine"; import storeRoutes from "@/routes/store"; -import paymentRoutes from "@/routes/payment"; const routes = new Elysia(); @@ -10,7 +9,6 @@ routes .get("/", () => "Hello from Elysia!") .group("/auth", (routes) => routes.use(authRoutes)) .group("/machine", (routes) => routes.use(machineRoutes)) - .group("/store", (routes) => routes.use(storeRoutes)) - .group("/payment", (routes) => routes.use(paymentRoutes)); + .group("/store", (routes) => routes.use(storeRoutes)); export default routes; diff --git a/backend/src/routes/payment/index.ts b/backend/src/routes/payment/index.ts deleted file mode 100644 index 3cc9f35..0000000 --- a/backend/src/routes/payment/index.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Elysia, t } from "elysia"; -import paymentController from "@/routes/payment/payment.controller"; - -const paymentRoutes = new Elysia(); - -paymentRoutes - .post("/generate", paymentController.GenerateURL, { - body: t.Object( - { - destinationWallet: t.String(), - cost: t.Number() - }, - { - description: "Expected Destination Wallet address.", - }, - ), - detail: { - summary: "Generate Payment URL", - tags: ["payment"], - }, - }) - - -export default paymentRoutes; diff --git a/backend/src/routes/payment/payment.controller.ts b/backend/src/routes/payment/payment.controller.ts deleted file mode 100644 index f617f5d..0000000 --- a/backend/src/routes/payment/payment.controller.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { Connection, Keypair, PublicKey } from '@solana/web3.js'; -import { encodeURL } from '@solana/pay'; -import BigNumber from 'bignumber.js'; - - -const reference = new Keypair().publicKey; -const label = 'Escrow Contract'; -const message = 'Funding Escrow Contract'; -const memo = 'Solana Pay Public Memo'; - - -const GenerateURL = async ({ body, set, log }) => { - try { - const { destinationWallet, cost } = body; - - const recipient = new PublicKey(destinationWallet); - const amount = new BigNumber(cost); - - const url: URL = encodeURL({ recipient, amount, reference, label, message, memo }); - // console.log('Payment request link:', url); - - set.status = 201; - return url; - } catch (err) { - log.error(err); - set.status = 500; - return { message: "Internal Server Error" }; - } -}; - - -export default { - GenerateURL -}; diff --git a/frontend/bun.lockb b/frontend/bun.lockb index adebded..af3db07 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/components/Provider/dashboard/screens/Resources.tsx b/frontend/components/Provider/dashboard/screens/Resources.tsx index a229a7a..541e114 100644 --- a/frontend/components/Provider/dashboard/screens/Resources.tsx +++ b/frontend/components/Provider/dashboard/screens/Resources.tsx @@ -64,7 +64,6 @@ function returnPrice(core: number, ram: number): string[] { return ["0.0832", "0.00585"] case 2: return ["0.126", "0.000886"] - default: break; } @@ -76,7 +75,6 @@ function returnPrice(core: number, ram: number): string[] { return ["0.09", "0.000633"] case 2: return ["0.136", "0.000956"] - default: break; } diff --git a/frontend/components/search/SearchWrapper.tsx b/frontend/components/search/SearchWrapper.tsx index c9bb5f7..2608b29 100644 --- a/frontend/components/search/SearchWrapper.tsx +++ b/frontend/components/search/SearchWrapper.tsx @@ -5,9 +5,7 @@ import ComputeCard from './cards/ComputeCard' export default async function SearchWrapper() { const machines = await (await fetch(`${process.env.NEXT_PUBLIC_API_URL}/machine/all`, { - next: { - revalidate: 3600 - } + cache: 'no-store' })).json() return ( diff --git a/frontend/components/search/cards/ComputeCard.tsx b/frontend/components/search/cards/ComputeCard.tsx index 9ec1dc7..91870c0 100644 --- a/frontend/components/search/cards/ComputeCard.tsx +++ b/frontend/components/search/cards/ComputeCard.tsx @@ -1,12 +1,130 @@ +"use client" +import { Connection, Keypair, LAMPORTS_PER_SOL, PublicKey, sendAndConfirmTransaction, SystemProgram, Transaction, TransactionInstruction } from '@solana/web3.js'; +import { encodeURL, validateTransfer, parseURL, TransferRequestURL, findReference } from '@solana/pay'; +import { useWallet } from "@solana/wallet-adapter-react"; +import BigNumber from 'bignumber.js'; import { Button } from '@/components/ui/button'; import { SpecsCard } from '@/constants/images/models/specscard.model' import { Rocket } from 'lucide-react'; -import React from 'react' +import bs58 from 'bs58'; interface Props { props: SpecsCard; } + + + +const addr = process.env.NEXT_PUBLIC_ESCROW_CONTRACT_WALLET +const payer = Keypair.fromSecretKey( + bs58.decode(`${addr}`) +) + +const quickNodeEndpoint = 'https://green-wiser-violet.solana-testnet.quiknode.pro/ba1187ecaae779be46900d5f0355ac4ff2780bc7/' +const connection = new Connection(quickNodeEndpoint, 'confirmed') + +const reference = new Keypair().publicKey +const label = 'Escrow Contract' +const message = 'Funding Escrow Contract' +const memo = 'Solana Pay Public Memo' + + + + + export default function ComputeCard({ props }: Props) { + + const { publicKey } = useWallet() + + async function GenerateUrl( + recipient: PublicKey, + amount: BigNumber, + reference: PublicKey, + label: string, + message: string, + memo: string + ) { + const url: URL = encodeURL({ recipient, amount, reference, label, message, memo }) + return url + } + + + async function processPayment(url: URL, payer: Keypair) { + const { recipient, amount, reference, label, message, memo } = parseURL(url) as TransferRequestURL; + if (!recipient || !amount || !reference) throw new Error('Invalid payment request link') + + const tx = new Transaction() + + if (memo != null) { + tx.add( + new TransactionInstruction({ + programId: new PublicKey(`${publicKey}`), + keys: [], + data: Buffer.from(memo, 'utf8'), + }) + ) + } + const ix = SystemProgram.transfer({ + fromPubkey: payer.publicKey, + toPubkey: recipient, + lamports: amount.multipliedBy(LAMPORTS_PER_SOL).integerValue(BigNumber.ROUND_FLOOR).toNumber() + }); + if (reference) { + const ref = Array.isArray(reference) ? reference : [reference] + for (const pubkey of ref) { + ix.keys.push({ pubkey, isWritable: false, isSigner: false }) + } + } + + tx.add(ix); + + const txId = await sendAndConfirmTransaction(connection, tx, [payer]) + console.log(txId) + } + + + async function verifyTx( + recipient: PublicKey, + amount: BigNumber, + reference: PublicKey, + memo: string + ) { + const found = await findReference(connection, reference) + + const response = await validateTransfer( + connection, + found.signature, + { + recipient, + amount, + splToken: undefined, + reference, + memo + }, + { commitment: 'confirmed' } + ) + return response + } + + + async function allInUnison() { + try { + const recepient = new PublicKey(props.address) + + const cost = parseInt(props.cpu) * (-0.000250583) + parseInt(props.ram) * 0.0000327202 + 0.00214017 + const amount = new BigNumber(cost) + + const url = await GenerateUrl(recepient, amount, reference, label, message, memo) + await processPayment(url, payer); + const response = await verifyTx(recepient, amount, reference, memo); + if (!response || response.meta?.err) throw new Error('Not verified'); + console.log('🎉 Payment Confirmed!'); + } + catch (err) { + console.error(err) + } + } + + return (