Skip to content

test(svm): add real Gateway V5 conformance (ACP-184 Step 5) - #1544

Merged
Reinis-FRP merged 7 commits into
epic-v5/svmfrom
reinis/acp-184-step-5-gateway-integration
Sep 30, 2026
Merged

Reinis-FRP merged 7 commits into
epic-v5/svmfrom
reinis/acp-184-step-5-gateway-integration

Conversation

@Reinis-FRP

@Reinis-FRP Reinis-FRP commented Sep 8, 2026 •

Copy link
Copy Markdown
Contributor

Scope

ACP-184 Step 5, targeting epic-v5/svm: real-Gateway integration tests, cross-VM fixtures, and docs. No production contract or packaged IDL/client changes.

  • Pin Gateway/PrefundedAdapter to solana-v5@457cf693 and run an isolated validator.
  • Cover source funding, destination delivery, root binding/reuse, replay, payer lifecycle, malformed accounts, and rollback.
  • Document unsafe short/aggregate delivery cases. The delivery policy is shared with EVM, not a new SVM-only security requirement.

Follow-ups

  • ACB-637: API builder port and applicable conformance tests; ACB-863 was consolidated here.
  • ENG-320: SVM relayer integration checks, reusing EVM policy.
  • Validate supported paths before SVM Across route enablement. Neither issue blanket-blocks ACP-184; no new generic validator or aggregation project is requested.
  • Run yarn test-svm-gateway locally with access to the pinned checkout. Ordinary CI runs the two dependency-free wire/hash checks and includes test/svm-gateway/** in the SVM path filter; it does not run the real-Gateway lane or use cross-repository credentials.
  • Public Gateway/Prefunded binaries and matching IDLs are a separate follow-up. Hosting is undecided; the development repository need not become public. Once immutable artifacts with reviewed checksums and source/program-ID provenance are available, adapt the runner and enable credential-free CI. Rebuilding a pinned public source snapshot is another option.

Validation

At 4eb7bbb8:

  • Local real-Gateway lane: 16/16; mock/foundation tests: 18/18; standalone wire/hash vectors: 2/2. Focused TypeScript and formatting checks pass; normal commit hooks pass on Node 22.18.0.
  • Droplet's recheck: Rust 13/13 and Foundry vectors 5/5; all 16 review threads addressed. Ihor's four threads remain open for him to close.
  • Current CI is green, including verified SVM, EVM tests, TypeScript, lint/generated-file checks, and DCO.

Review fixes include self-contained provider initialization, shared Spoke encoders with independent golden-vector checks, IDL-backed Gateway/Prefunded instructions, and consolidated docs. Earlier buffer-cleanup, failed-receipt, replay, and malformed-input assertions remain covered.

The local compiler reports stack-size diagnostics in unchanged legacy fill handlers; this V5 lane does not exercise or certify those handlers. Verified-build checks remain separate.

@linear

linear Bot commented Sep 8, 2026 •

Copy link
Copy Markdown

ACP-184

ACB-863

ENG-320

ACB-637

@droplet-rl droplet-rl 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.

Summary

Reviewed at 2d4155ab against base reinis/acp-184-step-4-destination-fill (13 files, +1211/-0). This is genuinely test/docs/CI-only: the programs/svm-spoke/src/v5.rs addition sits inside the #[cfg(test)] mod tests block at line 341, package.json only gains a script, and no packaged IDL/client is touched. Scope matches the description.

The suite is strong. What I like in particular:

  • It derives destination relays from actual origin FundsDeposited events rather than hand-built RelayData, so the deposit-ID derivation, the V5_MAGIC_PREFIX || stepId witness, and get_relay_hash are exercised end-to-end against the real Gateway instead of being restated in the test.
  • The account-authentication cases are meaningful, not tautological. relayJit(relay, wrong) / relayJit(relay, status, wrong) fail with MissingAccount because load_v5_fill_accounts re-derives V5FillStatusPdas and the real PDA is not in the forwarded set — which is precisely the property that makes the outer remaining-account pool safe. Adding wrong to the pool via extra and still getting a rejection is the right way to pin "pool membership does not equal forwarding."
  • Deliberately keeping the unsafe primitives (short consumption, two fills over one balance, floor-of-committed-minima with larger JIT outputs) as passing counterexamples rather than pretending the program enforces delivery is the honest framing, and the spec/README text around it is accurate w.r.t. v5_adapter.rs:196 (source.amount >= output_amount is an assertion, not a debit).
  • Good separation from the mock lane: InsufficientVaultBalance, allowance, pause, Token-2022 extension and exclusivity cases already live in test/svm/SvmSpoke.V5Fill.ts / .V5Source.ts, so this lane doesn't duplicate them.

Independent verification of the new fixture

I re-derived programs/svm-spoke/fixtures/v5_gateway_path.json from scratch (pure-Python Keccak-256, no repo code):

  • pathId, siblingPathId, stepRoot, witness — all four match.
  • executor base58-encodes to 34trBszXuqhRjWaMxXWsunJNmyUsBvDNPxAwTzbPTm4p, i.e. constants::GATEWAY_PROGRAM_ID. Since reference.ts::pathId hardcodes GATEWAY.toBuffer(), the TS assertion transitively pins that too.
  • V5_MAGIC_PREFIX = keccak256("AcrossV5MessagePrefix.V1"), matching the comment at constants.rs:27.
  • The message blob decodes byte-for-byte as the Borsh tape [BALANCE_REQ(mint, 500000), TRANSFER(mint, recipient, u64::MAX, 10000bps)] — op vector 02000000 0011, then two length-prefixed inputs of 0x28 and 0x4a bytes.

The fixture is self-consistent and correctly cross-checked in all three languages.

Main thing I'd like addressed

Nothing here runs in CI, and one piece of it easily could. The lane is workflow_dispatch-only and blocked on an environment/secret that doesn't exist yet (correctly disclosed in the PR body). But PathVectors.ts needs no validator and no private dependency — it's pure hashing — while its Rust and Solidity counterparts do run on every PR. That leaves reference.ts, the encoder most likely to be reused downstream by ACB-637/ENG-320, as the only unpinned side of the vector. Note also that pr.yml's paths-filter matches test/svm/**, which does not match test/svm-gateway/**, so a future PR touching only this directory triggers no SVM job at all. Details inline.

Everything else below is non-blocking: CI hygiene and a few assertions that could be tightened. Not requesting changes — this is test infrastructure with no production surface, and the substance is sound.

Caveat on validation: I could not execute the lane (private solana-v5 + Solana toolchain unavailable here), so I'm relying on your reported 14/14 · 16/16 · 5/5. My review is static analysis plus the independent fixture re-derivation above.

Comment thread test/svm-gateway/PathVectors.ts
Comment thread .github/workflows/svm-gateway.yml Outdated
Comment thread .github/workflows/svm-gateway.yml Outdated
Comment thread test/svm-gateway/RealGateway.ts Outdated
Comment thread test/svm-gateway/RealGateway.ts Outdated
Comment thread test/svm-gateway/RealGateway.ts
Comment thread test/svm-gateway/RealGateway.ts
Comment thread scripts/svm/testRealGateway.ts Outdated
Comment thread scripts/svm/testRealGateway.ts Outdated
Comment thread test/evm/foundry/local/SvmSpokeV5Vectors.t.sol Outdated
@droplet-rl

Copy link
Copy Markdown
Contributor

🔎 View trace

@droplet-rl droplet-rl 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.

Approving

Re-reviewed the delta 2d4155ab..1176c013 (3 commits, 10 files, +109/−108) and re-checked the full PR against base. All ten comments from my previous review are addressed, several more thoroughly than I asked. LGTM.

Fixes verified

Previous comment Resolution
PathVectors.ts never runs in CI New test-svm-gateway-vectors script wired into lint-and-check-generated (pr.yml:104)
paths-filter misses test/svm-gateway/** Added at pr.yml:147
Hardcoded toolchain versions Workflow deleted
Unverified binary download Workflow deleted
Params-buffer leak on setup failure Setup moved inside try — plus a new regression test
FilledRelay event in failed tx not asserted Now decoded from the failed receipt
assert.throws on a local helper assert.equal(delivered, consumed) added
Missing status-PDA assertions after JIT rejections Added at both sites
Hardcoded spoke program ID Read from target/idl/svm_spoke.json
Glob picked up reference.ts/provider.ts Explicit spec file list

Two fixes that went beyond the ask

The failed-receipt event decoding (RealGateway.ts:558-560) is now the real thing. Rather than grepping logs, it calls processEventFromTx(receipt, [spoke]) — which walks meta.innerInstructions and decodes the emit_cpi! self-invoke — then asserts exactly one attempted filledRelay and matches its depositId against the relay. That is precisely the hazard V5_ADAPTER_SPEC.md warns about ("Failed transaction logs may contain attempted fill events"), and the test is now the evidence for it rather than a proxy. I confirmed the signature at solanaProgramUtils.ts:55 accepts a VersionedTransactionResponse, which is what getTransaction(..., {maxSupportedTransactionVersion: 0}) returns.

The new retry test (RealGateway.ts:405-427) is self-verifying, which is the part I like. It patches provider.sendAndConfirm to let the setup instruction land on-chain and then throw, so the buffer genuinely exists when finally runs. Because it wraps expectFailure, a patch that silently failed to match would surface as expected injected setup confirmation failure rather than a false pass. The close instruction correctly escapes the injection (its discriminator doesn't match failAfter), so cleanup still runs inside the patched window, and path([floor(mint, 0n)]) encodes to 177 bytes — one fragment — so both loop branches are reachable. Restoration is in a finally.

Checks I ran

  • OZ Hashes.commutativeKeccak256 — @openzeppelin/contracts is pinned at 5.5.0 and Hashes.sol landed in 5.1.0, so the new import resolves. Swapping the hand-rolled ternary for the canonical helper also documents that the Gateway's sorted-pair rule is the standard commutative hash, and deriving the prefix via keccak256("AcrossV5MessagePrefix.V1") instead of the literal means the Solidity vector now catches constant drift the way the Rust one already did. Both orders asserted in Rust (v5.rs:405-412) and Solidity.
  • The new CI step works on a fresh checkout. lint-and-check-generated does not download SVM artifacts, so I traced the import graph: PathVectors.ts → reference.ts → src/types/svm.ts, which imports only @coral-xyz/anchor, @solana/web3.js and ethers. No target/ or generated-client dependency, and resolveJsonModule is already set. It will run green.
  • No dangling references. Grepped the tree for SVM_GATEWAY_READ_TOKEN, svm-gateway-integration, svm-gateway.yml and linear.app — all clean. Removing the private Linear links from a public repo is the right call; the replacement prose keeps the policy without the unresolvable pointers.
  • v5_gateway_path.json and reference.ts are byte-identical to what I reviewed last round, so my independent Keccak re-derivation of pathId / siblingPathId / stepRoot / witness still holds.

Carrying forward

The toolchain-pinning and binary-integrity concerns I raised were resolved by deleting the workflow rather than by fixing it. They'll be live again when solana-v5 goes public and CI returns — flagged inline on the README so they aren't lost with the file.

Same caveat as last time: I could not execute the real-Gateway lane here (private solana-v5, no Solana toolchain), so the reported 15/15 · 1/1 · 12/12 · 16/16 · 5/5 is taken from the PR description. My verification is static analysis plus the independent fixture derivation.

Comment thread test/svm-gateway/README.md Outdated
Comment thread test/svm-gateway/RealGateway.ts Outdated
@droplet-rl

Copy link
Copy Markdown
Contributor

🔎 View trace

@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 79c0b5d to deb977f Compare September 8, 2026 13:12
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 935b270 to 638afe1 Compare September 8, 2026 13:12
@Reinis-FRP
Reinis-FRP marked this pull request as ready for review September 8, 2026 13:16
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from deb977f to 7d7daaa Compare September 11, 2026 10:48
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 638afe1 to 0c25db4 Compare September 11, 2026 10:48
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 7d7daaa to 6e37e12 Compare September 15, 2026 11:53
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 0c25db4 to 5052d26 Compare September 15, 2026 11:53
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 6e37e12 to b20cf27 Compare September 15, 2026 14:51
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch 2 times, most recently from e5dd925 to 3f78703 Compare September 15, 2026 15:20
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from b20cf27 to 5e18c22 Compare September 15, 2026 15:20
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 3f78703 to e8c4ad5 Compare September 15, 2026 15:27
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 5e18c22 to 5237315 Compare September 15, 2026 15:27
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch 2 times, most recently from 8dad3f4 to f04c2c3 Compare September 16, 2026 14:00
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch 2 times, most recently from 12a0845 to c1f01e2 Compare September 18, 2026 07:35
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch 2 times, most recently from fe3a55d to 50fb8e3 Compare September 22, 2026 08:10
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from c1f01e2 to 93a5d29 Compare September 22, 2026 08:10
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 50fb8e3 to 2215794 Compare September 28, 2026 11:04
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 93a5d29 to 4ea94b0 Compare September 28, 2026 11:04
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from 2215794 to d646de9 Compare September 28, 2026 13:09
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-4-destination-fill branch from 4ea94b0 to 3683986 Compare September 28, 2026 13:09

@fusmanii fusmanii 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.

nice stuff

Base automatically changed from reinis/acp-184-step-4-destination-fill to epic-v5/svm September 28, 2026 18:34
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
@Reinis-FRP
Reinis-FRP force-pushed the reinis/acp-184-step-5-gateway-integration branch from d646de9 to 23277c0 Compare September 28, 2026 18:42
Comment thread test/svm-gateway/provider.ts Outdated

// Set this before SvmSpoke.common constructs anchor.workspace.SvmSpoke; its
// default provider otherwise points at port 8899, not our isolated validator.
setProvider(AnchorProvider.env());

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Remove provider.ts and make provider initialization self-contained.

This creates an import-order dependency: ./provider must run before SvmSpoke.common.ts constructs anchor.workspace.SvmSpoke. The shared fixture should initialize its provider before accessing the workspace:

const provider = anchor.AnchorProvider.env();
anchor.setProvider(provider);
const program = anchor.workspace.SvmSpoke as Program<SvmSpoke>;

That removes the need for this file and its side-effect import. Explicitly passing the provider to a Program constructor would further reduce reliance on global state.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 4eb7bbb8. The shared fixture now sets its provider before accessing the workspace. Removed provider.ts and its side-effect import.


Sent from Reinis Martinsons's Codex CLI Agent using gpt-6-astra 🤖

Comment thread test/svm-gateway/reference.ts Outdated
Comment on lines +66 to +68
export const fillInput = (recipient: PublicKey, mint: PublicKey, minimum: bigint) =>
Buffer.concat([Buffer.from([1]), recipient.toBuffer(), mint.toBuffer(), u64(minimum)]);
export const relayBytes = (r: RelayData) =>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Consolidate duplicated Spoke encoders.

fillInput, relayBytes, and fillJit repeat the encoding already implemented by encodeFill, encodeRelay, and encodeJit in test/svm/SvmSpoke.V5Fill.ts. depositInput similarly repeats the deposit layout in test/svm/SvmSpoke.V5Source.ts.

Extract shared test-only Spoke encoding helpers and reuse them in the mock and real-Gateway suites so wire changes have one implementation to update. Keep the independent golden-vector calculations independent, since those are intended to catch encoding drift.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 4eb7bbb8. Mock and real-Gateway suites now share test/svm/v5Encoding.ts. Independent golden-vector calculations are unchanged; a new check compares the shared encoders against the frozen wire fixture.


Sent from Reinis Martinsons's Codex CLI Agent using gpt-6-astra 🤖

Comment on lines +87 to +88
const ix = (programId: PublicKey, name: string, data: Buffer, keys: AccountMeta[]) =>
new TransactionInstruction({ programId, keys, data: Buffer.concat([discriminator(name), data]) });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Use IDL-based encoding for ordinary instructions when available.

For the pinned Gateway/Prefunded release, prefer Anchor instruction builders backed by its IDLs for ordinary instructions such as initialization, parameter-buffer initialization/writes/closure, execute, and store. This would avoid maintaining instruction discriminators, argument serialization, and fixed account ordering by hand here.

Keep explicit encoders for command tapes and JIT payloads where the IDL exposes opaque bytes. Consuming versioned IDL artifacts would not require importing the foreign Rust workspace.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in 4eb7bbb8. Initialization, buffer initialization/writes/closure, execute, and store now use IDL-backed Anchor builders. For now, IDLs are generated locally from the same pinned checkout as the binaries; public artifact distribution is a separate follow-up.


Sent from Reinis Martinsons's Codex CLI Agent using gpt-6-astra 🤖

The suite covers StepDelegate and prefunded source deposits, standard deposit identities and witnesses, external and
in-place destination delivery, first-fill-wins siblings, root mismatch and reuse, account/dispatch rejection, payer
funding/reclaim/withdrawal, and downstream rollback. Root reuse examples fund and fully deliver each execution.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Consolidate documentation.

The delivery invariants and integration boundary are repeated across this README, programs/svm-spoke/V5_ADAPTER_SPEC.md, and AGENTS.md. Keep the authoritative delivery/security rules in the adapter spec, execution instructions and test coverage in this README, and a brief architectural summary with links in AGENTS.md. Link to the spec for the detailed invariant instead of maintaining multiple versions of the same explanation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 4eb7bbb8. The adapter spec owns delivery/security rules; the README covers execution and test coverage; AGENTS.md has a short summary and links.


Sent from Reinis Martinsons's Codex CLI Agent using gpt-6-astra 🤖

@grasphoper

Copy link
Copy Markdown
Collaborator

Overall, I think this PR could benefit a lot from having a public repo with compiled SVM Gateway & co. contracts + IDLs. I'd try to set that up next and drop the code that works with the 'private repo checkout' from the tests here

Signed-off-by: Reinis Martinsons <reinis@umaproject.org>
@Reinis-FRP

Copy link
Copy Markdown
Contributor Author

Addressed the four inline comments in 4eb7bbb8. Validation: real-Gateway 16/16, mock/foundation 18/18, focused typecheck and formatting pass.

Agree on public Gateway/Prefunded binaries and matching IDLs as the next step. Keeping artifact hosting/publication separate so these fixes do not depend on that decision. The README is hosting-neutral; the existing pinned local build remains until we can consume a public release with reviewed checksums and provenance.


Sent from Reinis Martinsons's Codex CLI Agent using gpt-6-astra 🤖

@Reinis-FRP

Copy link
Copy Markdown
Contributor Author

@droplet-rl , please recheck if all reviews have been properly addressed

@droplet-rl

Copy link
Copy Markdown
Contributor

@Reinis-FRP Yes. All 16 review threads are addressed at 4eb7bbb8. I checked each fix against the code after the rebase onto epic-v5/svm and ran the vector suites locally. Nothing needs changing, so I pushed no commits.

grasphoper's 4 threads: fixed. I left these threads unresolved for grasphoper to close.

  • provider.ts: deleted. SvmSpoke.common.ts now calls anchor.setProvider(provider) before it reads anchor.workspace, so the import order no longer matters.
  • Duplicated encoders: moved into test/svm/v5Encoding.ts. In the mock suites this is purely a move: I compared the deleted local encoders with the new shared ones and they are byte-identical. No test cases were removed. After the rebase, the shared encoders match the base's current schema: DepositV1 = 0 / FillV1 = 1, with no fill message vec. The new PathVectors check compares them against v5_adapter_v1.json, which the Rust tests decode on their own, so the golden vectors are still an independent check.
  • IDL builders: done for initialize, the params buffer (init, write, close), execute and store. They use accountsStrict. Each IDL's address is checked against the pinned program ID. Discriminators now come from the IDL, including in the retry test. IDLs are built into the temporary run directory, not the solana-v5 checkout, so the clean-checkout check still passes on later runs.
  • Doc consolidation: done. AGENTS.md is now a short summary with links. The one rule that only the README had ("terminal outcome acceptable to every deposit matching the root") now lives in the spec, so nothing was lost. The #pda-and-token-invariants anchor resolves.

My 12 threads: all addressed. I resolved the 2 that were still open:

  • The README now records the follow-up CI guidance: reuse setup-solana-anchor and NODE_VERSION, and check any downloaded Anchor binary with sha256sum -c.
  • A successful execute() now returns only { signature }. Diagnostics come back only as failedReceipt, and the first test asserts that property is missing on success.
  • The 10 fixes from the first round survived the rebase: the vectors CI step and path filter, the workflow removal, buffer cleanup inside try, decoding the attempted FilledRelay from the failed receipt, delivered === consumed, the status-PDA assertions, the IDL-derived spoke ID, explicit spec files, and both sibling orders.

Run locally at 4eb7bbb8:

  • yarn test-svm-gateway-vectors: 2/2 passing with no target/ directory, which is how the lint job runs it.
  • cargo test -p svm-spoke --lib: 13/13.
  • Foundry SvmSpokeV5Vectors: 5/5.
  • No production program changes: v5/tests.rs is behind #[cfg(test)].

I still can't run the real-Gateway lane (private solana-v5), so I'm relying on your 16/16 for it.

Optional nits (none blocking):

  • RealGateway.ts:504: the spoke direct-call test is the last hand-built instruction (ix / discriminator). It could use spoke.methods.adapterExecuteAcrossV5(...).
  • The Validation section of the PR description still cites 1ea896d5 and 15/15.

grasphoper's point about public Gateway binaries and IDLs is recorded as a follow-up in the README.

@droplet-rl

Copy link
Copy Markdown
Contributor

🔎 View trace

@Reinis-FRP
Reinis-FRP merged commit a811e44 into epic-v5/svm Sep 30, 2026
7 checks passed
@Reinis-FRP
Reinis-FRP deleted the reinis/acp-184-step-5-gateway-integration branch September 30, 2026 08:17
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.

4 participants