-
Notifications
You must be signed in to change notification settings - Fork 0
PROTO-347: Swap and Bridge REPL tool #157
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?
Conversation
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.
Pull Request Overview
This PR introduces a Swap and Bridge REPL tool for the M protocol, enabling interactive command-line token swapping and cross-chain bridging. The implementation includes a new React-based terminal interface for performing swaps and bridge operations from Solana to other chains (specifically Ethereum).
- A new REPL service that provides an interactive CLI for token swapping and bridging operations
- Refactoring of the API from "swap" to "transactions" with enhanced functionality including bridge operations
- SDK updates to support the new transaction endpoints and bridge functionality
Reviewed Changes
Copilot reviewed 23 out of 63 changed files in this pull request and generated 6 comments.
Show a summary per file
File | Description |
---|---|
services/repl/ | New interactive CLI tool with React components for swap and bridge operations |
services/api/server/src/transactions.ts | Refactored swap service to transactions service with added bridge functionality |
services/api/fern/definition/transactions.yml | Updated API definition to include bridge endpoints and enhanced transaction response |
services/api/sdk-* | Updated SDKs to reflect the new transactions API structure |
dashboard/src/components/swap.tsx | Updated to use new transactions API endpoints |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
import { Connection, Keypair, VersionedTransaction } from '@solana/web3.js'; | ||
|
||
export const useWallet = () => { | ||
const key = Keypair.fromSecretKey(Buffer.from(JSON.parse(process.env.PAYER_KEYPAIR!))); |
Copilot
AI
Aug 22, 2025
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.
Direct parsing of environment variables without validation could be vulnerable to injection attacks. Consider validating the format and content of PAYER_KEYPAIR before parsing.
const key = Keypair.fromSecretKey(Buffer.from(JSON.parse(process.env.PAYER_KEYPAIR!))); | |
// Validate PAYER_KEYPAIR environment variable | |
const payerKeypairRaw = process.env.PAYER_KEYPAIR; | |
if (!payerKeypairRaw) { | |
throw new Error('PAYER_KEYPAIR environment variable is not set.'); | |
} | |
let payerKeypairParsed; | |
try { | |
payerKeypairParsed = JSON.parse(payerKeypairRaw); | |
} catch (e) { | |
throw new Error('PAYER_KEYPAIR is not valid JSON.'); | |
} | |
if ( | |
!Array.isArray(payerKeypairParsed) || | |
!payerKeypairParsed.every((n) => Number.isInteger(n) && n >= 0 && n <= 255) | |
) { | |
throw new Error('PAYER_KEYPAIR must be a JSON array of integers (0-255).'); | |
} | |
// Optionally, check for expected length (e.g., 64 for Solana keypair) | |
if (payerKeypairParsed.length !== 64) { | |
throw new Error('PAYER_KEYPAIR must be a 64-byte array.'); | |
} | |
const key = Keypair.fromSecretKey(Buffer.from(payerKeypairParsed)); |
Copilot uses AI. Check for mistakes.
|
||
useEffect(() => { | ||
if (!quote && amount) getQuote(); | ||
}, [quote, amount]); |
Copilot
AI
Aug 22, 2025
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.
Missing dependency array for useEffect could cause infinite re-renders. The effect depends on inputToken
and outputToken
which are not included in the dependency array.
}, [quote, amount]); | |
}, [quote, amount, inputToken, outputToken]); |
Copilot uses AI. Check for mistakes.
|
||
useEffect(() => { | ||
if (confirmedQuote) sendSwap(); | ||
}, [confirmedQuote]); |
Copilot
AI
Aug 22, 2025
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.
Missing dependency array for useEffect could cause infinite re-renders. The effect depends on variables like quote
, publicKey
, and execute
which are not included in the dependency array.
}, [confirmedQuote]); | |
}, [confirmedQuote, quote, publicKey, execute, onSwapResponse, signAndSendTransaction]); |
Copilot uses AI. Check for mistakes.
quoteResponse.preQuote = quote; | ||
routePlan.push(...quote.routePlan.map(convertRoutePlan)); | ||
routePlan.push(getM0Route(wM.toBase58(), outputMint, quote.outAmount)); | ||
if (outputMint !== wM.toBase58()) routePlan.push(getM0Route(wM.toBase58(), outputMint, quote.outAmount)); |
Copilot
AI
Aug 22, 2025
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.
[nitpick] This conditional logic is duplicated from the original implementation. Consider extracting this into a helper function to reduce code duplication and improve maintainability.
Copilot uses AI. Check for mistakes.
extensionTo: { | ||
mint: outputMint, | ||
programId: extensionData.find((ext) => ext.mint === outputMint)?.programId ?? mProgram, | ||
programId: extensionData.find((ext) => ext.mint === outputMint)?.programId ?? EARN, |
Copilot
AI
Aug 22, 2025
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.
Using EARN as fallback when programId is not found could lead to incorrect program execution. Consider throwing an error or handling this case more explicitly.
Copilot uses AI. Check for mistakes.
|
||
useEffect(() => { | ||
if (swap && recipientAddress) createTransaction(); | ||
}, [swap, recipientAddress]); |
Copilot
AI
Aug 22, 2025
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.
Missing dependency array for useEffect could cause infinite re-renders. The effect depends on variables like quote
, publicKey
, and other state that are not included in the dependency array.
}, [swap, recipientAddress]); | |
}, [swap, recipientAddress, quote, publicKey, signAndSendTransaction]); |
Copilot uses AI. Check for mistakes.
Lot of files touched because I made some updates to the API
Relevant files are in
services/repl
Screen.Recording.2025-08-22.at.3.40.25.PM.mov