OOTLE Toolchain

Spent the last week building on Ootle. Ran into enough friction along the way that I think it’s worth writing up as concrete asks, not just “better docs please.”

I’m fairly new to the tari L2 stack, so it’s entirely possible some of this already has a documented answer I just didn’t find. Genuinely happy to be corrected on any of it; flagging so the actual gaps (if any) are visible.

  1. A canonical WXTR (wrapped confidential XTR)?

XTR is Stealth-typed, and Stealth (as far as I could tell) is built for private wallet-to-wallet payments, not for a contract holding a hidden balance and unlocking it on its own logic — the engine rejected withdraw_confidential on a Stealth resource outright when I tried. I ended up minting my own wrapper Confidential resource pegged 1:1 to XTR just to get something the engine would let a contract hold sealed. Maybe this is a solved problem and I missed the standard pattern — if there’s already a canonical wrapped-XTR resource or recommended approach, I’d genuinely like to know, because I couldn’t find one.

  1. ootle.ts maintenance cadence

I ran into three bugs in the published SDK blocking basic shield/unshield (a missing required field, a WASM version mismatch, a bundling bug duplicating the WASM instance). Fixed all three locally, filed two upstream PRs — neither has moved yet, but it’s only been a short while and I know maintainer bandwidth is a real constraint. Not trying to call anyone out here, just flagging that if others are hitting the same wall, a maintenance push would help — and if there’s a faster channel to get eyes on SDK PRs than the public issue tracker, pointing me at it would save everyone time

  1. Client-side proof-building for custom Confidential resources

Couldn’t find a published JS/WASM way to build a ConfidentialWithdrawProof for a resource other than XTR. Ended up wrapping the Rust crypto myself. If this exists and I just didn’t find the right package name, please tell me — I’d rather delete my own version than maintain a duplicate.

  1. Moving Stealth funds into a contract call from a connected dApp

Couldn’t get tari_signAndSubmitTransaction to build a transaction that withdraws Stealth funds into a custom contract call — every attempt failed client-side. Ended up adding a new wallet RPC method myself to make it work. Would love to know if there’s an existing supported path for this I missed, since what I built is very much a workaround, not something I’d consider a reference implementation.

  1. Wire format for hand-built instructions

Once I needed to combine wallet-internal instructions with my own (outside the standard TransactionBuilder flow), I couldn’t find documentation for the raw instruction wire format — ended up reading the Rust source directly. If there’s a reference for this beyond the source, pointer appreciated.

  1. Reading the current epoch

Couldn’t find a JSON-RPC method for “what epoch is it right now” — pulled it as a side effect of a transaction receipt instead. Possible this exists under a name I didn’t think to search for.

  1. Testnet block explorer / substate inspector

Did most debugging via raw JSON-RPC dumps. If there’s an explorer for Ootle substates/transactions I missed, that alone would have saved a lot of time — pointer very welcome.

A lot of my friction above was less “missing feature” and more “the mental model wasn’t written down anywhere I could find” — when to reach for Stealth vs Confidential, what the engine auto-discovers vs what you must supply explicitly. A recurring session with the people who built it would probably clear up more in an hour than I worked out over this whole build.

What am I missing?

This is just what I personally hit on one contract, very possibly with existing solutions I didn’t find. If you’re building on Ootle too — what’s tripping you up or what did you find that would’ve saved me the trouble above? Would rather this become an accurate, corrected list than my own uninformed gripes.

1 Like

I hit several of the same gaps while building a local non custodial atomic swap application on Ootle, particularly around using selected account Stealth funds in ScriptPath and contract style transaction flows through walletd.

I ended up building and testing a walletd based proof of concept covering Stealth HTLC funding, hashlock claim, redeem, epoch-based refund, exact fee handling, and terminal/retry safe result handling. I documented the architecture and test results in tari-ootle issue #2343.

The upstream direction I received from Stan was to avoid placing a walletd provider inside ootle-rs. Instead, transaction construction should be separated from wallet approval, signing, and submission, using the canonical CBOR encoded UnsignedTransaction and separately scoped permissions. Explicit wallet-controlled input selection and statement preparation would remain on the wallet side so private keys and owned Stealth information do not leave walletd.

Your new wallet RPC sounds close enough to the path I had to build that comparing the two implementations could be useful. I also found that the individual transaction pieces were often available, but combining a wallet-prepared Stealth operation with custom instructions was not exposed cleanly through the TypeScript tooling.

So no, I do not think you are simply missing obvious documentation. A fair amount of the intended architecture currently has to be reconstructed from the Rust source, issues, and maintainer discussions.

2 Likes

The lack of basic functionality after all this time inspires great confidence

Finally got around to updating ootle.ts 0.2.0 https://www.npmjs.com/package/@tari-project/ootle

To get the epoch: GET /network yeah not super intuitive to find

2 Likes