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

[READY] Migrate signer-service to Typescript #352

Open
wants to merge 59 commits into
base: staging
Choose a base branch
from

Conversation

Sharqiewicz
Copy link
Contributor

@Sharqiewicz Sharqiewicz commented Jan 6, 2025

PR 🦈🟢


  • Migrate all files in signer-service to Typescript
  • Configure SWC ( TS Compiler )
  • Configure commands:
  • yarn build Compiles TypeScript code into JavaScript using the fast SWC compiler
  • yarn start Runs the compiled application
  • yarn build:start Compiles and then immediately runs the application (When you want to test production)
  • yarn dev Runs the application in development mode with automatic reloading on code changes

How to review

There are only two new files .swcrc and tsconfig.json they are short and consistent.
The challenge with the review is going through every migrated file. I tried to keep the logic the same, but sometimes there were a lot of TypeScript errors, so I had to make changes to the files.

@Sharqiewicz Sharqiewicz linked an issue Jan 6, 2025 that may be closed by this pull request
Copy link

netlify bot commented Jan 6, 2025

Deploy Preview for pendulum-pay ready!

Name Link
🔨 Latest commit 98a669d
🔍 Latest deploy log https://app.netlify.com/sites/pendulum-pay/deploys/67ac972484295900083e4bbb
😎 Deploy Preview https://deploy-preview-352--pendulum-pay.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

const { id, payload } = req.body;

