feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all \u003cpre\u003e\u003ccode\u003e blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks"); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length \u003e 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat: support muxed (M…) source accounts in the contract invoke pipeline - #2694

Open
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke
Open

feat: support muxed (M…) source accounts in the contract invoke pipeline#2694
Galmanus wants to merge 1 commit into
stellar:mainfrom
Galmanus:fix/2645-muxed-source-invoke

Conversation

@Galmanus

Copy link
Copy Markdown

What

contract invoke --source-account M… and token transfer --from M… now work end-to-end (simulate → sign → submit). The shared invoke pipeline's sequence-number lookup uses the source's underlying G… account id (MuxedAccount::account_id()) instead of handing the M… strkey to a G-only ed25519 parser. The up-front token transfer guard for muxed sources is removed.

Why

Fixes#2645. Only the underlying account exists on ledger, so the get_account lookup at invoke.rs:352 aborted with a raw strkey DecodeError for any muxed source.

One deviation from the issue's direction, with evidence

The issue suggests the muxed form should keep flowing into the SEP-41 transfer(from, …) argument. Empirically the host rejects that: on a protocol-27 quickstart, a muxed from fails simulation with HostError: Error(Value, UnexpectedType) — consistent with muxed accounts not being valid authorizers (see the ruling in #2534), and from must require_auth. So token transfer resolves a muxed --from to its underlying G… account for the transfer argument, while a muxed --to still flows through as-is and preserves the mux id in the argument and events. Happy to adjust if there's a supported way to carry the mux id on the from side.

Testing

Against a local protocol-27 quickstart:

  • invoke_with_muxed_source_accountcontract invoke --source-account M… --sign-with-key test --send=yes succeeds end-to-end (an M-literal carries no secret, so signing goes through the identity, per the issue's acceptance note).
  • transfer_from_muxed_sourcetoken transfer --from M… --sign-with-key test succeeds and moves the balance (replaces the previous muxed-rejection test).
  • Full integration::token::transfer suite: 9 passed. cargo clippy -p soroban-cli and cargo fmt --check clean.

CopilotAI balanced review requested due to automatic review settings August 22, 2026 10:35
@github-project-automationgithub-project-automationBot moved this to Backlog (Not Ready) in DevXAug 22, 2026

CopilotAI 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.

Pull request overview

Adds end-to-end muxed source-account support to contract invocation and token transfers.

Changes:

  • Uses the underlying G… account for sequence lookup and transaction sourcing.
  • Resolves muxed transfer senders to their underlying authorizing account.
  • Adds integration coverage for muxed contract invocation and token transfers.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

FileDescription
cmd/soroban-cli/src/commands/token/transfer.rsSupports muxed --from accounts.
cmd/soroban-cli/src/commands/contract/invoke.rsFixes sequence lookup for muxed sources.
cmd/crates/soroban-test/tests/it/integration/token/transfer.rsTests transfers from muxed sources.
cmd/crates/soroban-test/tests/it/integration/hello_world.rsTests invocation with a muxed source.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

The shared invoke pipeline handed the source account's strkey to a G-only
ed25519 parser when looking up the sequence number, so `contract invoke
--source-account M…` (and `token transfer --from M…`) aborted with a raw
strkey DecodeError. Only the underlying account exists on ledger, so the
lookup now uses the source's underlying G… account id.
`token transfer` no longer rejects a muxed `--from` up front. The `from`
argument resolves to the underlying G… account: `from` must authorize the
transfer, muxed accounts are not valid authorizers, and the host rejects a
muxed `from` in simulation with `Error(Value, UnexpectedType)`. A muxed
`--to` still flows through as-is, preserving the mux id.
Fixesstellar#2645
@Galmanus
Galmanusforce-pushed the fix/2645-muxed-source-invoke branch from 98cbde2 to 70f6642CompareSeptember 1, 2026 23:05
CopilotAI review requested due to automatic review settings September 1, 2026 23:05

CopilotAI 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.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

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

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

Support muxed (M…) source accounts in the contract invoke pipeline

2 participants

@Galmanus