-
Notifications
You must be signed in to change notification settings - Fork 2
✨ server: support manteca inquiry #680
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@exactly/server": patch | ||
| --- | ||
|
|
||
| ✨ support manteca inquiry |
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 Duplicate call to getMantecaDepositDetails in quote endpoint In the Click to expandCode flowLines 149-159 in try {
depositInfo = getMantecaDepositDetails(query.currency, mantecaUser.exchange);
} catch (error) {
// error handling...
}
depositInfo = getMantecaDepositDetails(query.currency, mantecaUser.exchange);
return c.json({ quote: await getMantecaQuote(`USDC_${query.currency}`), depositInfo });If the first call (line 150) succeeds, ImpactThis causes unnecessary computation and could potentially throw an error on the second call that wasn't caught by the try-catch block. (Refers to line 158) Recommendation: Remove the duplicate call on line 158. The Was this helpful? React with 👍 or 👎 to provide feedback. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -42,7 +42,7 @@ import { | |
| import { CryptoNetwork, type DepositDetails, type ProviderInfo, type RampProvider } from "../utils/ramps/shared"; | ||
| import validatorHook from "../utils/validatorHook"; | ||
|
|
||
| const debug = createDebug("exa:onramp"); | ||
| const debug = createDebug("exa:ramp"); | ||
| Object.assign(debug, { inspectOpts: { depth: undefined } }); | ||
|
|
||
| const ErrorCodes = { | ||
|
|
@@ -92,37 +92,24 @@ export default new Hono() | |
|
|
||
| const redirectURL = c.req.valid("query").redirectURL; | ||
| const [mantecaProvider, bridgeProvider] = await Promise.all([ | ||
| getMantecaProvider(credential.account, credentialId, templateId, countryCode, redirectURL).catch( | ||
| (error: unknown) => { | ||
| captureException(error, { contexts: { credential, params: { templateId, countryCode } } }); | ||
| return { status: "NOT_AVAILABLE" as const, currencies: [], cryptoCurrencies: [], pendingTasks: [] }; | ||
| }, | ||
| ), | ||
| getMantecaProvider(credential.account, countryCode).catch((error: unknown) => { | ||
| captureException(error, { contexts: { credential, params: { templateId, countryCode } } }); | ||
| return { onramp: { currencies: [], cryptoCurrencies: [] }, status: "NOT_AVAILABLE" as const }; | ||
| }), | ||
| getBridgeProvider({ | ||
| credentialId, | ||
| templateId, | ||
| customerId: credential.bridgeId, | ||
| countryCode, | ||
| redirectURL, | ||
| }).catch((error: unknown) => { | ||
| captureException(error, { contexts: { credential, params: { templateId, countryCode } } }); | ||
| return { status: "NOT_AVAILABLE" as const, currencies: [], cryptoCurrencies: [], pendingTasks: [] }; | ||
| return { onramp: { currencies: [], cryptoCurrencies: [] }, status: "NOT_AVAILABLE" as const }; | ||
| }), | ||
| ]); | ||
|
|
||
| const providers: Record<(typeof RampProvider)[number], InferInput<typeof ProviderInfo>> = { | ||
| manteca: { | ||
| status: mantecaProvider.status, | ||
| currencies: mantecaProvider.currencies, | ||
| cryptoCurrencies: mantecaProvider.cryptoCurrencies, | ||
| pendingTasks: mantecaProvider.pendingTasks, | ||
| }, | ||
| bridge: { | ||
| status: bridgeProvider.status, | ||
| currencies: bridgeProvider.currencies, | ||
| cryptoCurrencies: bridgeProvider.cryptoCurrencies, | ||
| pendingTasks: bridgeProvider.pendingTasks, | ||
| }, | ||
| manteca: mantecaProvider, | ||
| bridge: bridgeProvider, | ||
| }; | ||
| return c.json({ providers }); | ||
| }) | ||
|
|
@@ -196,62 +183,49 @@ export default new Hono() | |
| } | ||
| } | ||
| }) | ||
| .post( | ||
| "/onboarding", | ||
| auth(), | ||
| vValidator("query", object({ templateId: optional(string()) }), validatorHook({ code: "bad query" })), | ||
| vValidator("json", Onboarding, validatorHook({ code: "bad onboarding" })), | ||
| async (c) => { | ||
| const { credentialId } = c.req.valid("cookie"); | ||
| const onboarding = c.req.valid("json"); | ||
| const templateId = c.req.valid("query").templateId ?? PANDA_TEMPLATE; | ||
| if (templateId !== PANDA_TEMPLATE) { | ||
| return c.json({ code: "bad template", legacy: "invalid persona template" }, 400); | ||
| } | ||
| const credential = await database.query.credentials.findFirst({ | ||
| where: eq(credentials.id, credentialId), | ||
| columns: { account: true, bridgeId: true }, | ||
| }); | ||
| if (!credential) return c.json({ code: ErrorCodes.NO_CREDENTIAL }, 400); | ||
| setUser({ id: credential.account }); | ||
| .post("/", auth(), vValidator("json", Onboarding, validatorHook({ code: "bad onboarding" })), async (c) => { | ||
| const { credentialId } = c.req.valid("cookie"); | ||
| const onboarding = c.req.valid("json"); | ||
| const credential = await database.query.credentials.findFirst({ | ||
| where: eq(credentials.id, credentialId), | ||
| columns: { account: true, bridgeId: true }, | ||
| }); | ||
| if (!credential) return c.json({ code: ErrorCodes.NO_CREDENTIAL }, 400); | ||
| setUser({ id: credential.account }); | ||
|
|
||
| switch (onboarding.provider) { | ||
| case "manteca": | ||
| try { | ||
| await mantecaOnboarding(credential.account, credentialId, templateId); | ||
| } catch (error) { | ||
| captureException(error, { contexts: { credential } }); | ||
| if (error instanceof Error && Object.values(MantecaErrorCodes).includes(error.message)) { | ||
| switch (error.message) { | ||
| case MantecaErrorCodes.COUNTRY_NOT_ALLOWED: | ||
| case MantecaErrorCodes.ID_NOT_ALLOWED: | ||
| case MantecaErrorCodes.BAD_KYC_ADDITIONAL_DATA: | ||
| return c.json({ code: error.message }, 400); | ||
| } | ||
| switch (onboarding.provider) { | ||
| case "manteca": | ||
| try { | ||
| await mantecaOnboarding(credential.account, credentialId); | ||
| } catch (error) { | ||
| captureException(error, { contexts: { credential } }); | ||
| if (error instanceof Error && Object.values(MantecaErrorCodes).includes(error.message)) { | ||
| switch (error.message) { | ||
| case MantecaErrorCodes.NO_DOCUMENT: | ||
| return c.json({ code: error.message }, 400); | ||
| } | ||
| throw error; | ||
| } | ||
| break; | ||
| case "bridge": | ||
| try { | ||
| await bridgeOnboarding({ | ||
| credentialId, | ||
| customerId: credential.bridgeId, | ||
| templateId, | ||
| acceptedTermsId: onboarding.acceptedTermsId, | ||
| }); | ||
| } catch (error) { | ||
| captureException(error, { contexts: { credential } }); | ||
| if (error instanceof Error && Object.values(BridgeErrorCodes).includes(error.message)) { | ||
| switch (error.message) { | ||
| case BridgeErrorCodes.ALREADY_ONBOARDED: | ||
| return c.json({ code: error.message }, 400); | ||
| } | ||
| throw error; | ||
| } | ||
| break; | ||
| case "bridge": | ||
| try { | ||
| await bridgeOnboarding({ | ||
| credentialId, | ||
| customerId: credential.bridgeId, | ||
| acceptedTermsId: onboarding.acceptedTermsId, | ||
| }); | ||
| } catch (error) { | ||
| captureException(error, { contexts: { credential } }); | ||
| if (error instanceof Error && Object.values(BridgeErrorCodes).includes(error.message)) { | ||
| switch (error.message) { | ||
| case BridgeErrorCodes.ALREADY_ONBOARDED: | ||
| return c.json({ code: error.message }, 400); | ||
| } | ||
| throw error; | ||
| } | ||
| break; | ||
| } | ||
| return c.json({ code: "ok" }); | ||
| }, | ||
| ); | ||
| throw error; | ||
| } | ||
| break; | ||
| } | ||
|
Comment on lines
+196
to
+229
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Find where MantecaErrorCodes is defined
fd -t f "manteca" server/ | head -20
rg -l "MantecaErrorCodes" server/ --type tsRepository: exactly/exa Length of output: 127 🏁 Script executed: #!/bin/bash
# Get MantecaErrorCodes definition
rg -A 20 "export.*MantecaErrorCodes" server/ -t tsRepository: exactly/exa Length of output: 37 🏁 Script executed: #!/bin/bash
# Get BridgeErrorCodes definition
rg -A 20 "export.*BridgeErrorCodes" server/ -t tsRepository: exactly/exa Length of output: 37 🏁 Script executed: #!/bin/bash
# Check mantecaOnboarding function to understand error throwing behavior
rg -B 5 -A 30 "function mantecaOnboarding|export.*mantecaOnboarding" server/ -t tsRepository: exactly/exa Length of output: 2884 🏁 Script executed: #!/bin/bash
# Check bridgeOnboarding function to understand error throwing behavior
rg -B 5 -A 30 "function bridgeOnboarding|export.*bridgeOnboarding" server/ -t tsRepository: exactly/exa Length of output: 37 🏁 Script executed: #!/bin/bash
# Find ErrorCodes definition
rg -B 5 -A 30 "export.*ErrorCodes|const.*ErrorCodes" server/ -t ts | head -100Repository: exactly/exa Length of output: 5703 🏁 Script executed: #!/bin/bash
# Search for NO_DOCUMENT error
rg "NO_DOCUMENT" server/ -t ts -B 2 -A 2Repository: exactly/exa Length of output: 1729 🏁 Script executed: #!/bin/bash
# Search for bridgeOnboarding definition
rg -B 5 -A 30 "bridgeOnboarding" server/ -t tsRepository: exactly/exa Length of output: 3174 🏁 Script executed: #!/bin/bash
# Check if MantecaErrorCodes is imported or defined in ramp.ts
rg "MantecaErrorCodes|BridgeErrorCodes" server/api/ramp.ts -B 5 -A 5Repository: exactly/exa Length of output: 3350 🏁 Script executed: #!/bin/bash
# Check context around error handling in onboarding endpoint
cat -n server/api/ramp.ts | sed -n '185,235p'Repository: exactly/exa Length of output: 2116 🏁 Script executed: #!/bin/bash
# Look for comments explaining error handling strategy
rg -B 10 "case \"manteca\":" server/api/ramp.ts | head -30Repository: exactly/exa Length of output: 959 🏁 Script executed: #!/bin/bash
# Check if onboarding endpoint is called from webhooks or other places
rg "onboarding|POST /" server/hooks/ -t ts -B 2 -A 2Repository: exactly/exa Length of output: 37 Handle all error codes consistently in onboarding endpoint. The manteca and bridge onboarding error handling only catches specific error codes ( 🤖 Prompt for AI Agents |
||
| return c.json({ code: "ok" }); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The removal of the
eslint-disable-next-linecomment is a good improvement. It indicates that the conditionif (scope === "basic" && credential.pandaId)is now correctly recognized as potentially necessary, likely due to the introduction of the 'manteca' scope.