Skip to content

[BWS] Cleanup email service #3868

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

Merged
merged 17 commits into from
Apr 16, 2025
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
98 changes: 53 additions & 45 deletions packages/bitcore-wallet-service/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,49 @@ const Config = (): any => {
maintenanceOpts: {
maintenanceMode: false
},
emailOpts: {
mailer: 'sendgrid', // Valid options: sendgrid, nodemailer, mailersend
sendGridApiKey: process.env.SENDGRID_API_KEY, // Override in bws.config.js or set the env var
mailerSendApiKey: process.env.MAILERSEND_API_KEY, // Override in bws.config.js or set the env var
from: 'override me in bws.config.js',

// // nodemailer config
// host: 'localhost',
// port: 25,
// ignoreTLS: true,
// subjectPrefix: '[Wallet Service]',
// from: '[email protected]',
// // Note: Prod templates are in a the copay-emails repo (https://github.com/bitpay/copay-emails)
// templatePath: 'templates',
// defaultLanguage: 'en',
// defaultUnit: 'btc',
// publicTxUrlTemplate: {
// btc: {
// livenet: 'https://bitpay.com/insight/#/BTC/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/BTC/testnet/tx/{{txid}}',
// },
// bch: {
// livenet: 'https://bitpay.com/insight/#/BCH/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/BCH/testnet/tx/{{txid}}',
// },
// eth: {
// livenet: 'https://etherscan.io/tx/{{txid}}',
// testnet: 'https://kovan.etherscan.io/tx/{{txid}}',
// },
// xrp: {
// livenet: 'https://xrpscan.com/tx/{{txid}}',
// testnet: 'https://test.bithomp.com/explorer//tx/{{txid}}',
// },
// doge: {
// livenet: 'https://blockchair.com/dogecoin/transaction/{{txid}}',
// testnet: 'https://sochain.com/tx/DOGETEST/{{txid}}',
// },
// ltc: {
// livenet: 'https://bitpay.com/insight/#/LTC/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/LTC/testnet/tx/{{txid}}',
// }
// }
},
services: {
buyCrypto: {
disabled: false,
Expand Down Expand Up @@ -418,51 +461,6 @@ const Config = (): any => {
// apiKey: 'moralis_api_key_here',
// whitelist: []
// },
// To use email notifications uncomment this:
// emailOpts: {
// host: 'localhost',
// port: 25,
// ignoreTLS: true,
// subjectPrefix: '[Wallet Service]',
// from: '[email protected]',
// // Note: Prod templates are in a the copay-emails repo (https://github.com/bitpay/copay-emails)
// templatePath: 'templates',
// defaultLanguage: 'en',
// defaultUnit: 'btc',
// publicTxUrlTemplate: {
// btc: {
// livenet: 'https://bitpay.com/insight/#/BTC/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/BTC/testnet/tx/{{txid}}',
// },
// bch: {
// livenet: 'https://bitpay.com/insight/#/BCH/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/BCH/testnet/tx/{{txid}}',
// },
// eth: {
// livenet: 'https://etherscan.io/tx/{{txid}}',
// testnet: 'https://kovan.etherscan.io/tx/{{txid}}',
// },
// xrp: {
// livenet: 'https://xrpscan.com/tx/{{txid}}',
// testnet: 'https://test.bithomp.com/explorer//tx/{{txid}}',
// },
// doge: {
// livenet: 'https://blockchair.com/dogecoin/transaction/{{txid}}',
// testnet: 'https://sochain.com/tx/DOGETEST/{{txid}}',
// },
// ltc: {
// livenet: 'https://bitpay.com/insight/#/LTC/mainnet/tx/{{txid}}',
// testnet: 'https://bitpay.com/insight/#/LTC/testnet/tx/{{txid}}',
// }
// },
// },
// To use sendgrid:
// const sgMail = require('@sendgrid/mail');
// sgMail.setApiKey(process.env.SENDGRID_API_KEY);
//
//
// //then add:
// mailer: sgMail,
};

// Override default values with bws.config.js' values, if present
Expand All @@ -472,6 +470,16 @@ const Config = (): any => {
} catch {
logger.info('bws.config.js not found, using default configuration values');
}

if (process.env.SENDGRID_API_KEY) {
// override the config value in bws.config.js with env var
defaultConfig.emailOpts.sendGridApiKey = process.env.SENDGRID_API_KEY;
}
if (process.env.MAILERSEND_API_KEY) {
// override the config value in bws.config.js with env var
defaultConfig.emailOpts.mailerSendApiKey = process.env.MAILERSEND_API_KEY;
}

return defaultConfig;
};

Expand Down
4 changes: 2 additions & 2 deletions packages/bitcore-wallet-service/src/lib/blockchainmonitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ export class BlockchainMonitor {
next(null, notification);
});
},
(notification, next) => {
(notification: Notification, next) => {
this._storeAndBroadcastNotification(notification, next);
}
],
Expand Down Expand Up @@ -400,7 +400,7 @@ export class BlockchainMonitor {
}
}

_storeAndBroadcastNotification(notification, cb?: () => void) {
_storeAndBroadcastNotification(notification: Notification, cb?: () => void) {
this.storage.storeNotification(notification.walletId, notification, () => {
this.messageBroker.send(notification);
if (cb) return cb();
Expand Down
24 changes: 24 additions & 0 deletions packages/bitcore-wallet-service/src/lib/common/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -395,5 +395,29 @@ export const Utils = {

sortDesc(arr, ...keys) {
return Utils.sortAsc(arr, ...keys).reverse();
},

/**
* Takes an array of array-pairs and converts them to key-value map
* @param {Array<Array<any, any>>} input e.g. [[a, 1], [b, 2]]
* @returns {Object} e.g. { a: 1, b: 2 }
*/
fromPairs(input) {
return input.reduce((map, [k, v]) => {
map[k] = v;
return map;
}, {});
},

/**
* Returns the elements of arr1 that are NOT in arr2
* @param {Array<any>} arr1 Elements to filter
* @param {Array<any>} [arr2] Elements to remove from arr1 if they exist. If not provided, returns a copy of arr1.
* @returns
*/
difference(arr1, arr2) {
if (!Array.isArray(arr1)) return [];
if (!Array.isArray(arr2)) arr2 = null;
return arr1.filter(x => !arr2?.includes(x));
}
}
Loading