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

[DRAFT] Migrate signer-service to Typescript #352

Open
wants to merge 35 commits into
base: polygon-prototype-staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
b602482
add typescript @types and swc
Sharqiewicz Jan 6, 2025
57ca30e
add tsconfig.json
Sharqiewicz Jan 6, 2025
7b213eb
add .swcrc
Sharqiewicz Jan 6, 2025
6d57274
migrate index.ts
Sharqiewicz Jan 6, 2025
95886f8
migrate tokenConfig
Sharqiewicz Jan 6, 2025
d502b32
migrate constants.ts
Sharqiewicz Jan 6, 2025
9c9a50e
migrate express.ts
Sharqiewicz Jan 6, 2025
70e0117
migrate vars
Sharqiewicz Jan 6, 2025
acc515a
migrate logger.ts
Sharqiewicz Jan 6, 2025
25322f3
migrate alchemypay
Sharqiewicz Jan 6, 2025
b4f7965
migrate pendulum service and moonpay service
Sharqiewicz Jan 7, 2025
6ddf848
migrate sep10
Sharqiewicz Jan 8, 2025
b9a8769
migrate siwe
Sharqiewicz Jan 8, 2025
7ee59ba
migrate slack
Sharqiewicz Jan 8, 2025
ea26b5c
migrate spreadsheet
Sharqiewicz Jan 8, 2025
5789b0e
migrate transak
Sharqiewicz Jan 8, 2025
95f8380
migrate stellar
Sharqiewicz Jan 8, 2025
55e338f
migrate anchors
Sharqiewicz Jan 8, 2025
e3f1255
migrate memoDerivation
Sharqiewicz Jan 8, 2025
fe9adc2
migrate siweMessageFormatter
Sharqiewicz Jan 8, 2025
438e8a4
fix siwe service
Sharqiewicz Jan 8, 2025
c3e2b8a
migrate api-error
Sharqiewicz Jan 8, 2025
c68f9ec
migrate extendable-error
Sharqiewicz Jan 8, 2025
3be486d
migrate googleSpreadSheet controller
Sharqiewicz Jan 8, 2025
38f5b03
fix type mismatch googleSpreadSheet
Sharqiewicz Jan 8, 2025
a419963
migrate moonbeam
Sharqiewicz Jan 8, 2025
f357687
migrate pendulum controller
Sharqiewicz Jan 8, 2025
a11f768
migrate quote controller
Sharqiewicz Jan 8, 2025
264269f
migrate rating
Sharqiewicz Jan 8, 2025
8ba7c6f
migrate siwe controller
Sharqiewicz Jan 8, 2025
f7383ae
migrate stellar and storage controllers
Sharqiewicz Jan 9, 2025
7317f64
migrate subsidize controller
Sharqiewicz Jan 9, 2025
ec51c30
migrate auth middleware
Sharqiewicz Jan 9, 2025
b7fb742
migrate error middleware
Sharqiewicz Jan 9, 2025
3312175
migrate validators middleware
Sharqiewicz Jan 9, 2025
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
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"react-router-dom": "^6.8.1",
"react-toastify": "^10.0.6",
"stellar-base": "^11.0.1",
"stellar-sdk": "^11.3.0",
"stellar-sdk": "^13.1.0",
"tailwind": "^4.0.0",
"tailwindcss": "^3.4.3",
"viem": "^2.21.43",
Expand Down
12 changes: 12 additions & 0 deletions signer-service/.swcrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"jsc": {
"parser": {
"syntax": "typescript",
"tsx": false
},
"target": "es2020"
},
"module": {
"type": "commonjs"
}
}
24 changes: 19 additions & 5 deletions signer-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
"yarn": "*"
},
"scripts": {
"precommit": "yarn lint-staged && yarn lint",
"start": "node ./src/index.js",
"dev": "nodemon ./src/index.js",
"type-check": "tsc --noEmit",
"lint-staged": "prettier --write --ignore-unknown",
"lint": "eslint ./src/ --ignore-path .gitignore --ignore-pattern internals/scripts",
"lint:fix": "yarn lint --fix",
"lint:watch": "yarn lint --watch",
"precommit": "yarn lint-staged && yarn lint",
"start": "node ./dist/index.js",
"dev": "nodemon --watch ./src/index.ts --exec 'yarn build && yarn start'",
"build": "yarn type-check && swc src --out-dir dist --copy-files",
"test": "vitest",
"validate": "yarn lint && yarn test",
"postpublish": "git push --tags"
Expand All @@ -43,19 +45,31 @@
"mongoose": "^5.2.17",
"morgan": "^1.8.1",
"siwe": "^2.3.2",
"stellar-sdk": "^11.3.0",
"stellar-sdk": "^13.1.0",
"viem": "^2.21.3",
"winston": "^3.1.0"
},
"devDependencies": {
"@pendulum-chain/types": "^1.1.1",
"@stellar/stellar-sdk": "^13.1.0",
"@swc/cli": "^0.5.2",
"@swc/core": "^1.10.4",
"@types/body-parser": "^1.19.5",
"@types/compression": "^1.7.5",
"@types/cookie-parser": "^1.4.8",
"@types/cors": "^2.8.17",
"@types/express": "^5.0.0",
"@types/method-override": "^3.0.0",
"@types/morgan": "^1.9.9",
"eslint": "^7.29.0",
"eslint-config-airbnb-base": "^14.2.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-import": "^2.2.0",
"husky": "^3.0.7",
"mocha": "^6.2.2",
"nodemon": "^2.0.1",
"prettier": "^2.8.7"
"prettier": "^2.8.7",
"typescript": "^5.7.2"
},
"packageManager": "yarn@4.4.1"
}
10 changes: 0 additions & 10 deletions signer-service/src/api/controllers/email.controller.js

