Skip to content

Conversation

@stringhandler
Copy link
Contributor

@stringhandler stringhandler commented Nov 7, 2025

Summary by CodeRabbit

  • Documentation
    • Added a comprehensive technical specification for Tapplets: a sandboxed plugin framework for privacy-preserving on-chain data apps with isolated child accounts, scriptable logic, and registry-driven distribution.
    • Includes a worked example (password manager), CLI/test scaffolding, manifest/implementation guidance, and end-to-end storage/retrieval usage scenarios.

@stringhandler stringhandler requested a review from Copilot November 7, 2025 10:32
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR introduces TIP-XXXX, a comprehensive proposal for Tapplets - a sandboxed plugin system that enables privacy-preserving decentralized applications on the Tari blockchain. The proposal defines how developers can build wallet extensions using Lua scripting to store and retrieve encrypted data on-chain via transaction memo fields.

Key changes:

  • Defines the Tapplet architecture including child account system, key derivation using BLAKE2b-512, and data storage format
  • Specifies Lua-based API interface with sandboxing requirements and permission system
  • Establishes Git-based registry system for tapplet distribution and versioning

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

let memo3 = r#"t:"slot3","multiline\nvalue""#;

assert_eq!(parse_tapplet_memo("slot1", memo1), Some("simple value"));
assert_eq!(parse_tapplet_memo("slot2", memo2), Some(r#"value with "quotes""#));
Copy link

Copilot AI Nov 7, 2025

Choose a reason for hiding this comment

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

The expected return value appears incorrect. Based on the specification (line 105), double quotes are escaped using two double quotes (CSV format). If the memo is "value with ""quotes""", the parsed result should be value with "quotes" (with the doubled quotes converted to single quotes), not value with "quotes" with backslash escaping.

Copilot uses AI. Check for mistakes.
stringhandler and others added 2 commits November 7, 2025 12:43
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@coderabbitai
Copy link

coderabbitai bot commented Nov 7, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Adds TIP-XXXX.md: a new design spec for Tari Tapplets — a Lua-based, sandboxed plugin framework using derived child accounts, memo-field on-chain storage, BLAKE2b-512 view key derivation, and a registry-driven distribution and installation workflow. Includes API, manifest format, transaction flows, tests, and examples.

Changes

Cohort / File(s) Summary
Design Document
tips/TIP-XXXX.md
New design document describing Tari Tapplets: child account derivation and single-table-inheritance model, BLAKE2b-512 tapplet view key derivation, memo-field data format (t:"<slot>","<value>"), sandboxed Lua API (MinotariTappletApiV1 with append_data/load_data_entries), manifest (manifest.toml) and implementation.lua layout, registry-based deployment/installation flow, transaction protocol for storage/retrieval, security model, test scenarios, CLI commands, and example password manager tapplet.

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Wallet
  participant Registry
  participant Blockchain
  participant TappletSandbox

  rect rgb(230,245,255)
    User->>Wallet: install tapplet (manifest or registry ref)
    Wallet->>Registry: fetch manifest & implementation
    Registry-->>Wallet: manifest + implementation.lua
  end

  rect rgb(245,255,230)
    User->>Wallet: execute tapplet action (write/read)
    Wallet->>TappletSandbox: run implementation.lua (MinotariTappletApiV1)
    TappletSandbox->>Wallet: API calls (append_data/load_data_entries)
    Wallet->>Blockchain: submit tx with memo entries (t:"slot","value")
    Blockchain-->>Wallet: confirm tx (view key derived via BLAKE2b-512)
    Wallet->>TappletSandbox: deliver retrieved entries
    TappletSandbox-->>User: operation result
  end

  note over Wallet,Blockchain: Keys: derived child accounts + tapplet view key
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Areas requiring extra attention:

  • Cryptographic key-derivation details (BLAKE2b-512 usage, separators, truncation)
  • Memo data encoding/decoding rules and edge cases (escaping, size limits)
  • Security and isolation model for sandboxed Lua API and allowed syscalls
  • Transaction protocol interactions and failure modes (partial writes, reorgs)
  • Registry trust model, manifest validation, and permissions semantics

Poem

I nibble at memos, keys soft and bright,
Lua scrolls whisper in sandboxed light,
Child accounts hop where secrets reside,
A registry trail to install and guide,
Rabbit-approved tapplets—privacy's delight 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: tapplets v2 specification' accurately summarizes the main change: adding a new design document (TIP-XXXX.md) that specifies the tapplets v2 framework.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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 and usage tips.

stringhandler and others added 3 commits November 7, 2025 12:46
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
tips/TIP-XXXX.md (3)

210-210: Correct GitHub brand capitalization.

The text uses lowercase "Github" but the official brand name is "GitHub" with capital H.

Apply this diff:

-A default registry should be hosted in the Tari Github organization, but other registries can be added by the user at their own risk.
+A default registry should be hosted in the Tari GitHub organization, but other registries can be added by the user at their own risk.

425-436: Align test memo escape handling with CSV specification.

The test at line 428 uses backslash escaping (\"), but the specification (line 104) explicitly states quotes should be escaped using CSV format (doubled double quotes). These formats conflict.

Apply this diff to align the test with the CSV-based specification:

-    let memo2 = r#"t:"slot2","value with \"quotes\"""#;
+    let memo2 = r#"t:"slot2","value with ""quotes"""#;
-    assert_eq!(parse_tapplet_memo("slot2", memo2), Some(r#"value with "quotes""#));
+    assert_eq!(parse_tapplet_memo("slot2", memo2), Some("value with \"quotes\""));

This ensures the test uses CSV-style escaping consistent with line 104's specification.


95-98: Clarify the regex pattern to dynamically capture slot names.

The pattern ^t:"<slot>","((?s:.*?))"$ uses <slot> as a literal placeholder, but the format specification on line 92 shows <slot_name> as a variable. The regex should capture the actual slot name dynamically.

Apply this diff to fix the regex pattern:

-^t:"<slot>","((?s:.*?))"$
+^t:"([^"]+)","((?s:.*?))"$

This pattern captures any slot name (group 1) and the value (group 2), ensuring dynamic matching across all slots.

🧹 Nitpick comments (4)
tips/TIP-XXXX.md (4)

45-45: Add hyphen to compound adjective.

"Domain specific" should be hyphenated as a compound adjective modifying "hash."

Apply this diff:

-derived from a domain specific hash of the account viewkey and the tapplet's public key.
+derived from a domain-specific hash of the account viewkey and the tapplet's public key.

72-72: Add hyphen to compound adjective.

"User specific" should be hyphenated as a compound adjective modifying "password."

Apply this diff:

-In this case, the tapplet view key can also be derived by including a user specific password.
+In this case, the tapplet view key can also be derived by including a user-specific password.

106-106: Prefer "in the future" over "in future" (American English convention).

The phrase "in future" is British English. For consistency with American English documentation, use "in the future."

Apply this diff:

-> Note: in future, binary memos may be stored as well.
+> Note: in the future, binary memos may be stored as well.

3-3: Address markdown linting issues for consistency and readability.

Several markdown formatting issues were flagged:

  • Missing language identifiers on fenced code blocks (lines 3, 52, 73, 91, 222)
  • Heading level jumps that skip h3 when h2 is expected (lines 22, 42, 265)

These don't affect meaning but reduce consistency and accessibility.

Examples:

  • Line 3: Add language specifier: ```metadata or similar
  • Line 22: Change #### Objectives to ### Objectives
  • Line 52, 73, 91, 222: Specify code block languages (e.g., ```bash, ```rust, ```toml, ```lua)

This will improve document structure and make code blocks syntax-highlighted properly in renderers.

Also applies to: 22-22, 42-42, 52-52, 73-73, 91-91, 222-222, 265-265

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0834716 and 32e0adc.

📒 Files selected for processing (1)
  • tips/TIP-XXXX.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
tips/TIP-XXXX.md

[grammar] ~45-~45: Use a hyphen to join words.
Context: ...d using a viewkey derived from a domain specific hash of the account viewkey and...

(QB_NEW_EN_HYPHEN)


[grammar] ~72-~72: Use a hyphen to join words.
Context: ... can also be derived by including a user specific password. ``` tapplet_view_key...

(QB_NEW_EN_HYPHEN)


[grammar] ~82-~82: Ensure spelling is correct
Context: ... password ) ``` Future installs of the tapplet would require knowledge of the password...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~84-~84: Ensure spelling is correct
Context: ...tential use would be a password manager tapplet. Using a master password, the user can ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[locale-violation] ~106-~106: The phrase ‘in future’ is British English. Did you mean: “in the future”?
Context: ...ically matches the CSV format. > Note: in future, binary memos may be stored as well. #...

(IN_FUTURE)


[uncategorized] ~210-~210: The official name of this software platform is spelled with a capital “H”.
Context: ...t registry should be hosted in the Tari Github organization, but other registries can ...

(GITHUB)


[grammar] ~321-~321: Ensure spelling is correct
Context: ...- Immutable but cannot remove malicious tapplets - May be considered for future versions ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
tips/TIP-XXXX.md

3-3: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


22-22: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


42-42: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


52-52: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


73-73: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


91-91: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


222-222: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


265-265: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (1)
tips/TIP-XXXX.md (1)

210-210: Fix brand name capitalization: "Github" → "GitHub".

The official name is GitHub (capital H). This appears as an unresolved comment from previous review.

-A default registry should be hosted in the Tari Github organization, but other registries can be added by the user at their own risk.
+A default registry should be hosted in the Tari GitHub organization, but other registries can be added by the user at their own risk.
🧹 Nitpick comments (6)
tips/TIP-XXXX.md (6)

45-45: Use hyphenated compound adjectives: "domain specific" → "domain-specific".

Per LanguageTool grammar rules, compound adjectives before a noun should be hyphenated.

-derived from a domain specific hash of the account viewkey and the tapplet's public key.
+derived from a domain-specific hash of the account view key and the tapplet's public key.

Note: This also corrects "viewkey" → "view key" (two words) for consistency with lines 55–56 and line 70.


72-72: Use hyphenated compound adjectives: "user specific" → "user-specific".

-This can be addressed by adding a password for installing a tapplet. In this case, the tapplet view key can also be derived by including a user specific password.
+This can be addressed by adding a password for installing a tapplet. In this case, the tapplet view key can also be derived by including a user-specific password.

106-106: Use standard English phrasing: "in future" → "in the future".

-> Note: in future, binary memos may be stored as well.
+> Note: in the future, binary memos may be stored as well.

3-3: Add language specifiers to fenced code blocks for proper syntax highlighting.

Markdown best practice (enforced by markdownlint): all fenced code blocks should declare their language.

Examples:

  • Line 3: \``` should be ```yaml (for TOML/metadata block)
  • Line 52: \``` should be ```text or `` ```plaintext `` (for the hash derivation formula)
  • Line 73: \``` should be ```text (for the password variant)
  • Line 91: \``` should be ```text (for the storage format)
  • Line 222: \``` should be ```text (for the directory tree)

Also applies to: 52-52, 73-73, 91-91, 222-222


22-22: Fix heading level hierarchy: h4 (####) should be h3 (###).

Markdown convention (MD001): heading levels should increment by one at a time. Currently jumping from h2 (##) to h4 (####).

-#### Objectives
+### Objectives

-#### 1. Child Account System (Single Table Inheritance)
+### 1. Child Account System (Single Table Inheritance)

-#### Lua vs WASM
+### Lua vs WASM

This improves document structure and outline generation.

Also applies to: 42-42, 265-265


72-86: Consider additional clarity on optional vs. mandatory password-based key derivation.

Lines 72–86 describe an optional password-based derivation for security in custodial scenarios, but the spec does not clarify:

  • Is this an implementation choice per wallet, or a per-tapplet declaration in the manifest?
  • Does the registry indicate whether a tapplet uses password-derived keys?
  • What happens if a user installs without a password and later wants to enable it?

This is not a blocking issue if intentionally left flexible, but document it explicitly to guide implementers.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 32e0adc and 28b186b.

📒 Files selected for processing (1)
  • tips/TIP-XXXX.md (1 hunks)
🧰 Additional context used
🪛 LanguageTool
tips/TIP-XXXX.md

[grammar] ~45-~45: Use a hyphen to join words.
Context: ...d using a viewkey derived from a domain specific hash of the account viewkey and...

(QB_NEW_EN_HYPHEN)


[grammar] ~72-~72: Use a hyphen to join words.
Context: ... can also be derived by including a user specific password. ``` tapplet_view_key...

(QB_NEW_EN_HYPHEN)


[grammar] ~82-~82: Ensure spelling is correct
Context: ... password ) ``` Future installs of the tapplet would require knowledge of the password...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~84-~84: Ensure spelling is correct
Context: ...tential use would be a password manager tapplet. Using a master password, the user can ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[locale-violation] ~106-~106: The phrase ‘in future’ is British English. Did you mean: “in the future”?
Context: ...ically matches the CSV format. > Note: in future, binary memos may be stored as well. #...

(IN_FUTURE)


[uncategorized] ~210-~210: The official name of this software platform is spelled with a capital “H”.
Context: ...t registry should be hosted in the Tari Github organization, but other registries can ...

(GITHUB)


[grammar] ~321-~321: Ensure spelling is correct
Context: ...- Immutable but cannot remove malicious tapplets - May be considered for future versions ...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

🪛 markdownlint-cli2 (0.18.1)
tips/TIP-XXXX.md

3-3: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


22-22: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


42-42: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)


52-52: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


73-73: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


91-91: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


222-222: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


265-265: Heading levels should only increment by one level at a time
Expected: h3; Actual: h4

(MD001, heading-increment)

🔇 Additional comments (1)
tips/TIP-XXXX.md (1)

1-521: Document is well-structured and comprehensive.

The specification is clear on:

  • Child account model and key derivation strategy
  • Data storage format (memo field with CSV-like escaping)
  • API surface (append_data, load_data_entries)
  • Manifest and Lua tapplet structure
  • Transaction protocol and registry system
  • Backwards compatibility (no consensus changes)
  • Test cases and end-to-end workflows

Strengths: clear rationale for design decisions (Lua vs WASM, memo fields vs custom output types), security considerations documented (view key sharing risks, isolation), and concrete examples provided.

Once the critical language on line 66 is resolved and minor grammar/formatting issues are addressed, this is ready for adoption.

Comment on lines +37 to +38
> Note that tapplets are different from smart contracts. Smart contract allow executing logic on Tari validator nodes. Tapplets allow
execution of custom logic on a wallet client. In most cases these will be adapters that decode and present data stored in transaction fields.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix subject-verb agreement: "Smart contract allow" → "Smart contracts allow".

-> Note that tapplets are different from smart contracts. Smart contract allow executing logic on Tari validator nodes. Tapplets allow 
+> Note that tapplets are different from smart contracts. Smart contracts allow executing logic on Tari validator nodes. Tapplets allow
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> Note that tapplets are different from smart contracts. Smart contract allow executing logic on Tari validator nodes. Tapplets allow
execution of custom logic on a wallet client. In most cases these will be adapters that decode and present data stored in transaction fields.
> Note that tapplets are different from smart contracts. Smart contracts allow executing logic on Tari validator nodes. Tapplets allow
execution of custom logic on a wallet client. In most cases these will be adapters that decode and present data stored in transaction fields.
🤖 Prompt for AI Agents
In tips/TIP-XXXX.md around lines 37 to 38, fix the subject-verb agreement in the
sentence "Smart contract allow executing logic on Tari validator nodes." by
changing "Smart contract allow" to "Smart contracts allow" so the plural subject
matches the plural verb; update the sentence accordingly and verify surrounding
punctuation and spacing remain correct.

- Data is isolated from other tapplets
- Only those with both parent keys and tapplet public key can decrypt

> NOTE: The tapplet registry should maybe also be included, so that malicious developers cannot reuse the `tapplet_public_key` across multiple tapplet registrations. Including the registry identifier in the key derivation ensures that each tapplet's view key is unique, even if the same public key is used elsewhere.
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

CRITICAL: Resolve the uncertain language on registry inclusion in key derivation.

This note contains tentative language ("should maybe also be included") for a security-critical design decision. A specification this fundamental cannot remain ambiguous. Either:

  1. Make it mandatory if the security risk of key reuse across registries is a real concern, or
  2. Explicitly defer with clear documentation of the known security risks and a timeline for revisiting.

Based on the stated concern (preventing malicious key reuse across registry instances), this should be a definitive requirement:

-NOTE: The tapplet registry should maybe also be included, so that malicious developers cannot reuse the `tapplet_public_key` across multiple tapplet registrations. Including the registry identifier in the key derivation ensures that each tapplet's view key is unique, even if the same public key is used elsewhere.
+NOTE: The tapplet registry identifier MUST be included in the key derivation to prevent malicious developers from reusing the `tapplet_public_key` across multiple tapplet registrations. This ensures each tapplet's view key is unique per registry and prevents cross-registry impersonation attacks.

Alternatively, if this is intentionally deferred to v2, change to: "Deferred (v2): Future versions will include registry identifiers in key derivation to prevent..."


I need to verify the actual file and content. Let me search the repository:


---

🏁 Script executed:

```shell
#!/bin/bash
# Find the TIP file and examine the flagged lines
fd -e md 'TIP' tips/ 2>/dev/null | head -5

Length of output: 50


🏁 Script executed:

#!/bin/bash
# If file found, examine the context around line 66 and other flagged lines
fd -type f -name 'TIP*.md' tips/ -x cat {} \; 2>/dev/null | head -100

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Search for tips directory structure
find . -type d -name tips 2>/dev/null

Length of output: 6



---

🏁 Script executed:

```shell
#!/bin/bash
# Read the entire TIP-XXXX.md file
cat tips/TIP-XXXX.md

Length of output: 18540


Resolve uncertain language in security-critical key derivation specification.

The review comment correctly identifies a genuine issue at line 66. The phrase "should maybe also be included" is inappropriate for a security specification where the registry identifier's role in preventing cross-registry key reuse attacks is a definitive design decision.

The file contains additional related issues that should be addressed concurrently:

  • Line 210: "Github" → "GitHub"
  • Line 37-38: "Smart contract allow" → "Smart contracts allow"
  • Line 45: "domain specific" → "domain-specific"
  • Line 72: "user specific" → "user-specific"

For line 66 specifically, either commit to the security requirement (use "MUST") or explicitly mark as deferred with clear timeline, per the suggested rewrites in the review comment.

🤖 Prompt for AI Agents
tips/TIP-XXXX.md lines 66, 72, 210, 37-38, 45: The wording on line 66 is
indecisive for a security-critical key derivation; replace "should maybe also be
included" with a definitive requirement (e.g., "MUST include the tapplet
registry identifier in the key derivation to prevent cross-registry key reuse")
or explicitly mark the change as deferred and provide a clear decision timeline;
also fix the other issues in the same file: change "user specific" to
"user-specific" on line 72, "Github" to "GitHub" on line 210, "Smart contract
allow" to "Smart contracts allow" on lines 37-38, and "domain specific" to
"domain-specific" on line 45.

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.

1 participant