Skip to content

Fix CM uploading#97

Open
MarkSackerberg wants to merge 4 commits intomainfrom
fix/cm-upload
Open

Fix CM uploading#97
MarkSackerberg wants to merge 4 commits intomainfrom
fix/cm-upload

Conversation

@MarkSackerberg
Copy link
Copy Markdown
Contributor

This PR fixes two things:

  1. File uploader: batch uploads instead of one-by-one

uploadFiles was uploading files individually in a sequential loop, each with its own price check and retry logic. This caused issues with too many concurrent upload. Refactored to upload in batches of 50, letting the Irys uploader handle concurrency internally. Also removed the manual balance check/fund logic (the uploader handles this) and simplified the retry logic to operate per-batch rather than per-file.

  1. CM insert: switch to transactionStatus confirmation with batched send+confirm

The candy machine insertItems was using the default blockhash confirmation strategy, which sends all transactions at once then confirms all at once. For large CM uploads this could overwhelm the RPC. Changed to transactionStatus strategy, which sends and confirms in batches of 10, spreading RPC load and using polling-based confirmation that's more reliable for bulk operations.

To test try to upload at least 1k assets, this was the number where i could reliably reproduce the issues.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

Summary by CodeRabbit

  • New Features

    • Added selectable transaction confirmation strategies for send/confirm operations.
  • Improvements

    • Transaction sending supports batched send-and-confirm with per-batch progress and consolidated "Processed" reporting.
    • Confirmation now offers an alternate transaction-status polling strategy with bounded retries and progress updates.
    • File uploads run in batches, fill results deterministically, and abort after repeated failures.
    • Directory upload spinner shows current file index/total.
  • Tests

    • Command tests updated to expect "Processed" in output.

Walkthrough

Adds a pluggable confirmation strategy (blockhash vs transactionStatus), dispatches send/confirm flows accordingly (including batched send+confirm and polling-based transaction-status confirmation), switches config uploads to use transactionStatus, refactors uploader to batch processing with stricter retries, and updates CLI progress/tests.

Changes

Cohort / File(s) Summary
Confirmation Strategy & Options
src/lib/umi/sendOptions.ts
Added exported ConfirmationStrategy enum and optional confirmationStrategy?: ConfirmationStrategy on UmiSendOptions.
Send & Confirm Routing
src/lib/umi/sendAllTransactionsAndConfirm.ts
Route send/confirm by confirmationStrategy; added sendAndConfirmInBatches for transactionStatus and preserved/refactored blockhash path (sendAllThenConfirmAll). Batched progress messaging added.
Confirmation Implementations
src/lib/umi/confirmAllTransactions.ts
Split into confirmAllByBlockhash (sequential confirmTransaction) and confirmAllByTransactionStatus (polling via getSignatureStatuses with MAX_POLL_ROUNDS/POLL_INTERVAL); dispatcher picks strategy based on sendOptions.
Config Manager Integration
src/lib/cm/insertItems.ts
Now passes confirmationStrategy: ConfirmationStrategy.transactionStatus into umiSendAllTransactionsAndConfirm.
Uploader Batch Refactor
src/lib/uploader/uploadFiles.ts
Removed createIrysUploader / upfront funding flow; added batching (BATCH_SIZE=50) and MAX_RETRIES=3, pre-allocated results, per-file retries that abort on exceeded retries, and emit progress only on successful uploads.
CLI Progress & Tests
src/commands/toolbox/storage/upload.ts, test/commands/cm/cm.full.test.ts, test/commands/cm/cm.insert.test.ts
Spinner shows file index X/Y; tests updated to expect "Processed" in stderr instead of separate "Sent"/"Confirmed" messages.

Sequence Diagram

