feat(chat): implement Chat::register_bot in the shared Rust core - #430
Open
decrypto21 wants to merge 5 commits into
Open
feat(chat): implement Chat::register_bot in the shared Rust core#430decrypto21 wants to merge 5 commits into
decrypto21 wants to merge 5 commits into
Conversation
Member
|
Shared findings with @decrypto21 offline. |
decrypto21
force-pushed
the
feat/chat-register-bot
branch
from
August 18, 2026 08:02
a59a6b2 to
356e9b9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
chat.registerBotfrom the shared core through aChatPlatform::register_bothook, reaching native storage viaNativeChatCallbacksand the SwiftChatHostBridgecreate_roomandregister_bot, and normalizepost_message's room id to the same formCallError::Unsupportedfrom all nineCoinPaymentmethods rather than inheriting the trait default'sHostFailureregister_botrequest bytes and status discriminants against the reference JS host's own codecChatPlatform, soexecutionKind: "Chat"there answers unsupported and its subscriptions end emptyregister_botreserves wire id 40 and is present in the generated dispatcher, the wire table and the published TS types, so the wire surface is unchanged by this PR — it converts a runtimeunavailableinto a real answer.Chat coverage after this change
All six product-initiated Chat methods reach an implementation. The native adapter persists
TextandCustommessage content; the remaining fiveChatMessageContentvariants report a domain error, which a test pins so the ceiling is explicit rather than incidental. Worth naming:action_subscribedeliversActionTriggeredwhileActionsis one of the rejected variants, so a product can receive action triggers it cannot yet produce.Field validation
create_roomandregister_botbound their ids, names and icons, NFC-normalize them, and screen characters that let two distinct values render identically. Identifiers are screened harder than display names: a name keeps ZWJ and ZWNJ because emoji sequences and Persian need them, while an identifier rejects those plus variation selectors, soft hyphens, invisible operators and non-ASCII spaces. Icons are an allowlist —https, or an inline raster image — because a URL parser reaches a scheme through whitespace, tabs and NUL that a prefix comparison does not.Contextual output escaping, storage limits, and every
post_messagefield remain host-owned.ChatHostBridge.registerBotis a required memberThere is no protocol-extension default: a host either implements bot registration or fails to compile. A default that reported "unavailable" would land as an untyped
Unknown{reason}— indistinguishable from a genuine failure, and the same additive-blind shape this change set exists to remove.StubChatHostBridgein the test target writes out every member, which is what makes theios-swiftjob a gate.Downstream needs one method.
polkadot-app-ios-v2has a live conformer ondevelopatpolkadot-app/Modules/Products/TrUAPI/RustChatExecutionBridge.swift, implementing the four existing members. It needs aregisterBotfollowing thenotImplemented(#function)pattern already in that file. Theios-swiftjob compiles only this repo's package, so CI here cannot see that break.Validation
cargo test --workspace --all-features— 849 testscargo clippy --workspace --all-targets --all-features -- -D warningscargo +nightly fmt --check./scripts/codegen.shwith no tracked-file drift;make uniffireproduces the committed bindings byte-for-byteyarn test:unit,yarn lint; explorernpm run lintxcodebuild build-for-testing -scheme TrUAPIHostagainst a locally built simulator XCFrameworkEach new assertion was mutation-checked against the defect it guards: removing the
implreproducesunavailable; swallowing a host rejection into a fabricatedNewfails; collapsing a field rejection intoUnsupportedfails; droppingpost_messagenormalization orphans the room and fails; reorderingbot_id/namefails the wire fixture; deleting aCoinPaymentoverride restoresHostFailureand fails; a spurious room-list republish fails rather than hanging.Notes
Registering a bot does not republish the room list —
list_roomsreports rooms, and a bot identity is not a room. A host that joins a bot to a room signals that throughnotify_chat_rooms_changed.The checked-in host-CLI reports still carry the older
HostFailureDetailsstrings for the nineCoinPaymentmethods; they refresh on the next CLI e2e run.Open follow-ups, each a decision rather than effort:
Text/Custom, or narrowing what the protocol advertisesexecutionKind: "Chat"is accepted, but every chat call returnsUnsupported#383)TrUAPIHostRuntimewrapper first —TrUAPIHost.ktwraps onlyNativeTrUApiCore, andopenProductExecutionis the only entry point accepting chat callbacksCallErroradds a tag and inner version that itsErrEnumdoes not expect, tracked asTODO(shared-core-wire)inframe.rscomplete()is unreachable for error-channel subscriptions (ts.rs), which affects the livestatement_store.subscribetoday