From 3ae988620a79e4883bdb1bce37cead24f13ba02d Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:04:27 +0200 Subject: [PATCH 01/17] implement unified googleSpreadsheet controller --- .../googleSpreadSheet.controller.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 signer-service/src/api/controllers/googleSpreadSheet.controller.js diff --git a/signer-service/src/api/controllers/googleSpreadSheet.controller.js b/signer-service/src/api/controllers/googleSpreadSheet.controller.js new file mode 100644 index 00000000..45465e4a --- /dev/null +++ b/signer-service/src/api/controllers/googleSpreadSheet.controller.js @@ -0,0 +1,26 @@ +require('dotenv').config(); + +const { spreadsheet } = require('../../config/vars'); +const { initGoogleSpreadsheet, getOrCreateSheet, appendData } = require('../services/spreadsheet.service'); + + +exports.storeDataInGoogleSpreadsheet = async (req, res, spreadsheetId, SHEET_HEADER_VALUES) => { + try { + // We expect the data to be an object that matches our schema + const data = req.body; + + // Try dumping transactions to spreadsheet + const sheet = await initGoogleSpreadsheet(spreadsheetId, spreadsheet.googleCredentials).then((doc) => getOrCreateSheet(doc, SHEET_HEADER_VALUES)); + + if (sheet) { + console.log('Appending data to sheet'); + await appendData(sheet, data); + return res.status(200).json({ message: 'Data stored successfully' }); + } + + return res.status(500).json({ error: 'Failed to store data. Sheet unavailable.' }); + } catch (error) { + console.error('Error in storeData:', error); + return res.status(500).json({ error: 'Failed to store data', details: error.message }); + } +}; From 2d518c0b8de33d9ffb1f50bbc6f1cc3ffc9e32e2 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:06:32 +0200 Subject: [PATCH 02/17] implement googleSpreadsheet email controller --- .../src/api/controllers/email.controller.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 signer-service/src/api/controllers/email.controller.js diff --git a/signer-service/src/api/controllers/email.controller.js b/signer-service/src/api/controllers/email.controller.js new file mode 100644 index 00000000..45f9f7a6 --- /dev/null +++ b/signer-service/src/api/controllers/email.controller.js @@ -0,0 +1,12 @@ +const { spreadsheet } = require('../../config/vars'); +const { storeDataInGoogleSpreadsheet } = require('./googleSpreadsheet.controller'); + +// These are the headers for the Google Spreadsheet +const EMAIL_SHEET_HEADER_VALUES = [ + 'timestamp', + 'email' +]; + +exports.EMAIL_SHEET_HEADER_VALUES = EMAIL_SHEET_HEADER_VALUES; + +exports.storeEmail = async (req, res) => storeDataInGoogleSpreadsheet(req, res, spreadsheet.emailSheetId, EMAIL_SHEET_HEADER_VALUES) From c653d61a4d6315e91db04b4f4b92230c46a94770 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:07:02 +0200 Subject: [PATCH 03/17] update googleSpreadsheet storage controller --- .../src/api/controllers/storage.controller.js | 28 +++---------------- 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/signer-service/src/api/controllers/storage.controller.js b/signer-service/src/api/controllers/storage.controller.js index f94b0bea..55113473 100644 --- a/signer-service/src/api/controllers/storage.controller.js +++ b/signer-service/src/api/controllers/storage.controller.js @@ -1,10 +1,8 @@ -require('dotenv').config(); - const { spreadsheet } = require('../../config/vars'); -const { initGoogleSpreadsheet, getOrCreateSheet, appendData } = require('../services/spreadsheet.service'); +const { storeDataInGoogleSpreadsheet } = require('./googleSpreadsheet.controller'); // These are the headers for the Google Spreadsheet -exports.SHEET_HEADER_VALUES = [ +const SHEET_HEADER_VALUES = [ 'timestamp', 'polygonAddress', 'stellarEphemeralPublicKey', @@ -16,25 +14,7 @@ exports.SHEET_HEADER_VALUES = [ 'stellarCleanupTx', ]; -exports.storeData = async (req, res, next) => { - try { - // We expect the data to be an object that matches our schema - const data = req.body; - - // Try dumping transactions to spreadsheet - const sheet = await initGoogleSpreadsheet(spreadsheet.sheetId, spreadsheet.googleCredentials).then((doc) => { - return getOrCreateSheet(doc, this.SHEET_HEADER_VALUES); - }); +exports.SHEET_HEADER_VALUES = SHEET_HEADER_VALUES; - if (sheet) { - console.log('Appending data to sheet'); - await appendData(sheet, data); - return res.status(200).json({ message: 'Data stored successfully' }); - } +exports.storeData = async (req, res) => storeDataInGoogleSpreadsheet(req, res, spreadsheet.storageSheetId, SHEET_HEADER_VALUES) - return res.status(500).json({ error: 'Failed to store data. Sheet unavailable.', details: error.message }); - } catch (error) { - console.error('Error in storeData:', error); - return res.status(500).json({ error: 'Failed to store data', details: error.message }); - } -}; From 8bf29d02a6e1a4e9103af1d9c4747c5cb46eee5e Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:08:03 +0200 Subject: [PATCH 04/17] add GOOGLE_EMAIL_SPREADSHEET_ID env var --- signer-service/src/config/vars.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/signer-service/src/config/vars.js b/signer-service/src/config/vars.js index 3aa64104..ec17e533 100644 --- a/signer-service/src/config/vars.js +++ b/signer-service/src/config/vars.js @@ -19,6 +19,7 @@ module.exports = { email: process.env.GOOGLE_SERVICE_ACCOUNT_EMAIL, key: process.env.GOOGLE_PRIVATE_KEY?.split(String.raw`\n`).join('\n'), }, - sheetId: process.env.GOOGLE_SPREADSHEET_ID, + storageSheetId: process.env.GOOGLE_SPREADSHEET_ID, + emailSheetId: process.env.GOOGLE_EMAIL_SPREADSHEET_ID, }, }; From ae41774e31bb1210115fd0c28d32c04f63b38226 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:09:14 +0200 Subject: [PATCH 05/17] unify validateInputHeaderValues for storage and email routes --- signer-service/src/api/middlewares/validators.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/signer-service/src/api/middlewares/validators.js b/signer-service/src/api/middlewares/validators.js index e8943da4..959287c4 100644 --- a/signer-service/src/api/middlewares/validators.js +++ b/signer-service/src/api/middlewares/validators.js @@ -1,4 +1,5 @@ const { SHEET_HEADER_VALUES } = require('../controllers/storage.controller'); +const { EMAIL_SHEET_HEADER_VALUES } = require('../controllers/email.controller'); const validateCreationInput = (req, res, next) => { const { accountId, maxTime, assetCode } = req.body; @@ -32,12 +33,12 @@ const validateChangeOpInput = (req, res, next) => { next(); }; -const validateStorageInput = (req, res, next) => { +const validateInputHeaderValues = (requiredHeaders) => (req, res, next) => { const data = req.body; - // Check if the data contains values for all the headers - if (!SHEET_HEADER_VALUES.every((header) => data[header])) { - const missingItems = SHEET_HEADER_VALUES.filter((header) => !data[header]); - let errorMessage = 'Data does not match schema. Missing items: ' + missingItems.join(', '); + + if (!requiredHeaders.every((header) => data[header])) { + const missingItems = requiredHeaders.filter((header) => !data[header]); + const errorMessage = 'Data does not match schema. Missing items: ' + missingItems.join(', '); console.error(errorMessage); return res.status(400).json({ error: errorMessage }); } @@ -45,4 +46,7 @@ const validateStorageInput = (req, res, next) => { next(); }; -module.exports = { validateChangeOpInput, validateCreationInput, validateStorageInput }; +const validateStorageInput = validateInputHeaderValues(SHEET_HEADER_VALUES); +const validateEmailInput = validateInputHeaderValues(EMAIL_SHEET_HEADER_VALUES); + +module.exports = { validateChangeOpInput, validateCreationInput, validateStorageInput, validateEmailInput }; From e8e81f32d1f6897940c233f23541fe77c9ddde76 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:09:51 +0200 Subject: [PATCH 06/17] add email routes --- signer-service/src/api/routes/v1/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/signer-service/src/api/routes/v1/index.js b/signer-service/src/api/routes/v1/index.js index 410edf61..2e3678d5 100644 --- a/signer-service/src/api/routes/v1/index.js +++ b/signer-service/src/api/routes/v1/index.js @@ -2,6 +2,7 @@ const express = require('express'); const stellarRoutes = require('./stellar.route'); const pendulumRoutes = require('./pendulum.route'); const storageRoutes = require('./storage.route'); +const emailRoutes = require('./email.route'); const router = express.Router({ mergeParams: true }); const { sendStatusWithPk: sendStellarStatusWithPk } = require('../../services/stellar.service'); @@ -37,5 +38,6 @@ router.use('/pendulum', pendulumRoutes); * POST v1/storage */ router.use('/storage', storageRoutes); +router.use('/email', emailRoutes); module.exports = router; From 245f96651a52d0fc79827d1f70c8fc787f3c4589 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:10:38 +0200 Subject: [PATCH 07/17] implement email routes --- signer-service/src/api/routes/v1/email.route.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 signer-service/src/api/routes/v1/email.route.js diff --git a/signer-service/src/api/routes/v1/email.route.js b/signer-service/src/api/routes/v1/email.route.js new file mode 100644 index 00000000..806eae22 --- /dev/null +++ b/signer-service/src/api/routes/v1/email.route.js @@ -0,0 +1,9 @@ +const express = require('express'); +const controller = require('../../controllers/email.controller'); +const { validateEmailInput } = require('../../middlewares/validators'); + +const router = express.Router({ mergeParams: true }); + +router.route('/create').post(validateEmailInput, controller.storeEmail); + +module.exports = router; From 0ad941d5001d6ae5521ac1a75db7574891f83635 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:12:01 +0200 Subject: [PATCH 08/17] remove console.log --- src/services/storage/remote.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/services/storage/remote.ts b/src/services/storage/remote.ts index 39305b8a..7150daf1 100644 --- a/src/services/storage/remote.ts +++ b/src/services/storage/remote.ts @@ -25,6 +25,4 @@ export async function storeDataInBackend(data: Data) { if (!response.ok) { throw new Error(`Error while sending data to storage endpoint`); } - - console.log('Data stored successfully'); } From d142da7f75a2f8d02114a9affbf507bf86ac1713 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:12:38 +0200 Subject: [PATCH 09/17] disable pattern for email TextInput --- src/components/TextInput/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TextInput/index.tsx b/src/components/TextInput/index.tsx index 58842041..df9d3620 100644 --- a/src/components/TextInput/index.tsx +++ b/src/components/TextInput/index.tsx @@ -35,7 +35,7 @@ export const TextInput = ({ spellCheck="false" placeholder={placeholder} error={error} - pattern="^(0x[a-fA-F0-9]{40})$" + pattern={type === 'email' ? undefined : '^(0x[a-fA-F0-9]{40})$'} readOnly={readOnly} disabled={disabled} autoFocus={autoFocus} From 604895d1549471c0654d9a2e1fded8283ba764b9 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:16:49 +0200 Subject: [PATCH 10/17] implement getPattern for TextInput --- src/components/TextInput/index.tsx | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/TextInput/index.tsx b/src/components/TextInput/index.tsx index df9d3620..ff796832 100644 --- a/src/components/TextInput/index.tsx +++ b/src/components/TextInput/index.tsx @@ -1,6 +1,19 @@ import { Input } from 'react-daisyui'; import { UseFormRegisterReturn } from 'react-hook-form'; +const patterns: Record = { + email: '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$', + default: '^(0x[a-fA-F0-9]{40})$', +}; + +function getPattern(textInputType?: string) { + if (textInputType && patterns[textInputType]) { + return patterns[textInputType]; + } + + return patterns.default; +} + interface NumericInputProps { register: UseFormRegisterReturn; readOnly?: boolean; @@ -35,7 +48,7 @@ export const TextInput = ({ spellCheck="false" placeholder={placeholder} error={error} - pattern={type === 'email' ? undefined : '^(0x[a-fA-F0-9]{40})$'} + pattern={getPattern(type)} readOnly={readOnly} disabled={disabled} autoFocus={autoFocus} From 4b8e0ebb945d3e338e20fb593a0370ef86eaa234 Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:17:48 +0200 Subject: [PATCH 11/17] implement storeUserEmailInBackend request --- .../storage/storeUserEmailInBackend.ts | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/services/storage/storeUserEmailInBackend.ts diff --git a/src/services/storage/storeUserEmailInBackend.ts b/src/services/storage/storeUserEmailInBackend.ts new file mode 100644 index 00000000..bc46e18e --- /dev/null +++ b/src/services/storage/storeUserEmailInBackend.ts @@ -0,0 +1,22 @@ +import { SIGNING_SERVICE_URL } from '../../constants/constants'; + +// These are the headers for the Google Spreadsheet +type Data = { + email: string; +}; + +export async function storeUserEmailInBackend(data: Data) { + const response = await fetch(`${SIGNING_SERVICE_URL}/v1/email/create`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ ...data, timestamp: new Date().toISOString() }), + }); + + if (!response.ok) { + throw new Error(`Error while sending data to email endpoint`); + } + + return await response.json(); +} From e360588b8b68b7045acf08551746a1adb2d869df Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Wed, 28 Aug 2024 22:18:28 +0200 Subject: [PATCH 12/17] implement saveUserEmail for EmailForm component --- src/components/EmailForm/index.tsx | 60 +++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/src/components/EmailForm/index.tsx b/src/components/EmailForm/index.tsx index 3fc81ef6..a622f866 100644 --- a/src/components/EmailForm/index.tsx +++ b/src/components/EmailForm/index.tsx @@ -1,18 +1,66 @@ +import { useMutation } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; +import { storeUserEmailInBackend } from '../../services/storage/storeUserEmailInBackend'; import { TextInput } from '../../components/TextInput'; +async function saveUserEmail(email: string) { + return await storeUserEmailInBackend({ email }); +} + +// Implement tanstack query export const EmailForm = () => { - const { register } = useForm(); + const { register, handleSubmit } = useForm(); + + const { + mutate: saveUserEmailMutation, + isPending, + isSuccess, + isError, + } = useMutation({ + mutationFn: saveUserEmail, + }); + + const onSubmit = handleSubmit((data) => { + saveUserEmailMutation(data.email); + }); + + function getFormButtonSection() { + if (isSuccess) { + return ( +
Successfully saved!
+ ); + } + + if (isPending) { + return
Loading...
; + } + + return ( + <> +
+
+ +
+ +
+ {isError && ( +

+ Error while saving your email. Please try again. +

+ )} + + ); + } return ( -
+

To receive further assistance and information about our app,

please provide your email address below:

-
- -
-
+ {getFormButtonSection()} + ); }; From 057cbd7c57ac074180adf060aa81b7e554a8ebce Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Fri, 30 Aug 2024 16:56:07 +0200 Subject: [PATCH 13/17] simplify EmailForm --- src/components/EmailForm/index.tsx | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/components/EmailForm/index.tsx b/src/components/EmailForm/index.tsx index a622f866..1bedf5b5 100644 --- a/src/components/EmailForm/index.tsx +++ b/src/components/EmailForm/index.tsx @@ -3,11 +3,6 @@ import { useForm } from 'react-hook-form'; import { storeUserEmailInBackend } from '../../services/storage/storeUserEmailInBackend'; import { TextInput } from '../../components/TextInput'; -async function saveUserEmail(email: string) { - return await storeUserEmailInBackend({ email }); -} - -// Implement tanstack query export const EmailForm = () => { const { register, handleSubmit } = useForm(); @@ -17,14 +12,14 @@ export const EmailForm = () => { isSuccess, isError, } = useMutation({ - mutationFn: saveUserEmail, + mutationFn: storeUserEmailInBackend, }); const onSubmit = handleSubmit((data) => { - saveUserEmailMutation(data.email); + saveUserEmailMutation({ email: data.email }); }); - function getFormButtonSection() { + const FormButtonSection = () => { if (isSuccess) { return (
Successfully saved!
@@ -52,7 +47,7 @@ export const EmailForm = () => { )} ); - } + }; return (
@@ -60,7 +55,7 @@ export const EmailForm = () => { To receive further assistance and information about our app,

please provide your email address below:

- {getFormButtonSection()} + ); }; From a46d21ddcb97ef9ffdb47a24adbb442abaf791bf Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Fri, 30 Aug 2024 18:01:51 +0200 Subject: [PATCH 14/17] unify parameters case googleSpreadsheet.controller --- .../src/api/controllers/googleSpreadSheet.controller.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/signer-service/src/api/controllers/googleSpreadSheet.controller.js b/signer-service/src/api/controllers/googleSpreadSheet.controller.js index 45465e4a..520a990e 100644 --- a/signer-service/src/api/controllers/googleSpreadSheet.controller.js +++ b/signer-service/src/api/controllers/googleSpreadSheet.controller.js @@ -4,13 +4,13 @@ const { spreadsheet } = require('../../config/vars'); const { initGoogleSpreadsheet, getOrCreateSheet, appendData } = require('../services/spreadsheet.service'); -exports.storeDataInGoogleSpreadsheet = async (req, res, spreadsheetId, SHEET_HEADER_VALUES) => { +exports.storeDataInGoogleSpreadsheet = async (req, res, spreadsheetId, sheetHeaderValues) => { try { // We expect the data to be an object that matches our schema const data = req.body; // Try dumping transactions to spreadsheet - const sheet = await initGoogleSpreadsheet(spreadsheetId, spreadsheet.googleCredentials).then((doc) => getOrCreateSheet(doc, SHEET_HEADER_VALUES)); + const sheet = await initGoogleSpreadsheet(spreadsheetId, spreadsheet.googleCredentials).then((doc) => getOrCreateSheet(doc, sheetHeaderValues)); if (sheet) { console.log('Appending data to sheet'); From f34bf3ab1fda71dd87856e1917c9446023d839eb Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Fri, 30 Aug 2024 18:03:24 +0200 Subject: [PATCH 15/17] rename DUMP_SHEET_HEADER_VALUES storage.controller --- signer-service/src/api/controllers/storage.controller.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/signer-service/src/api/controllers/storage.controller.js b/signer-service/src/api/controllers/storage.controller.js index 55113473..c859dbf1 100644 --- a/signer-service/src/api/controllers/storage.controller.js +++ b/signer-service/src/api/controllers/storage.controller.js @@ -2,7 +2,7 @@ const { spreadsheet } = require('../../config/vars'); const { storeDataInGoogleSpreadsheet } = require('./googleSpreadsheet.controller'); // These are the headers for the Google Spreadsheet -const SHEET_HEADER_VALUES = [ +const DUMP_SHEET_HEADER_VALUES = [ 'timestamp', 'polygonAddress', 'stellarEphemeralPublicKey', @@ -14,7 +14,7 @@ const SHEET_HEADER_VALUES = [ 'stellarCleanupTx', ]; -exports.SHEET_HEADER_VALUES = SHEET_HEADER_VALUES; +exports.DUMP_SHEET_HEADER_VALUES = DUMP_SHEET_HEADER_VALUES; -exports.storeData = async (req, res) => storeDataInGoogleSpreadsheet(req, res, spreadsheet.storageSheetId, SHEET_HEADER_VALUES) +exports.storeData = async (req, res) => storeDataInGoogleSpreadsheet(req, res, spreadsheet.storageSheetId, DUMP_SHEET_HEADER_VALUES) From f997257bbdeecf2dedf2331c17d3215070cf221d Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Fri, 30 Aug 2024 18:04:32 +0200 Subject: [PATCH 16/17] improve api comments --- signer-service/src/api/middlewares/validators.js | 4 ++-- signer-service/src/api/routes/v1/index.js | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/signer-service/src/api/middlewares/validators.js b/signer-service/src/api/middlewares/validators.js index 71b7f650..ee5dfdba 100644 --- a/signer-service/src/api/middlewares/validators.js +++ b/signer-service/src/api/middlewares/validators.js @@ -1,5 +1,5 @@ const { TOKEN_CONFIG } = require('../../constants/tokenConfig'); -const { SHEET_HEADER_VALUES } = require('../controllers/storage.controller'); +const { DUMP_SHEET_HEADER_VALUES } = require('../controllers/storage.controller'); const { EMAIL_SHEET_HEADER_VALUES } = require('../controllers/email.controller'); const validateCreationInput = (req, res, next) => { @@ -47,7 +47,7 @@ const validateInputHeaderValues = (requiredHeaders) => (req, res, next) => { next(); }; -const validateStorageInput = validateInputHeaderValues(SHEET_HEADER_VALUES); +const validateStorageInput = validateInputHeaderValues(DUMP_SHEET_HEADER_VALUES); const validateEmailInput = validateInputHeaderValues(EMAIL_SHEET_HEADER_VALUES); const validatePreSwapSubsidizationInput = (req, res, next) => { diff --git a/signer-service/src/api/routes/v1/index.js b/signer-service/src/api/routes/v1/index.js index d763f854..67dfe5f6 100644 --- a/signer-service/src/api/routes/v1/index.js +++ b/signer-service/src/api/routes/v1/index.js @@ -34,14 +34,27 @@ router.get('/status', sendStatusWithPk); * POST v1/stellar */ router.use('/stellar', stellarRoutes); + + +/** + * POST v1/pendulum + */ router.use('/pendulum', pendulumRoutes); /** * POST v1/storage */ router.use('/storage', storageRoutes); + +/** + * POST v1/email + */ router.use('/email', emailRoutes); + +/** + * POST v1/subsidize + */ router.use('/subsidize', subsidizeRoutes); module.exports = router; From 6c61324b577f569ca3cd5a25cafd9face5c0c68b Mon Sep 17 00:00:00 2001 From: Kacper Szarkiewicz Date: Fri, 30 Aug 2024 18:13:27 +0200 Subject: [PATCH 17/17] unify remote.ts, add transactionId to storeUserEmail --- .../src/api/controllers/email.controller.js | 3 +- src/components/EmailForm/index.tsx | 15 ++++++++-- src/pages/failure/index.tsx | 2 +- src/pages/success/index.tsx | 2 +- src/services/storage/remote.ts | 28 +++++++++++++++---- .../storage/storeUserEmailInBackend.ts | 22 --------------- 6 files changed, 39 insertions(+), 33 deletions(-) delete mode 100644 src/services/storage/storeUserEmailInBackend.ts diff --git a/signer-service/src/api/controllers/email.controller.js b/signer-service/src/api/controllers/email.controller.js index 45f9f7a6..3d0dd6d6 100644 --- a/signer-service/src/api/controllers/email.controller.js +++ b/signer-service/src/api/controllers/email.controller.js @@ -4,7 +4,8 @@ const { storeDataInGoogleSpreadsheet } = require('./googleSpreadsheet.controller // These are the headers for the Google Spreadsheet const EMAIL_SHEET_HEADER_VALUES = [ 'timestamp', - 'email' + 'email', + 'transactionId' ]; exports.EMAIL_SHEET_HEADER_VALUES = EMAIL_SHEET_HEADER_VALUES; diff --git a/src/components/EmailForm/index.tsx b/src/components/EmailForm/index.tsx index 1bedf5b5..06c6a4d9 100644 --- a/src/components/EmailForm/index.tsx +++ b/src/components/EmailForm/index.tsx @@ -1,9 +1,13 @@ import { useMutation } from '@tanstack/react-query'; import { useForm } from 'react-hook-form'; -import { storeUserEmailInBackend } from '../../services/storage/storeUserEmailInBackend'; +import { storeUserEmailInBackend } from '../../services/storage/remote'; import { TextInput } from '../../components/TextInput'; -export const EmailForm = () => { +interface EmailFormProps { + transactionId?: string; +} + +export const EmailForm = ({ transactionId }: EmailFormProps) => { const { register, handleSubmit } = useForm(); const { @@ -16,7 +20,12 @@ export const EmailForm = () => { }); const onSubmit = handleSubmit((data) => { - saveUserEmailMutation({ email: data.email }); + if (!transactionId) { + console.error('Transaction ID is missing'); + return; + } + + saveUserEmailMutation({ email: data.email, transactionId }); }); const FormButtonSection = () => { diff --git a/src/pages/failure/index.tsx b/src/pages/failure/index.tsx index 0c6bc266..4eb07043 100644 --- a/src/pages/failure/index.tsx +++ b/src/pages/failure/index.tsx @@ -30,7 +30,7 @@ export const FailurePage = ({ finishOfframping, transactionId }: FailurePageProp

If you continue to experience issues, contact support on:

- + diff --git a/src/pages/success/index.tsx b/src/pages/success/index.tsx index e1d9298b..ba761923 100644 --- a/src/pages/success/index.tsx +++ b/src/pages/success/index.tsx @@ -29,7 +29,7 @@ export const SuccessPage = ({ finishOfframping, transactionId }: SuccessPageProp If your transaction is not completed after 60 minutes please contact support on:

- + diff --git a/src/services/storage/remote.ts b/src/services/storage/remote.ts index 7150daf1..4aa7aecb 100644 --- a/src/services/storage/remote.ts +++ b/src/services/storage/remote.ts @@ -1,7 +1,7 @@ import { SIGNING_SERVICE_URL } from '../../constants/constants'; // These are the headers for the Google Spreadsheet -type Data = { +interface DumpData { timestamp: string; polygonAddress: string; stellarEphemeralPublicKey: string; @@ -11,10 +11,15 @@ type Data = { spacewalkRedeemTx: string; stellarOfframpTx: string; stellarCleanupTx: string; -}; +} + +interface EmailData { + email: string; + transactionId: string; +} -export async function storeDataInBackend(data: Data) { - const response = await fetch(`${SIGNING_SERVICE_URL}/v1/storage/create`, { +async function sendRequestToBackend(endpoint: string, data: EmailData | DumpData) { + const response = await fetch(endpoint, { method: 'POST', headers: { 'Content-Type': 'application/json', @@ -23,6 +28,19 @@ export async function storeDataInBackend(data: Data) { }); if (!response.ok) { - throw new Error(`Error while sending data to storage endpoint`); + throw new Error(`Error while sending data to ${endpoint}`); } + + return await response.json(); +} + +export async function storeDataInBackend(data: DumpData) { + const endpoint = `${SIGNING_SERVICE_URL}/v1/storage/create`; + return await sendRequestToBackend(endpoint, data); +} + +export async function storeUserEmailInBackend(data: EmailData) { + const endpoint = `${SIGNING_SERVICE_URL}/v1/email/create`; + const payload = { ...data, timestamp: new Date().toISOString() }; + return await sendRequestToBackend(endpoint, payload); } diff --git a/src/services/storage/storeUserEmailInBackend.ts b/src/services/storage/storeUserEmailInBackend.ts deleted file mode 100644 index bc46e18e..00000000 --- a/src/services/storage/storeUserEmailInBackend.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { SIGNING_SERVICE_URL } from '../../constants/constants'; - -// These are the headers for the Google Spreadsheet -type Data = { - email: string; -}; - -export async function storeUserEmailInBackend(data: Data) { - const response = await fetch(`${SIGNING_SERVICE_URL}/v1/email/create`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ ...data, timestamp: new Date().toISOString() }), - }); - - if (!response.ok) { - throw new Error(`Error while sending data to email endpoint`); - } - - return await response.json(); -}