sequenceDiagram
    participant Client
    participant SendConfirm as umiSendAllTransactionsAndConfirm
    participant Batch as sendAndConfirmInBatches
    participant RPC as RPC/Blockchain
    participant Poller as confirmAllByTransactionStatus

    Client->>SendConfirm: send(transactions, sendOptions{confirmationStrategy: transactionStatus})
    SendConfirm->>Batch: route to batched sender
    loop per batch
        Batch->>RPC: send batch (commitment: processed)
        RPC-->>Batch: signatures[]
        Batch->>Poller: start polling signatures[]
        loop poll rounds (up to MAX_POLL_ROUNDS)
            Poller->>RPC: getSignatureStatuses(signatures[])
            alt status observed
                RPC-->>Poller: statuses (confirmed/unconfirmed)
                Poller->>SendConfirm: onProgress/update per signature
            else continue polling
            end
        end
        Poller-->>Batch: confirmation results (confirmed or timed out)
        Batch->>Client: progress "Processed X/Y..." and partial results
    end
    SendConfirm-->>Client: aggregated results with confirmations
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested reviewers

  • tonyboylehub
  • blockiosaurus
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Fix CM uploading' is vague and does not clearly summarize the main changes. It lacks specificity about what was fixed and could apply to many different types of CM upload improvements. Consider a more specific title that describes the actual changes, such as 'Use transactionStatus strategy and batch uploads for CM insertions' or 'Implement batched confirmation for CM uploads'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description check ✅ Passed The description clearly explains both key changes: batch file uploading and the switch to transactionStatus confirmation strategy with details about why these changes improve performance.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cm-upload

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 75-91: The loop in confirmAllTransactions.ts that sequentially
awaits umi.rpc.getTransaction for each pending entry should be parallelized to
avoid slow rounds: gather the pending entries (index, signature) into an array,
call Promise.allSettled (or Promise.all) on mapped calls to
umi.rpc.getTransaction, then iterate the settled results to update
results[index], delete from pending, and call onProgress(index, results[index])
for those that resolved; for rejected or failed RPCs simply leave the entry in
pending to retry next round. Locate the code block in confirmAllTransactions
(the for (const [index, signature] of pending) { ... } section) and replace it
with a batched/parallelized approach that preserves existing error handling (set
confirmed false and error when txResult.meta.err, confirmed true when ok) and
does not treat RPC errors as fatal.
- Around line 72-73: The loop currently sleeps before the first poll, causing an
unnecessary initial delay; change the polling order in confirmAllTransactions
(the for loop using MAX_POLL_ROUNDS, POLL_INTERVAL and pending) to poll
immediately then sleep between subsequent rounds. Concretely, call the poll
logic at the top of the loop, and only await new Promise(resolve =>
setTimeout(resolve, POLL_INTERVAL)) at the end of the iteration (or guard the
sleep with if (round < MAX_POLL_ROUNDS - 1 && pending.size > 0)) so the first
round runs without the initial delay.
- Around line 88-90: The empty catch in confirmAllTransactions.ts swallows RPC
exceptions; change the catch block to capture the error (e.g., catch (err)) and
log it (using the existing logger or console.debug) with context like
"confirmAllTransactions RPC error" and the error object so transient failures
are visible during debugging; optionally gate the debug log behind a
non-production or verbose flag so production noise is avoided.

In `@src/lib/umi/sendAllTransactionsAndConfirm.ts`:
- Around line 75-99: The local variable processedCount in
sendAllTransactionsAndConfirm is unused; remove its declaration and the
processedCount += batch.length update (or alternatively wire it into the
batchLabel/spinner logic if you intended to track progress). Specifically,
delete the let processedCount = 0 line and the processedCount += batch.length
statement inside the for-loop (or replace usages of transactions.length in
batchLabel/spinner with processedCount where appropriate) so there are no dead
variables left in the sendAllTransactionsAndConfirm function.

In `@src/lib/umi/sendOptions.ts`:
- Line 12: The field declaration confirmationStrategy?: ConfirmationStrategy |
undefined is redundant because the `?:` already allows undefined; remove the `|
undefined` so the property reads confirmationStrategy?: ConfirmationStrategy in
the sendOptions type/interface to clean up the style (look for the
confirmationStrategy field in src/lib/umi/sendOptions.ts).

