Skip to content

Auto-detect Core asset vs collection for plugin add/update - #129

Closed
MarkSackerberg wants to merge 2 commits into
mainfrom
cursor/auto-detect-plugin-collection-e1e4
Closed

Auto-detect Core asset vs collection for plugin add/update#129
MarkSackerberg wants to merge 2 commits into
mainfrom
cursor/auto-detect-plugin-collection-e1e4

Conversation

@MarkSackerberg

@MarkSackerberg MarkSackerberg commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

mplx core plugins add and update previously assumed the address was an asset unless --collection was passed. Passing a collection address without the flag failed with Unable to fetch asset.

This change introduces resolveCoreAccount, which:

  1. Honors --collection as an explicit override (collection only)
  2. Otherwise tries Asset first, then falls back to Collection
  3. Surfaces a clear error if the address is neither

This mirrors the auto-detect pattern already used by genesis bucket fetch when --type is omitted (safeFetch* + fallback).

Also prepends a 400k compute unit limit on Genesis create only. Create was flaking on Node 24 CI with Computational budget exceeded at Solana's 200k default. A global CU limit was tried and rejected because it pushed near-full txs (e.g. add presale bucket) over the transaction size cap.

Usage

# Works for collections without --collection
mplx core plugins add <collectionPublicKey> ./plugin.json

# Explicit override still supported
mplx core plugins add <collectionPublicKey> ./plugin.json --collection

Test plan

  • TypeScript build passes
  • CI green on Node 24 and LTS (run 29988648804)
  • Existing plugin tests with --collection still pass
  • New tests: add/update collection plugins without --collection (auto-detect)
  • Asset plugin add/update still resolves parent collection from update authority
  • Invalid address fails with a clear neither-asset-nor-collection error
Open in Web Open in Cursor 

When adding or updating plugins, resolve the address as an asset first
and fall back to a collection instead of failing with "Unable to fetch
asset". The --collection flag remains as an explicit override.

Co-authored-by: MarkSackerberg <MarkSackerberg@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Core plugin add and update commands now share account resolution for asset and collection addresses. Transaction sending also supports configurable compute-unit limits and prepended priority-fee instructions, with collection auto-detection covered by tests.

Changes

Core plugin account resolution

Layer / File(s) Summary
Core account resolver
src/lib/core/fetch/resolveCoreAccount.ts
Adds typed asset and collection resolution with forced collection handling and unresolved-address errors.
Add and update command integration
src/commands/core/plugins/add.ts, src/commands/core/plugins/update.ts
Uses resolved account type and collection identifiers in wizard and JSON batch operations, and updates collection flag help text and examples.
Collection auto-detection coverage
test/commands/core/core.plugins.test.ts
Tests adding and updating collection plugins without the --collection flag.

Transaction compute-budget configuration

Layer / File(s) Summary
Compute-unit limit option
src/lib/umi/sendOptions.ts, src/lib/umi/sendTransaction.ts
Adds an optional compute-unit limit and a 400,000-unit default.
Compute-budget transaction setup
src/lib/umi/sendTransaction.ts
Prepends compute-unit limit instructions and optionally prepends priority-fee instructions using the configured fee.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant CorePluginsCommand
  participant resolveCoreAccount
  participant CoreAsset
  participant CoreCollection
  participant PluginBatchOperation

  CLI->>CorePluginsCommand: add or update plugins
  CorePluginsCommand->>resolveCoreAccount: resolve target address
  resolveCoreAccount->>CoreAsset: fetch asset
  resolveCoreAccount->>CoreCollection: fetch collection if needed
  resolveCoreAccount-->>CorePluginsCommand: return account type and collectionId
  CorePluginsCommand->>PluginBatchOperation: submit add or update batch
  PluginBatchOperation-->>CLI: report command result
Loading

