RFC: Reference-Ordered PTB Commands — Unlocking Composable Transaction Building #1017
Replies: 3 comments 2 replies
-
|
Questions:
Complexity and backwards compatibility are big concerns here. We try really hard to avoid breaking changes where possible, and when they are needed we try to batch them together so bigger migrations are less frequent. The This is also a much more complex issue than it might appear at a surface level, and also has security and debugging implications that need careful consideration in the design.
To move forward with this, we'd a very detailed understanding of the full set of changes required, and exactly how this interacts with many different parts of the system including:
I am very confident this is not something an LLM would do well, and would be very hesitant to spend any significant time reviewing a mostly llm derived solution to these problems. I think doing this well is probably multiple months of effort and iteration (first solutions to these kinds of problems always need revision or redesigns). And the complexity involved here is why it did not happen as part of the 2.0 release.
There are no real blockers on these changes, but many pain points that could be made simpler if this was handled properly (mostly similar to what's mentioned in the original issue). We have some use cases that are overly complex today, that should be made simpler:
|
Beta Was this translation helpful? Give feedback.
-
|
Thanks for the response, Hayes — really appreciate the depth. Hearing you clearly: the ref-ordering redesign is complex, touches six load-bearing surfaces, not urgent. Parking the full design. The transforms+caches direction is really cool — it makes all three pain points collapse into the same shape. Looking forward to seeing where you take it. Hoping to help out with the three pain points. |
Beta Was this translation helpful? Give feedback.
-
|
Hey Hayes — thanks again for the steer on those three pain points. I took a swing at #1 (coin/balance intent substitution). Two questions before I open a PR:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
TL;DR
In
Transaction.ts, there's a TODO comment (introduced in SDK v2 Release, lines 94-96):I'd like to explore what this foundational change would enable.
Once transaction results are symbolic until build-time, the SDK could:
Questions:
Happy to contribute research, RFC drafting, or a proof-of-concept if this direction is welcome.
The Current State
Today, when you call:
The
coinvariable receives aTransactionResultwith a concrete command index. Internally, its shape is:The index is determined at declaration time — specifically, it's
this.#data.commands.length - 1at the moment the command is added (seeTransaction.tsline 478).This means the moment you reference that result in another command, you've implicitly committed to an execution order. The SDK processes commands largely in declaration order, with some handling for async thunks, but the fundamental ordering is fixed at declaration time.
The Composition Problem
Consider two protocol SDKs trying to interoperate.
(Note: These are simplified illustrative examples, not actual protocol APIs.)
Protocol A provides a swap helper:
Protocol B provides a deposit helper:
A developer composes them:
But then they realize they need to add a borrow operation that should logically come before the swap:
The developer is stuck. The indices were baked in when each command was declared. They can't insert a command at position 0 without manually rewriting every
Resultreference in the transaction.This is why composing transaction fragments from multiple protocol SDKs is fragile today — each SDK bakes in concrete indices, and combining them requires careful coordination of declaration order.
The Vision: Reference Ordering
What if transaction results were symbolic until build time?
(Note: The syntax below is illustrative — it shows what a reference-based API could look like, not current SDK behavior.)
Now developers could declare commands in any order that makes sense for their code:
What would happen at build time:
Dependency analysis — The SDK traces which commands consume which results:
depositdepends onswap(it usesoutputCoin)borrowhas no dependency on eitherTopological sort — Find valid execution orders that respect dependencies:
[borrow, swap, deposit]✓[swap, borrow, deposit]✓[swap, deposit, borrow]✓[deposit, swap, ...]✗ (violates dependency)Index assignment — Pick a valid order and assign concrete indices
Reference resolution — Replace all symbolic references with concrete indices
The developer never had to think about command ordering. They declared what they wanted, and the SDK figured out a valid execution sequence.
Error handling: If references create a circular dependency (A depends on B, B depends on A), the SDK would fail at build time with a clear error message.
What This Foundation Would Enable
Once the SDK has a dependency graph instead of a flat command list, it enters "compiler" territory. The first step (reference ordering) is the foundation; these are potential future capabilities it would unlock:
1. Composable Transaction Fragments
Protocol SDKs could provide transaction "building blocks" that compose naturally:
Today this is fragile because of index coordination. With reference ordering, each protocol SDK could operate independently.
2. Dead Code Elimination (Future Possibility)
If a command's result is never consumed, a future optimization pass could detect and remove it:
3. Command Deduplication (Future Possibility)
Identical commands with identical inputs could potentially be merged:
4. Transaction Templates (Future Possibility)
With symbolic references, parameterized transaction templates become conceivable:
5. Debugging & Visualization
The dependency graph IS the execution plan. Future tooling could expose it:
The Architectural Principle
This pattern — delaying commitment from declaration to build time — is the same architectural move that:
Declarative systems that defer commitment can perform analysis and optimization that imperative systems cannot.
Summary
PTBs are Sui's signature innovation — atomic, composable, multi-step transactions. The TODO comment in
Transaction.tsidentifies a foundational improvement: making transaction results reference-based rather than index-based.This change would:
The first step is the foundation. Everything else builds on it.
I'm happy to contribute RFC drafting, migration path analysis, or a proof-of-concept implementation if this direction is welcome.
Beta Was this translation helpful? Give feedback.
All reactions