Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update to fiat #329

Merged
merged 2 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 46 additions & 27 deletions src/controllers/api_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ const {
AWAITING_ATTEST,
ARG_TOKEN_ID,
ARG_SLOT_ID,
EXPIRY_DATE_ERROR
EXPIRY_DATE_ERROR,
BAD_COMMITMENT
} = require('../utils/constants');

const {
Expand All @@ -59,13 +60,12 @@ const {

const DATE_FORMAT = 'HH:mm:ss L z';

const C_LIGHTNING_URL = env.c_lightning.url;
const MACAROON_HEX = env.c_lightning.macaroon_hex;
const FEE_RATE_PER_MONTH_IN_MSAT = env.c_lightning.fee_rate_per_month_in_msat;
const LIGHTNING_URL = env.lightning.url;
const API_KEY = env.lightning.api_key;
const FEE_RATE_PER_MONTH_IN_EUR = env.lightning.fee_rate_per_month_in_eur;
const INVOICE_DESCRIPTION = 'Invoice for Mainstay token';
const C_LIGHTNING_REQUEST_HEADERS = {
'encodingtype': 'hex',
'macaroon': MACAROON_HEX,
const LIGHTNING_REQUEST_HEADERS = {
'Api-Key': API_KEY,
'Content-Type': 'application/json'
};

Expand Down Expand Up @@ -439,6 +439,15 @@ module.exports = {
return reply_err(res, MISSING_PAYLOAD_TOKEN, startTime);
}


if (payload.commitment.length !== 64) {
return reply_err(res, BAD_COMMITMENT, startTime);
}
if (payload.commitment.split('').every(c => '0123456789ABCDEFabcdef'.indexOf(c) !== -1)) {
return reply_err(res, BAD_COMMITMENT, startTime);
}


const signatureCommitment = data[MAINSTAY_SIGNATURE];
try {
// try get client details
Expand Down Expand Up @@ -1181,18 +1190,27 @@ module.exports = {
}
const token_id = uuidv4();
try {
const response = await axios.post(C_LIGHTNING_URL + '/v1/invoice/genInvoice', {
amount: amount,
label: token_id,
description: INVOICE_DESCRIPTION
const response = await axios.post(LIGHTNING_URL + '/checkout', {
title: token_id,
description: INVOICE_DESCRIPTION,
amount: amount,
unit: "EUR",
redirectAfterPaid: "",
email: "",
emailLanguage: "en",
onChain: true,
delay: 60,
extra: {
tag: "invoice-web"
}
}, {
headers: C_LIGHTNING_REQUEST_HEADERS
headers: LIGHTNING_REQUEST_HEADERS
});
const invoice = response.data;

if (invoice) {
const tokenDetailsData = {
token_id: token_id,
pp_id: invoice.id,
value: amount,
confirmed: false,
amount: 0
Expand All @@ -1201,15 +1219,15 @@ module.exports = {
await tokenDetails.save();
reply_msg(res, {
"lightning_invoice": {
"bolt11": invoice.bolt11,
"expires_at": invoice.expires_at,
"payment_hash": invoice.payment_hash
"bolt11": invoice.pr,
},
"token_id": token_id,
"value": amount
"value": amount,
"bitcoin_address": invoice.onChainAddr,
}, startTime);
}
} catch (error) {
console.log(error);
reply_err(res, INTERNAL_ERROR_API, startTime);
}
},
Expand All @@ -1221,21 +1239,22 @@ module.exports = {
return;
}
try {
const response = await axios.get(C_LIGHTNING_URL + '/v1/invoice/listInvoices?label=' + token_id,
const tokenDetails = await models.tokenDetails.findOne({token_id: token_id});
const response = await axios.get(LIGHTNING_URL + '/checkout/' + tokenDetails.pp_id,
{
headers: C_LIGHTNING_REQUEST_HEADERS
headers: LIGHTNING_REQUEST_HEADERS
});
const invoice = response.data.invoices[0];
console.log(response);
const pp_response = response.data;
let invoice_paid = false;
if (invoice && invoice.status === "paid") {
const tokenDetails = await models.tokenDetails.findOne({token_id: token_id});
if (pp_response.isPaid) {
tokenDetails.confirmed = true;
tokenDetails.amount = invoice.msatoshi;
tokenDetails.amount = pp_response.fiatAmount;
await tokenDetails.save();
invoice_paid = true;
}
reply_msg(res, {
amount: invoice.msatoshi,
amount: pp_response.amount,
confirmed: invoice_paid
}, startTime);
} catch (error) {
Expand Down Expand Up @@ -1266,7 +1285,7 @@ module.exports = {
const startTime = start_time();
try {
reply_msg(res, {
fee_rate: FEE_RATE_PER_MONTH_IN_MSAT
fee_rate: FEE_RATE_PER_MONTH_IN_EUR
}, startTime);
} catch (error) {
reply_err(res, INTERNAL_ERROR_API, startTime);
Expand All @@ -1287,8 +1306,8 @@ module.exports = {
const slot_id = data[ARG_SLOT_ID];
const tokenDetails = await models.tokenDetails.findOne({token_id: token_id});

if (tokenDetails.amount >= FEE_RATE_PER_MONTH_IN_MSAT) {
const months = tokenDetails.amount / FEE_RATE_PER_MONTH_IN_MSAT;
if (tokenDetails.amount >= FEE_RATE_PER_MONTH_IN_EUR) {
const months = tokenDetails.amount / FEE_RATE_PER_MONTH_IN_EUR;
if (!isNaN(slot_id) && Number(slot_id) === 0) {
const clientDetailsData = await create_slot_with_token(months);
reply_msg(res, {
Expand Down
8 changes: 4 additions & 4 deletions src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,9 @@ module.exports = {
secret: onfidoWebhookSecret
}
},
c_lightning: {
url: env.C_LIGHTNING_URL,
macaroon_hex: env.MACAROON_HEX,
fee_rate_per_month_in_msat: env.FEE_RATE_PER_MONTH_IN_MSAT
lightning: {
url: env.LIGHTNING_URL,
api_key: env.API_KEY,
fee_rate_per_month_in_eur: env.FEE_RATE_PER_MONTH_IN_EUR
}
};
1 change: 1 addition & 0 deletions src/models/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ schemaClientSignup.index({'verify_code': 1});

const schemaTokenDetails = new Schema({
token_id: String,
pp_id: String,
value: Number,
confirmed: Boolean,
amount: Number
Expand Down
3 changes: 2 additions & 1 deletion src/utils/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const constants = {
ARG_SLOT_ID: 'slot_id',
BAD_LENGTH_TXID: 'txid string parameter must contain 64 characters',
BAD_LENGTH_COMMITMENT: 'commitment string parameter must contain 64 characters',
BAD_COMMITMENT: 'commitment is not a valid hex string',
BAD_TYPE_POSITION: 'position expects a int',
BAD_TYPE_VALUE: 'value expects an int',
COMMITMENT_POSITION_UNKNOWN: 'your commitment or position is unknown to us',
Expand Down Expand Up @@ -54,4 +55,4 @@ const constants = {

constants.BAD_LENGTH_MERKLE_ROOT = constants.BAD_LENGTH_COMMITMENT;

module.exports = constants;
module.exports = constants;
6 changes: 1 addition & 5 deletions src/view/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ const Footer = () => (
<Link to="/" className="logo">
<img src="favicon.png" alt="favicon" />
</Link>
<span>© 2020 CommerceBlock Limited. All rights reserved.</span>
<div className="powered-by">
<span>Powered by </span>
<a href="https://www.securosys.com/en/"><img src="securosys.png" alt="logo" /></a>
</div>
<span>© 2024 CommerceBlock Limited. All rights reserved.</span>
</div>
</div>
</footer>
Expand Down
14 changes: 5 additions & 9 deletions src/view/modals/CreateSlotModal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ import {Button, Form, FormGroup, Input, Label, Modal, ModalBody, ModalFooter, Mo
import apiService from '../../helpers/api-service';
import QRCode from "qrcode.react";

function milliSatsToSats(milliSats) {
return milliSats / 1000;
}

class CreateSlotModal extends React.PureComponent {

constructor(props) {
Expand All @@ -20,7 +16,7 @@ class CreateSlotModal extends React.PureComponent {
inputs: {
months: 1,
},
fee_rate_per_month_in_msat: '',
fee_rate_per_month_in_eur: '',
invoice: '',
copied: false,
confirmed: false,
Expand All @@ -33,7 +29,7 @@ class CreateSlotModal extends React.PureComponent {
apiService.axiosClient.get('/api/v1/feerate')
.then(({ data, error }) => {
if (data?.response) {
this.setState({ fee_rate_per_month_in_msat: data.response.fee_rate });
this.setState({ fee_rate_per_month_in_eur: data.response.fee_rate });
}
});
}
Expand Down Expand Up @@ -67,7 +63,7 @@ class CreateSlotModal extends React.PureComponent {
return this.showErrorAlert('Months field is empty');
}

const fee_rate = this.state.fee_rate_per_month_in_msat;
const fee_rate = this.state.fee_rate_per_month_in_eur;
const amount = fee_rate * months;

apiService.axiosClient.get(`/api/v1/token/init/?value=${amount}`)
Expand Down Expand Up @@ -155,9 +151,9 @@ class CreateSlotModal extends React.PureComponent {
>
<ModalBody>
{this.props.slotDetails.new_slot ?
<h6>Pay with lightning to reserve a unique proof-of-publication slot for {milliSatsToSats(this.state.fee_rate_per_month_in_msat)} sats a month</h6>
<h6>Pay with lightning to reserve a unique proof-of-publication slot for {this.state.fee_rate_per_month_in_eur} EUR a month</h6>
:
<h6>Pay with lightning to keep using slot number {this.props.slotDetails.slot_id} for {milliSatsToSats(this.state.fee_rate_per_month_in_msat)} sats a month</h6>
<h6>Pay with lightning to keep using slot number {this.props.slotDetails.slot_id} for {this.state.fee_rate_per_month_in_eur} EUR a month</h6>
}
<FormGroup>
<Label className="f-bold fs14">Months</Label>
Expand Down
Loading