This file was deleted.

26 changes: 26 additions & 0 deletions signer-service/src/api/controllers/email.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Request, Response } from 'express';
import { config } from '../../config/vars';
import { storeDataInGoogleSpreadsheet } from './googleSpreadSheet.controller';

const { spreadsheet } = config;

const enum EmailSheetHeaders {
Timestamp = 'timestamp',
Email = 'email',
TransactionId = 'transactionId',
}

const EMAIL_SHEET_HEADER_VALUES = [
EmailSheetHeaders.Timestamp,
EmailSheetHeaders.Email,
EmailSheetHeaders.TransactionId,
];

export { EMAIL_SHEET_HEADER_VALUES };

export const storeEmail = async (req: Request, res: Response): Promise<void> => {
if (!spreadsheet.emailSheetId) {
throw new Error('Email sheet ID is not configured');
}
await storeDataInGoogleSpreadsheet(req, res, spreadsheet.emailSheetId, EMAIL_SHEET_HEADER_VALUES);
};
28 changes: 0 additions & 28 deletions signer-service/src/api/controllers/googleSpreadSheet.controller.js

This file was deleted.

54 changes: 54 additions & 0 deletions signer-service/src/api/controllers/googleSpreadSheet.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import 'dotenv/config';
import { Request, Response } from 'express';
import { config } from '../../config/vars';
import { initGoogleSpreadsheet, getOrCreateSheet, appendData } from '../services/spreadsheet.service';
import { APIError } from '../errors/api-error';
import { GoogleCredentials } from '../services/spreadsheet.service';

type SheetHeaderValues = readonly string[];

interface SpreadsheetResponse {
message: string;
}

interface SpreadsheetErrorResponse {
error: string;
details?: string;
}

export async function storeDataInGoogleSpreadsheet(
req: Request,
res: Response,
spreadsheetId: string,
sheetHeaderValues: SheetHeaderValues,
): Promise<Response<SpreadsheetResponse | SpreadsheetErrorResponse>> {
try {
// Ensure credentials are fully defined
const credentials: GoogleCredentials = {
email: config.spreadsheet.googleCredentials.email ?? '',
key: config.spreadsheet.googleCredentials.key ?? '',
};

const sheet = await initGoogleSpreadsheet(spreadsheetId, credentials).then((doc) =>
getOrCreateSheet(doc, [...sheetHeaderValues]),
);

if (!sheet) {
throw new APIError({
message: 'Failed to store data. Sheet unavailable.',
status: 500,
isPublic: true,
});
}

await appendData(sheet, req.body);
return res.status(200).json({ message: 'Data stored successfully' });
} catch (error) {
console.error('Error in storeData:', error);
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
return res.status(500).json({
error: 'Failed to store data',
details: errorMessage,
});
}
}
85 changes: 0 additions & 85 deletions signer-service/src/api/controllers/moonbeam.controller.js

