-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Add bootstrap script #14
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
Signed-off-by: Dylan Kilkenny <[email protected]>
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 comprehensive TypeScript script for bootstrapping and managing Stellar channel accounts in the OpenZeppelin Relayer system. The script automates the creation of signers, relayers, and on-chain account funding while providing validation and repair capabilities.
Key Changes
- Added a new script
create-channel-accounts.tsthat manages channel account lifecycle - Implements validation and "fix" mode to heal partially created slots
- Integrates with OpenZeppelin Relayer API and Stellar Horizon for account management
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| let attempt = 0; | ||
| while (!submitted && attempt < 2) { | ||
| attempt += 1; | ||
| const account = new Account(fundingAddress, currentSequence); |
Copilot
AI
Oct 30, 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.
The sequence number is not being incremented after each transaction builder instantiation. This will cause all transactions in the loop to use the same sequence number, leading to tx_bad_seq errors for subsequent transactions. The sequence should be incremented after line 948 with currentSequence = (BigInt(currentSequence) + 1n).toString().
| keypair = Keypair.random(); | ||
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | ||
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | ||
| signerRecord = { id: signerIdentifier }; | ||
| signerCreated = true; | ||
| } else { | ||
| keypair = Keypair.random(); | ||
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | ||
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | ||
| signerRecord = { id: signerIdentifier }; | ||
| signerCreated = true; | ||
| } |
Copilot
AI
Oct 30, 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.
The nested conditional logic for handling missing relayers (lines 872-889) contains duplicated code blocks that create keypairs and signers. The three branches (lines 875-881, lines 883-888, and the implicit else case) all perform identical operations. This duplication should be consolidated into a single code path.
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; | |
| } else { | |
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; | |
| } | |
| } | |
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; |
| .build(); | ||
|
|
||
| const transactionXdr = transaction.toXDR(); | ||
| currentSequence = account.sequenceNumber(); |
Copilot
AI
Oct 30, 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.
This line assigns the current sequence number back to itself without incrementing, which is incorrect. After building a transaction, the sequence should be incremented to prepare for the next transaction. This should be currentSequence = (BigInt(account.sequenceNumber()) + 1n).toString() to properly increment the sequence.
| currentSequence = account.sequenceNumber(); | |
| currentSequence = (BigInt(account.sequenceNumber()) + 1n).toString(); |
| const existingSigner = await fetchSignerRecord(signersApi, signerId); | ||
| const existingRelayer = await fetchRelayerRecord(relayersApi, relayerId); | ||
|
|
||
| const signerExistedBefore = Boolean(existingSigner); |
Copilot
AI
Oct 30, 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.
Unused variable signerExistedBefore.
| const signerExistedBefore = Boolean(existingSigner); |
| const existingRelayer = await fetchRelayerRecord(relayersApi, relayerId); | ||
|
|
||
| const signerExistedBefore = Boolean(existingSigner); | ||
| const relayerExistedBefore = Boolean(existingRelayer); |
Copilot
AI
Oct 30, 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.
Unused variable relayerExistedBefore.
| const relayerExistedBefore = Boolean(existingRelayer); |
| keypair = Keypair.random(); | ||
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | ||
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | ||
| signerRecord = { id: signerIdentifier }; | ||
| signerCreated = true; | ||
| } else { | ||
| keypair = Keypair.random(); | ||
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | ||
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | ||
| signerRecord = { id: signerIdentifier }; | ||
| signerCreated = true; | ||
| } |
Copilot
AI
Oct 30, 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.
This use of variable 'signerRecord' always evaluates to true.
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; | |
| } else { | |
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; | |
| } | |
| } | |
| keypair = Keypair.random(); | |
| secretHex = Buffer.from(keypair.rawSecretKey()).toString('hex'); | |
| const signerIdentifier = await ensureSigner(signersApi, signerId, secretHex); | |
| signerRecord = { id: signerIdentifier }; | |
| signerCreated = true; |
| if (!signerRecord) { | ||
| throw new Error(`[${accountName}] Unable to ensure signer state.`); | ||
| } |
Copilot
AI
Oct 30, 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.
This negation always evaluates to false.
| if (!signerRecord) { | |
| throw new Error(`[${accountName}] Unable to ensure signer state.`); | |
| } |
| if (!relayerRecord) { | ||
| throw new Error( | ||
| `[${accountName}] Unable to determine account address. Consider deleting the relayer and signer manually before rerunning.` | ||
| ); | ||
| } | ||
|
|
Copilot
AI
Oct 30, 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.
This negation always evaluates to false.
| if (!relayerRecord) { | |
| throw new Error( | |
| `[${accountName}] Unable to determine account address. Consider deleting the relayer and signer manually before rerunning.` | |
| ); | |
| } |
No description provided.