Suggested reviewers: tonyboylehub

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: auto-detecting Core assets vs collections for plugin add/update.
Description check ✅ Passed The description is related to the changeset and describes the add/update auto-detection behavior, though it also mentions an extra compute-unit change.
✨ 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 cursor/auto-detect-plugin-collection-e1e4

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.

@MarkSackerberg
MarkSackerberg marked this pull request as ready for review July 23, 2026 06:51
@MarkSackerberg

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/commands/core/core.plugins.test.ts`:
- Around line 43-61: Add resolver-level tests covering a valid but absent
address, an asset supplied with forceCollection, and an RPC rejection, alongside
the existing collection auto-detection test. Exercise the resolver’s explicit
override and error paths and assert their documented outcomes, using the
resolver symbols and test setup already present in the surrounding cases.
🪄 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 Plus

Run ID: 7e3927d2-84a9-4dba-af59-a5e7442fece1

📥 Commits

Reviewing files that changed from the base of the PR and between a3c03ae and 485de17.

📒 Files selected for processing (4)
  • src/commands/core/plugins/add.ts
  • src/commands/core/plugins/update.ts
  • src/lib/core/fetch/resolveCoreAccount.ts
  • test/commands/core/core.plugins.test.ts

Comment on lines +43 to +61
it('adds a plugin to a collection without --collection by auto-detecting', async function() {
this.timeout(30000)
const { collectionId } = await createCoreCollection()

const addInput = [
'core',
'plugins',
'add',
collectionId,
'test-files/plugins.json',
]

const { stderr: addStderr, code: addCode } = await runCli(addInput)
const cleanAddStderr = stripAnsi(addStderr)

expect(addCode).to.equal(0)
expect(cleanAddStderr).to.contain('Resolved as collection')
expect(cleanAddStderr).to.contain('Successfully added')
})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Cover the resolver’s negative branches.

Add resolver-level tests for a valid absent address, an asset passed with forceCollection, and an RPC rejection. The new integration cases only verify successful collection auto-detection, leaving the explicit override and clear-error contracts unguarded.

Also applies to: 99-125

🧰 Tools
🪛 ESLint

[error] 44-44: Invalid group length in numeric value.

(unicorn/numeric-separators-style)


[error] 55-55: Expected "code" to come before "stderr"

(perfectionist/sort-objects)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/commands/core/core.plugins.test.ts` around lines 43 - 61, Add
resolver-level tests covering a valid but absent address, an asset supplied with
forceCollection, and an RPC rejection, alongside the existing collection
auto-detection test. Exercise the resolver’s explicit override and error paths
and assert their documented outcomes, using the resolver symbols and test setup
already present in the surrounding cases.

Genesis account creation can exceed Solana's 200k default compute
budget under Node 24 CI. Prepend setComputeUnitLimit (400k) in the
shared send path so heavier Metaplex transactions stop failing flakily.

Co-authored-by: MarkSackerberg <MarkSackerberg@users.noreply.github.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/umi/sendOptions.ts`:
- Around line 10-11: Reorder the computeUnitLimit property and its documentation
in the send options interface so they appear before priorityFee, satisfying the
perfectionist/sort-interfaces ordering rule without changing the property
definition.

In `@src/lib/umi/sendTransaction.ts`:
- Around line 12-14: Avoid using DEFAULT_COMPUTE_UNIT_LIMIT as the implicit
priority-fee budget in sendTransaction when computeUnitLimit is omitted. Use a
tighter transaction-specific compute-unit estimate, or require an explicit
computeUnitLimit whenever priorityFee is enabled, while preserving the existing
default only for transactions without priority fees.
🪄 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 Plus

Run ID: 6d9ad036-33ae-4066-918f-020d285fee93

📥 Commits

Reviewing files that changed from the base of the PR and between 485de17 and f72cb60.

📒 Files selected for processing (2)
  • src/lib/umi/sendOptions.ts
  • src/lib/umi/sendTransaction.ts

Comment on lines +10 to +11
/** Override the default compute unit limit (400_000). */
computeUnitLimit?: number | undefined

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Move computeUnitLimit before priorityFee.

ESLint’s perfectionist/sort-interfaces rule requires the new property to precede priorityFee; move the documentation and field above line 9 to avoid the lint failure.

🧰 Tools
🪛 ESLint

[error] 11-11: Expected "computeUnitLimit" to come before "priorityFee"

(perfectionist/sort-interfaces)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/umi/sendOptions.ts` around lines 10 - 11, Reorder the
computeUnitLimit property and its documentation in the send options interface so
they appear before priorityFee, satisfying the perfectionist/sort-interfaces
ordering rule without changing the property definition.

