Skip to content

Commit

Permalink
OnboardingAPI: fix-ups for algol (#1560)
Browse files Browse the repository at this point in the history
* Send proper chain id to api

* Fix typescript errors

* Fix onboarding for algol/demo

* Fix global onboarding status

* Fix global status for evm

* Update email dynamic data to match new templates

* Remove duplicate pool name
  • Loading branch information
sophialittlejohn authored Sep 5, 2023
1 parent bc4a9d3 commit 76b3955
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import { useWallet } from '@centrifuge/centrifuge-react'
import { useCentrifuge, useWallet } from '@centrifuge/centrifuge-react'
import { encodeAddress } from '@polkadot/util-crypto'
import { useQuery } from 'react-query'
import { getSelectedWallet } from '../../../utils/getSelectedWallet'

export const useGlobalOnboardingStatus = () => {
const wallet = useWallet()
const cent = useCentrifuge()

const selectedWallet = getSelectedWallet(wallet)

const query = useQuery(
['global-onboarding-status', selectedWallet?.address],
async () => {
if (selectedWallet) {
if (selectedWallet && selectedWallet.address) {
const chainId = await cent.getChainId()
const address =
selectedWallet.network === 'substrate'
? encodeAddress(selectedWallet.address, chainId)
: selectedWallet.address
const response = await fetch(
`${import.meta.env.REACT_APP_ONBOARDING_API_URL}/getGlobalOnboardingStatus?address=${
selectedWallet.address
}&network=${selectedWallet.network}`,
`${import.meta.env.REACT_APP_ONBOARDING_API_URL}/getGlobalOnboardingStatus?address=${address}&network=${
selectedWallet.network
}&chainId=${wallet.connectedNetwork}`,
{
method: 'GET',
headers: {
Expand Down
4 changes: 3 additions & 1 deletion centrifuge-app/src/pages/Onboarding/queries/useSignRemark.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,13 @@ export const useSignRemark = (
// @ts-expect-error
blockNumber = result.blockNumber.toString()
}
const chainId = connectedNetwork === 'centrifuge' ? await centrifuge.getChainId() : connectedNetwork

await sendDocumentsToIssuer({
txHash,
blockNumber,
isEvmOnSubstrate,
chainId: connectedNetwork || 'centrifuge',
chainId: chainId || 136,
})
setIsSubstrateTxLoading(false)
} catch (e) {
Expand Down
16 changes: 13 additions & 3 deletions onboarding-api/.env.example
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
# VARIABLES
REDIRECT_URL=http://localhost:3000
MEMBERLIST_ADMIN_PURE_PROXY=kAM1ELFDHdHeLDAkAdwEnfufoCL5hpUycGs4ZQkSQKVpHFoXm
COLLATOR_WSS_URL=wss://fullnode.algol.cntrfg.com/public-ws
RELAY_WSS_URL=wss://fullnode-relay.algol.cntrfg.com
INFURA_KEY=bf808e7d3d924fbeb74672d9341d0550
EVM_NETWORK=goerli
ONBOARDING_STORAGE_BUCKET=centrifuge-onboarding-api-dev
# SECRETS
SHUFTI_PRO_SECRET_KEY=
SHUFTI_PRO_CLIENT_ID=
NODE_ENV=development
JWT_SECRET=
REDIRECT_URL=http://localhost:3000
SENDGRID_API_KEY=
SENDGRID_API_KEY=
COOKIE_SECRET=
EVM_MEMBERLIST_ADMIN_PRIVATE_KEY=
PURE_PROXY_CONTROLLER_SEED=
12 changes: 3 additions & 9 deletions onboarding-api/src/controllers/user/getGlobalOnboardingStatus.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
import { Request, Response } from 'express'
import { InferType, mixed, object, string } from 'yup'
import { SupportedNetworks } from '../../database'
import { walletSchema } from '../../database'
import { fetchUser } from '../../utils/fetchUser'
import { reportHttpError } from '../../utils/httpError'
import { validateInput } from '../../utils/validateInput'

const getGlobalOnboardingStatusInput = object({
address: string().required(),
network: mixed<SupportedNetworks>().required().oneOf(['evm', 'substrate']),
})

export const getGlobalOnboardingStatusController = async (
req: Request<{}, {}, {}, InferType<typeof getGlobalOnboardingStatusInput>>,
req: Request<{}, {}, {}, Request['wallet']>,
res: Response
) => {
try {
await validateInput(req.query, getGlobalOnboardingStatusInput)
await validateInput(req.query, walletSchema)

const user = await fetchUser(req.query, { suppressError: true })

Expand Down
4 changes: 2 additions & 2 deletions onboarding-api/src/controllers/user/updateInvestorStatus.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ export const updateInvestorStatusController = async (
metadata,
countersignedAgreementPDF
),
sendApproveIssuerMessage(wallet.address, metadata, tranche as Pool['tranches'][0], countersignedAgreementPDF),
sendApproveIssuerMessage(wallet, metadata, tranche as Pool['tranches'][0], countersignedAgreementPDF),
validateAndWriteToFirestore(wallet, updatedUser, user.investorType, ['poolSteps']),
])
return res.status(200).send({ status: 'approved', poolId, trancheId, txHash })
} else if (user?.email && status === 'rejected') {
await Promise.all([
sendRejectInvestorMessage(user.email, metadata),
sendRejectInvestorMessage(user.email, tranche as Pool['tranches'][0], metadata),
validateAndWriteToFirestore(wallet, updatedUser, user.investorType, ['poolSteps']),
])
return res.status(200).send({ status: 'rejected', poolId, trancheId })
Expand Down
4 changes: 2 additions & 2 deletions onboarding-api/src/database/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const uboSchema = object({
countryOfCitizenship: string().required(),
})

const walletSchema = object({
export const walletSchema = object({
evm: array().of(string()),
substrate: array().of(string()),
evmOnSubstrate: array().of(string()),
Expand Down Expand Up @@ -115,7 +115,7 @@ export const individualUserSchema = object({
investorType: string().default('individual') as StringSchema<Individual>,
wallets: walletSchema,
kycReference: string().optional(),
email: string().default(null).nullable(), // TODO: coming soon
email: string().default(null).nullable(),
name: string().required(),
dateOfBirth: string().required(),
countryOfCitizenship: string().required(), // TODO: validate with list of countries
Expand Down
1 change: 0 additions & 1 deletion onboarding-api/src/emails/sendApproveInvestorMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export const sendApproveInvestorMessage = async (
},
],
dynamic_template_data: {
poolName: poolMetadata?.pool.name,
trancheName: tranche?.currency.name,
poolUrl: `${process.env.REDIRECT_URL}/pools/${poolId}`,
},
Expand Down
10 changes: 7 additions & 3 deletions onboarding-api/src/emails/sendApproveIssuerMessage.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { Pool } from '@centrifuge/centrifuge-js'
import { Request } from 'express'
import { sendEmail, templateIds } from '.'
import { fetchUser } from '../utils/fetchUser'

export const sendApproveIssuerMessage = async (
walletAddress: string,
wallet: Request['wallet'],
metadata: Record<string, any>,
tranche: Pool['tranches'][0],
countersignedAgreementPDF: Uint8Array
) => {
const user = await fetchUser(wallet)
const message = {
personalizations: [
{
Expand All @@ -16,7 +19,8 @@ export const sendApproveIssuerMessage = async (
},
],
dynamic_template_data: {
tokenName: tranche.currency.name,
trancheName: tranche.currency.name,
investorEmail: user.email,
},
},
],
Expand All @@ -28,7 +32,7 @@ export const sendApproveIssuerMessage = async (
attachments: [
{
content: Buffer.from(countersignedAgreementPDF).toString('base64'),
filename: `${walletAddress}-${tranche.currency.name?.replaceAll(' ', '-')}-subscription-agreement.pdf`,
filename: `${wallet.address}-${tranche.currency.name?.replaceAll(' ', '-')}-subscription-agreement.pdf`,
type: 'application/pdf',
disposition: 'attachment',
},
Expand Down
6 changes: 6 additions & 0 deletions onboarding-api/src/emails/sendDocumentsMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Request } from 'express'
import * as jwt from 'jsonwebtoken'
import { sendEmail, templateIds } from '.'
import { onboardingBucket } from '../database'
import { fetchUser } from '../utils/fetchUser'
import { HttpError } from '../utils/httpError'
import { NetworkSwitch } from '../utils/networks/networkSwitch'

Expand All @@ -11,6 +12,7 @@ export type UpdateInvestorStatusPayload = {
trancheId: string
}

// send documents to issuer to approve or reject the prospective investor
export const sendDocumentsMessage = async (
wallet: Request['wallet'],
poolId: string,
Expand All @@ -19,6 +21,8 @@ export const sendDocumentsMessage = async (
debugEmail?: string
) => {
const { metadata, pool } = await new NetworkSwitch(wallet.network).getPoolById(poolId)
const tranche = pool?.tranches.find((t) => t.id === trancheId)
const investorEmail = (await fetchUser(wallet)).email
const payload: UpdateInvestorStatusPayload = { wallet, poolId, trancheId }
const token = jwt.sign(payload, process.env.JWT_SECRET, {
expiresIn: '14d',
Expand Down Expand Up @@ -48,6 +52,8 @@ export const sendDocumentsMessage = async (
token
)}&status=approved&metadata=${pool?.metadata}&network=${wallet.network}`,
disclaimerLink: `${process.env.REDIRECT_URL}/disclaimer`,
trancheName: tranche?.currency.name,
investorEmail,
},
},
],
Expand Down
9 changes: 7 additions & 2 deletions onboarding-api/src/emails/sendRejectInvestorMessage.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Pool } from '@centrifuge/centrifuge-js'
import { sendEmail, templateIds } from '.'

export const sendRejectInvestorMessage = async (to: string, metadata: Record<string, any>) => {
export const sendRejectInvestorMessage = async (
to: string,
tranche: Pool['tranches'][0],
metadata: Record<string, any>
) => {
const message = {
personalizations: [
{
Expand All @@ -10,8 +15,8 @@ export const sendRejectInvestorMessage = async (to: string, metadata: Record<str
},
],
dynamic_template_data: {
poolName: metadata?.pool.name,
issuerEmail: metadata.pool.issuer.email,
trancheName: tranche?.currency.name,
},
},
],
Expand Down
2 changes: 1 addition & 1 deletion onboarding-api/src/utils/envCheck.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
const devEnvs = ['demo', 'development', 'catalyst']
const devEnvs = ['algol', 'development', 'catalyst']
export const IS_DEV_ENV = devEnvs.some((env) => process.env.COLLATOR_WSS_URL.includes(env))
2 changes: 1 addition & 1 deletion onboarding-api/src/utils/fetchUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export async function fetchUser<T>(wallet: Request['wallet'], options?: OptionsO
if (!userSnapshotOnOtherNetwork.empty) {
const { user, id } = userSnapshotOnOtherNetwork.docs.map((doc) => ({ user: doc.data(), id: doc.id }))[0]
await validateAndWriteToFirestore(
{ address: id, network },
{ address: id, network, chainId: wallet.chainId },
{
wallets: {
...user.wallets,
Expand Down

0 comments on commit 76b3955

Please sign in to comment.