Record numberless accounts explicitly instead of treating every retained ACI as a discoverable account. Resolve older index entries against saved account state, preserving ACI lookup and retrying unavailable state on later reads. The optional index field remains compatible with version 2 readers. Update native-image reflection metadata and cover replacement, legacy migration, locked and missing state, and mismatched ACIs in regression tests.
3.8 KiB
Linking an account without a phone number
signal-cli can link as a secondary device to an account registered without a phone number, such as those created in Signal Android 8.28. Creating or recovering a primary numberless account using an Account Key is not supported.
Run signal-cli link -n signal-cli, then scan the QR code from the mobile app's
Linked devices screen. The linking URI advertises capabilities=nopni. If linking
completes, the CLI prints the account's ACI instead of a phone number.
Use that ACI with -a for subsequent commands:
signal-cli -a YOUR_ACCOUNT_ACI receive
signal-cli -a YOUR_ACCOUNT_ACI listGroups
signal-cli -a YOUR_ACCOUNT_ACI send --note-to-self -m 'Numberless account test'
When only one local account exists, -a can be omitted. Numbered accounts continue
to accept their phone number or ACI. A numberless account cannot infer a country
code for a recipient's phone number; use a complete international number beginning
with +, an ACI, or a Signal username.
In JSON-RPC, use the ACI in the account parameter. listAccounts and finishLink
return an aci field alongside number; number is null for a numberless account.
Receive events use the ACI in their account field when there is no phone number.
REST wrappers must understand those nullable numbers and ACI selectors before they
can be assumed compatible.
Numberless accounts are also supported through D-Bus. Start
signal-cli daemon --dbus, then use the ACI with the D-Bus client:
signal-cli --dbus -a YOUR_ACCOUNT_ACI listGroups
signal-cli --dbus -a YOUR_ACCOUNT_ACI send --note-to-self -m 'Numberless account test'
In multi-account mode, D-Bus exports numberless accounts under
/org/asamk/Signal/ACI, with the ACI's hyphens replaced by underscores. Numbered
accounts retain their phone-number-based paths. Use SignalControl.listAccounts
or SignalControl.getAccount to discover paths; getAccount accepts either a
phone number or an ACI. Signal.getSelfNumber returns an empty string when the
account has no phone number, and Signal.getSelfACI returns the ACI.
Signal.listRecipientIdentifiers includes contacts without a phone number;
Signal.listNumbers continues to return only phone numbers.
Validation
Run ./gradlew test installDist with JDK 25. Regression tests cover the linking
request (including ACI authentication and omission of PNI keys), numbered-account
linking, missing group credential salts, persisted account reload, account discovery
(including superseded accounts and legacy indexes), group membership lookup,
recipient-number formatting, and JSON account identifiers.
D-Bus transport tests require a session bus. To run them on an isolated bus, use
dbus-run-session -- ./gradlew --no-daemon :test --tests '*NumberlessDbusTest*' --rerun-tasks.
These tests exercise the D-Bus server and client with a local test backend, including
mixed accounts, direct and group messages, self-directed operations, and account
removal. They do not contact Signal. Without a session bus, only the D-Bus unit
tests run and the transport tests are skipped.
Live acceptance requires a real mobile account and is separate from these tests:
- Link a newly created secondary device using the numberless mobile account.
- Restart signal-cli and verify that
listAccountsstill reports the ACI. - Send and receive a Note to Self message and a DM with a second account.
- Receive a group message, list the group, and send a reply to that test group.
- Run the JSON-RPC daemon, restart it, and repeat receiving and sending by ACI.
- Repeat with
daemon --dbusand the--dbus -a YOUR_ACCOUNT_ACIclient, checking direct messages, group messages, and Note to Self.
Only one signal-cli process may open an account's state at a time. Stop the daemon before running one-off commands against the same configuration directory.