Source: Linters/SAST tools

Comment on lines +12 to +14
/** Default above Solana's 200k so heavier Metaplex txs (e.g. Genesis create) don't flake. */
const DEFAULT_COMPUTE_UNIT_LIMIT = 400_000

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Repository files matching sendTransaction.ts:\n'
fd -a 'sendTransaction\.ts$' . || true

file="$(fd 'sendTransaction\.ts$' . | head -n 1 || true)"
if [ -n "$file" ]; then
  printf '\nFile: %s\n' "$file"
  wc -l "$file"
  printf '\nRelevant file contents:\n'
  cat -n "$file"
fi

printf '\nSearch for DEFAULT_COMPUTE_UNIT_LIMIT and priorityFee handling:\n'
rg -n "DEFAULT_COMPUTE_UNIT_LIMIT|computeUnitLimit|priorityFee|priorityFeeMicroLamports|computeBudget" .

Repository: metaplex-foundation/cli

Length of output: 4048


🌐 Web query:

Solana priority fees computed based on requested compute unit limit documentation

💡 Result:

On the Solana network, the prioritization fee is calculated based on the requested compute unit (CU) limit, not the actual number of compute units consumed by the transaction execution [1][2][3]. The formula for calculating the prioritization fee is: priority_fee = ceil(compute_unit_price * compute_unit_limit / 1,000,000) In this formula: - compute_unit_price: The price in micro-lamports per compute unit, set using the SetComputeUnitPrice instruction [1][2]. - compute_unit_limit: The maximum number of compute units the transaction is allowed to consume, set using the SetComputeUnitLimit instruction [1][2]. - 1,000,000: The conversion factor (micro-lamports per lamport) [2][4]. - ceil: The result is rounded up to the nearest whole lamport [2][3]. Key Considerations: - Requested vs. Actual: Because the fee is charged based on the requested limit, setting a limit significantly higher than necessary will result in overpayment [1][2][5]. - Defaults: If a transaction does not explicitly include a SetComputeUnitLimit instruction, the network uses a default limit based on the number and type of instructions in the transaction (e.g., 200,000 CUs for each non-builtin instruction) [2][4][6]. - Optimization: To minimize fees while ensuring transaction success, it is recommended to simulate the transaction to determine the actual CU usage, then set the compute unit limit to that value plus a small margin of error [5][3].

Citations:


Avoid using the 400k fallback as the priority-fee budget for every transaction.

Lines 37-46 apply DEFAULT_COMPUTE_UNIT_LIMIT whenever computeUnitLimit is omitted, and then charge priorityFee per requested CU. Solana bases priority fees on the requested CU limit, so lighter transactions can overpay; use a tighter per-transaction estimate or require an explicit limit when priority fees are enabled.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib/umi/sendTransaction.ts` around lines 12 - 14, Avoid using
DEFAULT_COMPUTE_UNIT_LIMIT as the implicit priority-fee budget in
sendTransaction when computeUnitLimit is omitted. Use a tighter
transaction-specific compute-unit estimate, or require an explicit
computeUnitLimit whenever priorityFee is enabled, while preserving the existing
default only for transactions without priority fees.

Source: MCP tools

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