This file was deleted.

103 changes: 103 additions & 0 deletions signer-service/src/api/controllers/moonbeam.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { createWalletClient, createPublicClient, http, encodeFunctionData, Hash, Address } from 'viem';
import { moonbeam } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';
import Big from 'big.js';
import { Request, Response } from 'express';

import {
MOONBEAM_EXECUTOR_PRIVATE_KEY,
MOONBEAM_RECEIVER_CONTRACT_ADDRESS,
MOONBEAM_FUNDING_AMOUNT_UNITS,
} from '../../constants/constants';
import { SlackNotifier } from '../services/slack.service';
// @ts-ignore
import splitReceiverABI from '../../../../mooncontracts/splitReceiverABI.json';

interface XcmPayload {
id: string;
payload: string;
}

interface StatusResponse {
status: boolean;
public: Address | undefined;
}

const createClients = (executorAccount: ReturnType<typeof privateKeyToAccount>) => {
const walletClient = createWalletClient({
account: executorAccount,
chain: moonbeam,
transport: http(),
});

const publicClient = createPublicClient({
chain: moonbeam,
transport: http(),
});

return { walletClient, publicClient };
};

export const executeXcmController = async (req: Request<{}, {}, XcmPayload>, res: Response) => {
const { id, payload } = req.body;

try {
if (!MOONBEAM_EXECUTOR_PRIVATE_KEY) {
throw new Error('Moonbeam executor private key not configured');
}
const moonbeamExecutorAccount = privateKeyToAccount(MOONBEAM_EXECUTOR_PRIVATE_KEY as `0x${string}`);
const { walletClient, publicClient } = createClients(moonbeamExecutorAccount);

const data = encodeFunctionData({
abi: splitReceiverABI,
functionName: 'executeXCM',
args: [id, payload],
});

try {
const { maxFeePerGas, maxPriorityFeePerGas } = await publicClient.estimateFeesPerGas();
const hash = await walletClient.sendTransaction({
to: MOONBEAM_RECEIVER_CONTRACT_ADDRESS,
value: 0n,
data,
maxFeePerGas,
maxPriorityFeePerGas,
});
return res.json({ hash });
} catch (error) {
console.error('Error executing XCM:', error);
return res.status(400).json({ error: 'Invalid transaction' });
}
} catch (error) {
console.error('Error executing XCM:', error);
return res.status(500).json({ error: 'Internal Server Error' });
}
};

export const sendStatusWithPk = async (): Promise<StatusResponse> => {
const slackService = new SlackNotifier();
let moonbeamExecutorAccount;

try {
if (!MOONBEAM_EXECUTOR_PRIVATE_KEY) {
throw new Error('Moonbeam executor private key not configured');
}
moonbeamExecutorAccount = privateKeyToAccount(MOONBEAM_EXECUTOR_PRIVATE_KEY as `0x${string}`);
const { publicClient } = createClients(moonbeamExecutorAccount);

const balance = await publicClient.getBalance({ address: moonbeamExecutorAccount.address });
const minimumBalance = BigInt(Big(MOONBEAM_FUNDING_AMOUNT_UNITS).times(Big(10).pow(18)).toString());

if (balance < minimumBalance) {
await slackService.sendMessage({
text: `Current balance of funding account is ${balance} GLMR please charge the account ${moonbeamExecutorAccount.address}.`,
});
return { status: false, public: moonbeamExecutorAccount.address };
}

return { status: true, public: moonbeamExecutorAccount.address };
} catch (error) {
console.error('Error fetching Moonbeam executor balance:', error);
return { status: false, public: moonbeamExecutorAccount?.address };
}
};
Loading