In `@src/lib/uploader/uploadFiles.ts`:
- Line 45: Replace the manual split('/') filename extraction with the repo's
file helper: change the logic that computes firstFile from
filePaths[batchStart].split('/') to use the utility in src/lib/file.ts (or at
minimum path.basename) so both occurrences (the one at firstFile and the similar
one at line 62) use the same helper; update references in uploadFiles.ts (the
firstFile variable calculation and the similar code at the second spot) to call
the shared filename function (or path.basename) instead of split('/') to ensure
consistent filename normalization.
- Around line 57-67: The progress callback currently emits a raw globalIndex
from uploadFiles.ts (in the loop that maps batch results) which breaks semantics
and UI (renders as percent) and hides progress until a batch finishes; change
the onProgress call to provide an explicit object like { completed: globalIndex
+ 1, total: filePaths.length } (or equivalent completed count and total) instead
of a single number, update the uploadResults mapping code in uploadFiles.ts to
use the new callback signature, and apply corresponding updates to the two
callers referenced (the renderer in src/commands/toolbox/storage/upload.ts and
the caller in src/lib/cm/uploadItems.ts) so they accept and render the {
completed, total } shape; keep the same call site timing (after each per-file
assignment) so progress remains incremental despite awaiting
umi.uploader.upload(batchFiles).
- Around line 26-33: The batching loop still holds the entire files array in
memory (so peak memory stays high); change the loop to slice from the original
filePaths per batch instead of using a pre-materialized files array—inside the
for loop compute batchFiles = filePaths.slice(batchStart, batchEnd) and then
map/transform those paths into the upload items and fill uploadResults
(UploadFileResult[]) as you process each batch, keeping BATCH_SIZE memory bounds
and avoiding full-materialization of files before the loop.
- Around line 38-53: The current batch retry loop around umi.uploader.upload can
re-submit already-persisted files on partial failures; change uploadFiles.ts so
upload retries are per-file (not per-batch): call umi.uploader.upload for each
filePath (or use a provider method that returns per-file results) and maintain a
map of filePath -> uri/failed state, retry only files marked failed up to
MAX_RETRIES, using retryCount per file; use the existing symbols
batchFiles/batchUris/filePaths/batchStart/MAX_RETRIES to locate the loop and
replace the batch retry logic with per-file retry/backoff and update the final
URI mapping to come from the per-file results.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 10babcf5-eceb-4549-a651-b5067b91b28f

📥 Commits

Reviewing files that changed from the base of the PR and between 1c81bea and ce380cf.

📒 Files selected for processing (7)
  • src/lib/cm/insertItems.ts
  • src/lib/umi/confirmAllTransactions.ts
  • src/lib/umi/sendAllTransactionsAndConfirm.ts
  • src/lib/umi/sendOptions.ts
  • src/lib/uploader/uploadFiles.ts
  • test/commands/cm/cm.full.test.ts
  • test/commands/cm/cm.insert.test.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/umi/confirmAllTransactions.ts (1)

22-26: ⚠️ Potential issue | 🔴 Critical

Bug: Missing confirmations.push() for transactions without signatures.

When a transaction has no signature, the function calls onProgress but doesn't push a result to the confirmations array. This causes confirmations.length to be less than transactions.length, breaking the index correspondence expected by callers (e.g., sendAllThenConfirmAll at line 60 does confirmations[index]).

