Skip to content

Add language hint for spoken dynamic PIN - #131

Merged
maximmaxim345 merged 3 commits into
mainfrom
ap/language-hint-for-spoken-dynamic-pin
Aug 5, 2026
Merged

Add language hint for spoken dynamic PIN#131
maximmaxim345 merged 3 commits into
mainfrom
ap/language-hint-for-spoken-dynamic-pin

Conversation

@arturpragacz

Copy link
Copy Markdown
Contributor

Add language hint for spoken dynamic PIN.

@arturpragacz
arturpragacz changed the base branch from main to ap/improve-pin-pairing-window August 4, 2026 00:05
@arturpragacz
arturpragacz force-pushed the ap/language-hint-for-spoken-dynamic-pin branch from c219c49 to 930dafb Compare August 4, 2026 00:22
Base automatically changed from ap/improve-pin-pairing-window to main August 5, 2026 12:08

@maximmaxim345 maximmaxim345 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looks good, just left one comment about possibly expanding languages for other uses too.

But thats not blocking this PR and just an idea. We can discuss/add that separately to this change.

Comment thread messaging.md
- `pairing?`: object - parameters of the pairing attempt this activation admits. Required when `'pairing'` is in `activities`; absent otherwise. A client ignores this field when `activities` does not include `'pairing'`.
- `method`: 'dynamic_pin' | 'pairing_psk' | 'static_pin' - pairing method the server picked, drawn from the client's `supported_pair_methods`.
- `pin_length?`: integer - the dynamic [PIN length](pairing.md#dynamic-pin-pairing-flow) for this session. Required when `method` is `'dynamic_pin'`; absent otherwise.
- `languages?`: string[] - non-empty list of [BCP 47](https://www.rfc-editor.org/rfc/rfc5646) language tags in descending operator preference (e.g. `["ca", "es", "en"]`), for spoken [PIN emission](pairing.md#dynamic-pin-pairing-flow). Optional when `method` is `'dynamic_pin'`; absent otherwise.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Just an idea: should we allow sending languages regardless of the selected method? Still optional for the server, but clients could use it for other things, like translating the UI they show.

@arturpragacz arturpragacz Aug 5, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Hmm, if we would want a hint for translating the whole client UI, then I think we would have to make it a global option, and not just here in pairing then.

@maximmaxim345
maximmaxim345 marked this pull request as ready for review August 5, 2026 12:28
@maximmaxim345
maximmaxim345 merged commit 21b9746 into main Aug 5, 2026
1 check passed
@maximmaxim345
maximmaxim345 deleted the ap/language-hint-for-spoken-dynamic-pin branch August 5, 2026 17:55
maximmaxim345 added a commit to Sendspin/aiosendspin that referenced this pull request Aug 10, 2026
Add PIN language and secret locations hints.

Implements Sendspin/spec#131 and
Sendspin/spec#132 for server side.

---------

Co-authored-by: Maxim Raznatovski <nda.mr43@gmail.com>
maximmaxim345 added a commit to Sendspin/sendspin-js that referenced this pull request Aug 11, 2026
Aligns the client with the new pairing spec changes and moves the E2E
dependency to aiosendspin 9.0.0.

On the Spec side, this PR implements:
- Sendspin/spec#129
- Sendspin/spec#130
- Sendspin/spec#131
- Sendspin/spec#132.


## Pairing

`server/activate` now carries a `pairing` object (`method`,
`pin_length`, `languages`) in place of `selected_pair_method`, and
`pin_length` moved out of `server/pair-init` so the client validates it
before an attempt starts. Terminal lockout is gone: a single dynamic-PIN
failure counter escalates the method to gesture-gating at ten failures
and de-escalates on the next verified round, so repeated wrong PINs can
no longer leave a device permanently unpairable. A gesture-gated attempt
signals `client/pair-pending` and waits for `openPairingWindow()` rather
than closing the connection after five minutes, and a window opened
before the server asks now survives a reconnect instead of being
silently discarded.

Clients can advertise where the operator finds each static secret
through `locations`, and which channels convey the dynamic PIN through
`out_channels`. A server's spoken-PIN language preference reaches the
app as a second argument to `onPairingPin`; the sample player uses it to
read the PIN aloud in the operator's language.

## Breaking changes

`isPairingLockedOut()` and `clearPairingLockout()` are removed in favour
of `isDynamicPinEscalated()`, since escalation has no operator exit
other than a successful round. `onPairing` gained a `pending` event and
`onPairingPin` a second `languages` argument. New optional config:
`pinOutChannels`, `staticPinLocations` and `pairingPskLocations`, all
omitted from `client/hello` when unset.
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.

2 participants