Skip to content

bindings/node: add Conversation.createExternalInvite NAPI binding#3675

Open
tylerhawkes wants to merge 9 commits into
tyler/qr-invite-l10-create-invitefrom
tyler/qr-invite-b1-napi-create
Open

bindings/node: add Conversation.createExternalInvite NAPI binding#3675
tylerhawkes wants to merge 9 commits into
tyler/qr-invite-l10-create-invitefrom
tyler/qr-invite-b1-napi-create

Conversation

@tylerhawkes

@tylerhawkes tylerhawkes commented May 21, 2026

Copy link
Copy Markdown
Contributor

Summary

NAPI binding for MlsGroup::create_external_invite (PR-L10).

  • New file bindings/node/src/conversation/external_invite.rs.
  • Buffer in, Buffer out — no encoding conversions at the boundary. The caller's TS/JS code chooses how to transport the invite payload bytes (hex, base64, raw QR encoder, ...).

Stack

Test plan

  • cargo check -p bindings_node passes.
  • node-side smoke test (will land with B-2 or T-1 once the full flow is wired).

Note

Add Conversation.createExternalInvite NAPI binding to node bindings

  • Adds a new async createExternalInvite method to Conversation in external_invite.rs, accepting optional servicePointer (bytes) and expiresAtNs (bigint) options.
  • Returns a CreateExternalInviteOutput object with invitePayload and encryptedGroupInfo as Uint8Array values, converted from the underlying MLS group call.
  • Validates expiresAtNs: throws a napi error if the value is negative or exceeds u64 range.
  • Exports the new module via mod.rs.

Macroscope summarized df2c7b6.

@claude

claude Bot commented May 21, 2026

Copy link
Copy Markdown

Claude finished @tylerhawkes's task —— View job


PR Review Complete ✓

Reviewed at: 2026-05-27 18:34 UTC

Summary

Clean, well-structured NAPI binding that correctly wraps the underlying Rust functionality. The code follows existing patterns in the codebase and includes appropriate validation. No significant issues found.

Minor Observations

  1. BigInt validation (bindings/node/src/conversation/external_invite.rs:62-72)

    • The validation logic correctly handles negative values and overflow
    • Consider extracting this pattern into a helper if similar BigInt→u64 conversions appear elsewhere in the codebase (not required for this PR)
  2. Test coverage

    • Author correctly notes that node-side integration tests will land with B-2/T-1
    • The underlying Rust implementation has unit tests (xmtp_mls/src/groups/external_invite.rs:203-274)
    • NAPI binding layer is straightforward type conversion; comprehensive testing makes more sense at the integration level
  3. Code consistency

    • Follows established patterns (e.g., create_mls_group(), ErrorWrapper::from, async/Result signatures)
    • Struct documentation clearly explains the boundary contract (buffer in, buffer out)
    • Export in mod.rs:12 properly integrates the new module

Verdict

✅ Approve — no blocking issues. The binding is a thin, correct wrapper with appropriate validation.


macroscopeapp[bot]
macroscopeapp Bot previously approved these changes May 21, 2026
@macroscopeapp

macroscopeapp Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This PR adds a Node.js binding that wraps existing Rust functionality for creating external invites. The changes are self-contained, involve straightforward type conversions, and the author owns all modified files.

No code changes detected at df2c7b6. Prior analysis still applies.

You can customize Macroscope's approvability policy. Learn more.

@codecov

codecov Bot commented May 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (tyler/qr-invite-l10-create-invite@e8978a2). Learn more about missing BASE report.

Additional details and impacted files
@@                         Coverage Diff                          @@
##             tyler/qr-invite-l10-create-invite    #3675   +/-   ##
====================================================================
  Coverage                                     ?   83.90%           
====================================================================
  Files                                        ?      402           
  Lines                                        ?    59701           
  Branches                                     ?        0           
====================================================================
  Hits                                         ?    50092           
  Misses                                       ?     9609           
  Partials                                     ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-l10-create-invite branch 2 times, most recently from c12079b to 096e94d Compare May 26, 2026 22:59
@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-b1-napi-create branch from f6de3b8 to 9c190fa Compare May 27, 2026 18:17
@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-l10-create-invite branch from 096e94d to 5ebf785 Compare May 27, 2026 18:17
@macroscopeapp macroscopeapp Bot dismissed their stale review May 27, 2026 18:18

Dismissing prior approval to re-evaluate 9c190fa

… generic AppDataUpdate intent

Defense-in-depth master switch + per-component declarative external
committer authorization for the QR-invite flow (MLS External Commits,
RFC 9420 §12.4.3.2).

- ComponentId::EXTERNAL_COMMIT_POLICY = 0x800C in xmtp_mls_common.
- Type-dispatch entry: ComponentType::Bytes for the new id.
- crates/xmtp_mls/src/groups/external_commit_policy.rs (new file):
  - load_external_commit_policy(group) -> Option<ExternalCommitPolicyV1>
  - is_external_commit_allowed(group) -> bool
  - external_committer_permissions_for(group, id) -> Option<ComponentPermissions>
- MlsGroup::set_external_commit_policy(policy) — granular setter
  writes the full ExternalCommitPolicyV1 via the generic
  AppDataUpdate intent (AppDataUpdateOp::Replace, since the
  component is full-replace Bytes-typed).
- MlsGroup::set_allow_external_commit(bool) — sugar wrapper.

Depends on L-0 (generic IntentKind::AppDataUpdate) for the intent
machinery. No new IntentKind variant added — the generic path covers
this and every future full-replace component setter.

No bootstrap synth: absent EXTERNAL_COMMIT_POLICY = disabled default.
First setter call creates the entry via AppDataUpdateOperation::Update
upsert semantics. Zero risk of cross-client serialization drift.
@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-l10-create-invite branch from 5ebf785 to e8978a2 Compare May 27, 2026 18:33
@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-b1-napi-create branch from 9c190fa to df2c7b6 Compare May 27, 2026 18:33
@tylerhawkes tylerhawkes force-pushed the tyler/qr-invite-l10-create-invite branch 4 times, most recently from 88884e2 to 47d1f52 Compare June 10, 2026 06:42
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