🐛 Proposed fix
   for (const transaction of transactions) {
     if (!transaction?.signature) {
-      onProgress && onProgress(index, { confirmed: false, error: transaction?.err || 'transaction has no signature' })
+      const result = { confirmed: false, error: transaction?.err || 'transaction has no signature' }
+      confirmations.push(result)
+      onProgress && onProgress(index, result)
       index++
       continue
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/umi/confirmAllTransactions.ts` around lines 22 - 26, In
confirmAllTransactions, when a transaction lacks a signature the code calls
onProgress but fails to push a corresponding result into the confirmations
array, breaking the index alignment used by callers like sendAllThenConfirmAll;
update the branch that checks transaction?.signature to push a confirmation
object (e.g., { confirmed: false, error: transaction?.err || 'transaction has no
signature' }) into confirmations at the current index before incrementing index
and continuing so confirmations.length always matches transactions.length.
♻️ Duplicate comments (2)
src/lib/uploader/uploadFiles.ts (2)

35-50: ⚠️ Potential issue | 🟠 Major

Batch-level retries can re-upload already persisted files after partial failures.

Retrying the whole batch on Line 37 after an error can duplicate uploads and spend extra funds if the provider persists a subset before throwing. Prefer retrying only failed items (or idempotency checks) instead of resubmitting the full batch payload.

In the currently used `@metaplex-foundation/umi-uploader-irys` version for metaplex-foundation/cli, does `uploader.upload(files)` guarantee all-or-nothing atomicity, or can a subset of files be persisted before an error is thrown?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/uploader/uploadFiles.ts` around lines 35 - 50, The current batch
retry loop around umi.uploader.upload(batchFiles) can re-submit
already-persisted files; instead change the retry strategy so you only retry
failed items: call umi.uploader.upload on each file (or a per-file upload API)
or, if umi.uploader.upload returns a partial-success result, inspect its
response to determine which files succeeded and only requeue the failed ones for
subsequent retries; update the logic around batchFiles, batchUris, retryCount
and MAX_RETRIES (and the error path that throws using batchStart / firstFile) to
perform per-file retries with exponential backoff and deduplication (or include
idempotency keys) until all items in the original batch succeed or MAX_RETRIES
is exceeded.

1-2: 🛠️ Refactor suggestion | 🟠 Major

Use src/lib/file.ts helpers for file operations in this module.

Line 25 (fs.readFileSync) and Line 27/42/59 (path.basename) bypass the repository’s file utility requirement for src/**/*.ts. Please switch these calls to the helper(s) from src/lib/file.ts to keep path normalization and file I/O behavior consistent across commands.

As per coding guidelines, src/**/*.ts: Use utilities in src/lib/file.ts for file handling operations.

Also applies to: 24-29, 42-42, 59-59

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/uploader/uploadFiles.ts` around lines 1 - 2, In uploadFiles.ts
replace direct node fs/path usage with the repository file helpers: import the
file I/O and path utilities from src/lib/file.ts and use them instead of
fs.readFileSync and path.basename; specifically, swap the fs.readFileSync call
and the three path.basename usages in this module to the corresponding read
(async or sync) and basename/normalize helpers exported by src/lib/file.ts so
path normalization and I/O follow repository conventions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/umi/sendAllTransactionsAndConfirm.ts`:
- Around line 82-88: The batch-level progress callbacks in
sendAllTransactionsAndConfirm are not forwarded to per-batch operations; update
sendAllTransactionsAndConfirm to pass sendOptions.onSendProgress into
umiSendAllTransactions (e.g., umiSendAllTransactions(umi, batch, { ...,
onSendProgress })) and sendOptions.onConfirmProgress into confirmAllTransactions
(e.g., confirmAllTransactions(umi, sent, { ..., onConfirmProgress })) so any
per-transaction progress callbacks provided on sendOptions are invoked; ensure
you merge these keys with the existing sendOptions and keep the batch-level
spinner behavior unchanged.

---

Outside diff comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 22-26: In confirmAllTransactions, when a transaction lacks a
signature the code calls onProgress but fails to push a corresponding result
into the confirmations array, breaking the index alignment used by callers like
sendAllThenConfirmAll; update the branch that checks transaction?.signature to
push a confirmation object (e.g., { confirmed: false, error: transaction?.err ||
'transaction has no signature' }) into confirmations at the current index before
incrementing index and continuing so confirmations.length always matches
transactions.length.

---

Duplicate comments:
In `@src/lib/uploader/uploadFiles.ts`:
- Around line 35-50: The current batch retry loop around
umi.uploader.upload(batchFiles) can re-submit already-persisted files; instead
change the retry strategy so you only retry failed items: call
umi.uploader.upload on each file (or a per-file upload API) or, if
umi.uploader.upload returns a partial-success result, inspect its response to
determine which files succeeded and only requeue the failed ones for subsequent
retries; update the logic around batchFiles, batchUris, retryCount and
MAX_RETRIES (and the error path that throws using batchStart / firstFile) to
perform per-file retries with exponential backoff and deduplication (or include
idempotency keys) until all items in the original batch succeed or MAX_RETRIES
is exceeded.
- Around line 1-2: In uploadFiles.ts replace direct node fs/path usage with the
repository file helpers: import the file I/O and path utilities from
src/lib/file.ts and use them instead of fs.readFileSync and path.basename;
specifically, swap the fs.readFileSync call and the three path.basename usages
in this module to the corresponding read (async or sync) and basename/normalize
helpers exported by src/lib/file.ts so path normalization and I/O follow
repository conventions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ffdb952b-a9bf-4828-b27f-92f9f1e454a4

📥 Commits

Reviewing files that changed from the base of the PR and between ce380cf and bb51f2b.

📒 Files selected for processing (5)
  • src/commands/toolbox/storage/upload.ts
  • src/lib/umi/confirmAllTransactions.ts
  • src/lib/umi/sendAllTransactionsAndConfirm.ts
  • src/lib/umi/sendOptions.ts
  • src/lib/uploader/uploadFiles.ts

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/umi/confirmAllTransactions.ts (1)

18-25: ⚠️ Potential issue | 🟠 Major

Keep blockhash confirmations index-aligned with transactions.

This branch reports the failure via onProgress, but it never writes a placeholder into confirmations. src/lib/umi/sendAllTransactionsAndConfirm.ts:57-62 and src/lib/umi/sendAllTransactionsAndConfirm.ts:90-95 later pair confirmation results back to the original transaction list by index, so the first missing signature shifts every subsequent result onto the wrong transaction.

♻️ Preserve one result per input transaction
-  let confirmations: UmiTransactionConfirmationResult[] = []
+  const confirmations: UmiTransactionConfirmationResult[] = []
@@
   for (const transaction of transactions) {
     if (!transaction?.signature) {
-      onProgress && onProgress(index, { confirmed: false, error: transaction?.err || 'transaction has no signature' })
+      const res = { confirmed: false, error: transaction?.err || 'transaction has no signature' }
+      confirmations.push(res)
+      onProgress?.(index, res)
       index++
       continue
     }
@@
-    onProgress && onProgress(index, res)
+    onProgress?.(index, res)
     index++
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/umi/confirmAllTransactions.ts` around lines 18 - 25, The loop in
confirmAllTransactions builds confirmations but skips pushing a placeholder when
transaction has no signature, causing index misalignment; update the for-loop in
confirmAllTransactions (the block handling !transaction?.signature) to push a
corresponding UmiTransactionConfirmationResult placeholder into the
confirmations array (e.g., { confirmed: false, error: transaction?.err ||
'transaction has no signature' }) at the same index, while still calling
onProgress(index, ...) and continuing, so confirmations remains one-to-one with
transactions.
♻️ Duplicate comments (1)
src/lib/uploader/uploadFiles.ts (1)

29-32: 🛠️ Refactor suggestion | 🟠 Major

Use src/lib/file.ts helpers for file reads/name extraction.

The changed code performs file operations with direct fs/path calls (Line 29, Line 31, Line 42, Line 51, Line 56). Please switch these to the repository file utilities for consistency and centralized file-path handling behavior.

As per coding guidelines, src/**/*.ts: "Use utilities in src/lib/file.ts for file handling operations".

Also applies to: 42-43, 51-56

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/uploader/uploadFiles.ts` around lines 29 - 32, The code reads files
and extracts names using direct fs/path calls (fs.readFileSync, path.basename)
around createGenericFile and mime.getType; replace those with the centralized
helpers exported from src/lib/file.ts (use the file read helper to get the
buffer and the filename extraction helper to get the base name) so the
uploadFiles.ts logic uses those utilities instead of fs/path directly, and
ensure you pass the resulting buffer and filename into createGenericFile and
preserve the content-type tag derived from mime.getType.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 71-93: Replace the per-signature umi.rpc.getTransaction polling
with batched signature-status polling using umi.rpc.getSignatureStatuses (pass
the array of pending signatures and the intended commitment) inside the
confirmAllTransactions loop: gather the pending signatures from the pending Map,
call umi.rpc.getSignatureStatuses(signatures, { searchTransactionHistory: true,
commitment: intendedCommitment }), iterate the returned statuses to set
results[index] = { confirmed: boolean, error: status.err ?? null } and delete
resolved indexes from pending, call onProgress for each resolved index, and keep
the existing retry/wait logic (POLL_INTERVAL / MAX_POLL_ROUNDS) while catching
RPC errors around the batched call; ensure you preserve use of symbols pending,
results, onProgress, POLL_INTERVAL and MAX_POLL_ROUNDS and thread the desired
commitment through the RPC call.

In `@src/lib/uploader/uploadFiles.ts`:
- Around line 49-53: The current throw in uploadFiles.ts (inside the retry/throw
block that checks retryCount > MAX_RETRIES and constructs a new Error) aborts
the whole directory upload; change this to make the behavior configurable by
adding a failFast flag to the uploadFiles function (or its options) so that when
failFast is true you keep the existing throw (using the retryCount > MAX_RETRIES
branch), and when failFast is false you instead return/record a failed upload
result as an empty URI (preserve the index mapping like uri || '') and continue
processing other files; update callers (e.g., the toolbox directory upload path)
to pass failFast: false and any CM path callers to pass failFast: true, and
ensure the error message still includes error instanceof Error ? error.message :
String(error) when failFast is true.

---

Outside diff comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 18-25: The loop in confirmAllTransactions builds confirmations but
skips pushing a placeholder when transaction has no signature, causing index
misalignment; update the for-loop in confirmAllTransactions (the block handling
!transaction?.signature) to push a corresponding
UmiTransactionConfirmationResult placeholder into the confirmations array (e.g.,
{ confirmed: false, error: transaction?.err || 'transaction has no signature' })
at the same index, while still calling onProgress(index, ...) and continuing, so
confirmations remains one-to-one with transactions.

---

Duplicate comments:
In `@src/lib/uploader/uploadFiles.ts`:
- Around line 29-32: The code reads files and extracts names using direct
fs/path calls (fs.readFileSync, path.basename) around createGenericFile and
mime.getType; replace those with the centralized helpers exported from
src/lib/file.ts (use the file read helper to get the buffer and the filename
extraction helper to get the base name) so the uploadFiles.ts logic uses those
utilities instead of fs/path directly, and ensure you pass the resulting buffer
and filename into createGenericFile and preserve the content-type tag derived
from mime.getType.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c18df0f0-7bca-4aef-ac77-a2623cc1d3c7

📥 Commits

Reviewing files that changed from the base of the PR and between bb51f2b and 3e77b06.

📒 Files selected for processing (2)
  • src/lib/umi/confirmAllTransactions.ts
  • src/lib/uploader/uploadFiles.ts

Replace per-signature getTransaction calls with a single batched
getSignatureStatuses call per poll round. This is lighter on the RPC
and eliminates rate limit retries on large inserts.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/umi/confirmAllTransactions.ts (1)

22-26: ⚠️ Potential issue | 🔴 Critical

Missing result entry for transactions without signatures causes array length mismatch.

When a transaction lacks a signature, onProgress is called but no entry is pushed to confirmations. This creates an array shorter than the input, breaking index alignment with the caller's transaction array. The confirmAllByTransactionStatus strategy correctly pre-allocates results for all indices—this strategy should do the same.

🐛 Proposed fix to ensure consistent array length
   for (const transaction of transactions) {
     if (!transaction?.signature) {
-      onProgress && onProgress(index, { confirmed: false, error: transaction?.err || 'transaction has no signature' })
+      const failedResult = { confirmed: false, error: transaction?.err || 'transaction has no signature' }
+      confirmations.push(failedResult)
+      onProgress && onProgress(index, failedResult)
       index++
       continue
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/umi/confirmAllTransactions.ts` around lines 22 - 26, The loop in
confirmAllTransactions.ts currently calls onProgress for transactions without a
signature but does not push a corresponding entry into the confirmations array,
causing length/ordering mismatches; update the branch that checks
(!transaction?.signature) to push a result object into confirmations (e.g., {
signature: null, confirmed: false, error: transaction?.err || 'transaction has
no signature' }) before incrementing index and continuing so
confirmAllTransactions (like confirmAllByTransactionStatus) always produces a
result slot per input transaction and preserves index alignment for onProgress
and callers.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 76-79: The RPC call to umi.rpc.getSignatureStatuses is not
forwarding the caller's commitment level from sendOptions, causing potential
mismatches; update the call inside confirmAllTransactions (where signatures are
queried) to include the commitment from sendOptions (e.g.,
sendOptions?.commitment) in the options object along with
searchTransactionHistory: true so the RPC uses the same commitment as the
original sendOptions; ensure you reference umi.rpc.getSignatureStatuses, the
signatures variable, and sendOptions when making this change.

---

Outside diff comments:
In `@src/lib/umi/confirmAllTransactions.ts`:
- Around line 22-26: The loop in confirmAllTransactions.ts currently calls
onProgress for transactions without a signature but does not push a
corresponding entry into the confirmations array, causing length/ordering
mismatches; update the branch that checks (!transaction?.signature) to push a
result object into confirmations (e.g., { signature: null, confirmed: false,
error: transaction?.err || 'transaction has no signature' }) before incrementing
index and continuing so confirmAllTransactions (like
confirmAllByTransactionStatus) always produces a result slot per input
transaction and preserves index alignment for onProgress and callers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: c5cee805-387f-4477-9548-fc9143708095

📥 Commits

Reviewing files that changed from the base of the PR and between 3e77b06 and 3588eb6.

📒 Files selected for processing (1)
  • src/lib/umi/confirmAllTransactions.ts

@MarkSackerberg
Copy link
Copy Markdown
Contributor Author

Thanks for the review @tonyboylehub , please have another look

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants