diff --git a/src/app.js b/src/app.js index 6153f8d..1492a3e 100644 --- a/src/app.js +++ b/src/app.js @@ -1,6 +1,7 @@ import express from 'express'; import dotenv from 'dotenv'; import currencyRoutes from './routes/currencyRoutes.js'; +import { transactionRoute } from './routes/transaction.js'; dotenv.config(); @@ -12,6 +13,7 @@ app.use(express.urlencoded({ extended: true })); // Routes app.use('/api/currency', currencyRoutes); +app.use('/api/currency', transactionRoute); // Error handling middleware app.use((err, req, res) => { diff --git a/src/controllers/customers/sendBitcoin.js b/src/controllers/customers/sendBitcoin.js new file mode 100644 index 0000000..9613537 --- /dev/null +++ b/src/controllers/customers/sendBitcoin.js @@ -0,0 +1,71 @@ +import { AxiosService } from "../../services/axios/AxiosService.js"; + +const BITNOB_BASE_URL = process.env.BITNOB_BASE_URL +const BITNOB_API_KEY = process.env.BITNOB_SANDBOX_API_URL; + +const bitnobClient = new AxiosService(BITNOB_BASE_URL, BITNOB_API_KEY); + +// generate address +export const generateAddress = async (req, res) => { + try { + const { label = 'purchase xbox', customerEmail, formatType = 'bip21', amount = '' } = req.body; + + if (!customerEmail) { + return res.status(400).json({ status: false, message: 'customerEmail is required' }); + }; + + const addressData = { label, customerEmail, formatType, amount }; + const response = await bitnobClient.post('/addresses/generate', addressData); + + console.log("response data:", response.data); + console.log('Full response.data:', JSON.stringify(response.data, null, 2)); + + const { data } = response; + if (data.status) { + return res.status(200).json({ + status: true, + message: 'Address successfully generated', + data: response.data.data, + }); + } else { + return res.status(500).json({ status: false, message: 'Failed to generate address' }); + }; + } catch (error) { + console.error('Generate address error:', error.response?.data || error.message); + return res.status(500).json({ status: false, message: 'Failed to generate address' }); + }; +}; + +// Send bitcoin onchain +export const sendBitcoin = async (req, res) => { + try { + const { satoshis, address, customerEmail, description = '', priorityLevel = 'regular' } = req.body; + + if (!satoshis || !address || !customerEmail) { + return res.status(400).json({ status: false, message: 'satoshis, address, and customerEmail are required' }); + } + + const paymentData = { satoshis, address, customerEmail, description, priorityLevel }; + const response = await bitnobClient.post('/wallets/send_bitcoin', paymentData); + + const { data } = response; + if (data.status === true) { + console.log('sending bitcoin successful', data.data); + + return res.status(200).json({ + status: true, + message: 'Address successfully generated', + data: data + }); + } else { + return res.status(400).json({ + status: false, + message: 'Failed to send bitcoin', + }); + }; + + } catch (error) { + console.error('Send bitcoin error:', error.response?.data || error.message); + return res.status(500).json({ message: 'Internal Server Error', error}); + }; +}; diff --git a/src/index.js b/src/index.js index cb54e96..93bd215 100644 --- a/src/index.js +++ b/src/index.js @@ -19,6 +19,7 @@ import { BaseError } from './errors/errors.js'; // Models import './models/wallet.js'; import './models/transaction.js'; +import { transactionRoute } from './routes/transaction.js'; import './models/btcAddressModel.js'; // Load environment variables @@ -44,6 +45,7 @@ app.use(urlencoded({ extended: true, limit: '200mb' })); app.use('/api/wallet', walletRoute); app.use(`${BASE_URL}/customers`, customersRouter); app.use(`${BASE_URL}/currency`, currencyRoutes); +app.use(`${BASE_URL}/transaction`, transactionRoute); app.use(`${BASE_URL}/btc/address`, btcAddressRoutes); // Error handling middleware diff --git a/src/routes/transaction.js b/src/routes/transaction.js new file mode 100644 index 0000000..ac831b6 --- /dev/null +++ b/src/routes/transaction.js @@ -0,0 +1,9 @@ +import Router from 'express'; +import { generateAddress, sendBitcoin } from '../controllers/customers/sendBitcoin.js'; +const router = Router(); + +router.post('/address', generateAddress); + +router.post('/create', sendBitcoin); + +export {router as transactionRoute}