try {
if (!MOONBEAM_EXECUTOR_PRIVATE_KEY) {
Copy link
Contributor

@gianfra-t gianfra-t Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already check for this variable (and any required one) on index.ts, using validateRequiredEnvVars, when the service starts.

Because we should never reach this function without the variable because the process will break in the middle.

toFiat: FiatCurrency,
amount: string,
network?: string,
) => Promise<unknown>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could provide type AnyQuote = AlchemyPayQuote | MoonpayQuote | QuoteResult; wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good catch!

export const getQuoteForProvider = async (req: Request, res: Response, next: NextFunction) => {
const { provider, fromCrypto, toFiat, amount, network } = req.query;

if (!provider || typeof provider !== 'string') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks are also in the validators, but I guess we need them for the typing 🤔.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we need it for TS

import { createAndSendNonce, verifyAndStoreSiweMessage } from '../services/siwe.service';
import { DEFAULT_LOGIN_EXPIRATION_TIME_HOURS } from '../../constants/constants';

interface SiweRequestBody {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we are not using this interface.

type HashValue = `0x${string}` | Uint8Array;

/**
* Returns the hash value for the address.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the previous comment was off. And the name of the function itself. It is returning the raw data/ decoded value of the address actually, not the hash.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, very good suggestion

Copy link
Contributor

@gianfra-t gianfra-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this refactor @Sharqiewicz ! I only left mostly type and preference related comments.
The one I think we may need to change is this one. The way it is right now it can work, but it will always pick up the first cookie, which may or may not match with the address the user wants to use (substrate or evm). The previous for loop may be required.

Copy link
Contributor

@gianfra-t gianfra-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Never mind my last comment, only small comments!

Copy link
Member

@ebma ebma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for going through this tedious process @Sharqiewicz 👌 Looks good overall, I just found a few things we might want to improve.

Some remarks:

  • IIRC our deployment currently assumes that yarn start is enough to run the signer-service. If we now split it up into yarn build and yarn start, we'll have to touch the deployment instructions of the service or it won't start. This is an important consideration before we merge this. Either we a) combine building and running in yarn start or b) change the deployment steps. b) is favorable IMO.
  • The linting seems to be broken. yarn lint finds lots of issues that doesn't seem like issues to me. Maybe we need to change the config files.

"license": "MIT",
"engines": {
"node": ">=12",
"yarn": "*"
},
"scripts": {
"precommit": "yarn lint-staged && yarn lint",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should keep the precommit script so that the code formatting is consistent.

Comment on lines 27 to 30
const credentials: GoogleCredentials = {
email: config.spreadsheet.googleCredentials.email ?? '',
key: config.spreadsheet.googleCredentials.key ?? '',
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have multiple defintions for the type GoogleCredentials, one with string | undefined and one with string. I think it makes more sense to keep the interface string | undefined and don't do the ?? '' check here. initGoogleSpreadsheet() checks if the values are undefined anyway.


const PENDULUM_FUNDING_SEED = process.env.PENDULUM_FUNDING_SEED;
const FUNDING_SECRET = process.env.FUNDING_SECRET;
const MOONBEAM_EXECUTOR_PRIVATE_KEY = process.env.MOONBEAM_EXECUTOR_PRIVATE_KEY;
const SEP10_MASTER_SECRET = FUNDING_SECRET;
const CLIENT_DOMAIN_SECRET = process.env.CLIENT_DOMAIN_SECRET;

module.exports = {
export {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we group all constants in an object const constants = { ... } and export only that object? Makes importing all these constants easier, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we import all of them anywhere. If we need to import all of them, we can simply use import * as constants from 'constants'

};

export const executeXcmController = async (req: Request, res: Response): Promise<void> => {
const { id, payload } = req.body;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We could also define the types for the body like you did for other controller functions.

Comment on lines 13 to 15
import { sendStatusWithPk as sendStellarStatusWithPk } from '../../services/stellar.service';
import { sendStatusWithPk as sendPendulumStatusWithPk } from '../../services/pendulum/pendulum.service';
import { sendStatusWithPk as sendMoonbeamStatusWithPk } from '../../controllers/moonbeam.controller';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This is not consistent. Sometimes it's using a function from a *.service or form a *.controller. There even is a function sendStatusWithPkControlller in pendulum.controller which is never used.

Comment on lines 82 to 83
const validateQuoteInput: RequestHandler = (req, res, next) => {
const { provider, fromCrypto, toFiat, amount, network } = req.query as unknown as QuoteQuery;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't we define all of these types directly on the RequestHandler instead of casting?

Suggested change
const validateQuoteInput: RequestHandler = (req, res, next) => {
const { provider, fromCrypto, toFiat, amount, network } = req.query as unknown as QuoteQuery;
const validateQuoteInput: RequestHandler<_,_,QuoteQuery> = (req, res, next) => {
const { provider, fromCrypto, toFiat, amount, network } = req.query as unknown as QuoteQuery;

Comment on lines 287 to 300
export {
validateChangeOpInput,
validateQuoteInput,
validateCreationInput,
validatePreSwapSubsidizationInput,
validatePostSwapSubsidizationInput,
validateStorageInput,
validateEmailInput,
validateRatingInput,
validateExecuteXCM,
validateSep10Input,
validateSiweCreate,
validateSiweValidate,
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be better to just add the export keyword to each function instead of exporting them in a batch.

import { executeXcmController } from '../../controllers/moonbeam.controller';
import { validateExecuteXCM } from '../../middlewares/validators';

const router: Router = Router({ mergeParams: true });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't define mergeParams: true here before. Could lead to issues if we are not careful.

import { Router } from 'express';
import { fundEphemeralAccountController } from '../../controllers/pendulum.controller';

const router: Router = Router({ mergeParams: true });
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mergeParams also wasn't defined here before.

};

module.exports = { verifySiweMessage, verifyAndStoreSiweMessage, createAndSendNonce, validateSignatureAndGetMemo };
export { verifySiweMessage, verifyAndStoreSiweMessage, createAndSendNonce, validateSignatureAndGetMemo };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe also remove the batched export. What's your general opinion on this @Sharqiewicz?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I also don't like batched exports

@Sharqiewicz Sharqiewicz changed the base branch from polygon-prototype-staging to staging February 7, 2025 13:46
@Sharqiewicz
Copy link
Contributor Author

@ebma
I changed the commands to:

    "build": "swc src -d dist --strip-leading-paths",
    "serve": "node dist/index.js",
    "start": "yarn build && yarn serve"

so yarn start is enough for the deployment

}
};

export const sendStatusWithPkController = async (_req: Request, res: Response, _next: NextFunction) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we're not using this fn anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch @gianfra-t

Copy link
Contributor

@gianfra-t gianfra-t left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for addressing the comments @Sharqiewicz !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch to TypeScript in signer service
3 participants