* smp server: delayed AUTH responses
* plan
* update
* simplify
* simplify
* stat when sent without delay
* update schema
* round up response time to the nearest delay multiple
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* smp protocol: require fixed size corr ID when used as nonce, and min size msg ID to use as nonce
* simpler
* fixes
* randomMsgId
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* consider IP address protected only if it is used for the chosen host
* simplify
* simplify
* simplify
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* crypto: Ethereum primitives for SimpleX names
secp256k1 (vendored libsecp256k1 v0.8.0, recoverable ECDSA), BIP-39
mnemonics, BIP-32 derivation, Keccak-256, EIP-55 addresses and EIP-712
typed data hashing.
Client-side signing only: no RLP, no transaction construction, no chain
writes. The resolver path stays read-only.
Verified against published vectors — the 24 official BIP-39 English
vectors, BIP-32 spec vectors 1 and 2, the EIP-55 spec addresses and the
EIP-712 Mail example.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* tiny fixes
* plan update
* expose what's necessary for stealth addresses too"
* add string encoding
* streamline hex encoding
* core: ethereumPath takes the address index
The BIP-44 path is the same for every address under an account, so the
caller that wants one names it, rather than rebuilding the path around the
one this hard-coded.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rvc3HbiWBTqbAvRT45G5oX
* core: embed the BIP-39 wordlist as the upstream file
The list was transcoded into Haskell, which can only be audited by reading
2048 words against the source. The upstream english.txt is vendored instead
and embedded at compile time, so auditing it is one sha256sum, and a test
pins that checksum so the copy cannot drift.
file-embed moves into the library, where it was already a dependency of the
executables and the test suite.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Rvc3HbiWBTqbAvRT45G5oX
* review fixes
* fix review findings iterate self-reviews with /goal
* next review round
* cut to the min
* cut comments
* streamline
* Update src/Simplex/Messaging/Crypto/BIP32.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update CHANGELOG.md
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Crypto/BIP32.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Crypto/Secp256k1.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Crypto/Secp256k1.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* opus 5.5 /goal iterations
* self-review rounds
* self-review iteration 2
* self-review iteration 3
* self-review iteration 3ff
* self-review iteration 3fff
* self-review iteration 5
* more doc tweaks
* self-review iteration 9
* self-review iteration 10
* wip
* rng preserve
* finish wip and factor in test vectors
* make wallet creation and account derivation infallible like trezor does
* review iterations
* limit derivation retries to 3
* remove unnecessary export
* random
* security, simplify, imports
* use static context
* fix test
* restore public api to use rng
* back to IO
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* implement resolving 2LD names by labelhash
* tiny test addition
* simplify language
* report expiry and availability correctly
* compare block instead of wall clock
* simplify language
* simplify language
* map resolver 410 to NAME NOT_FOUND (a lapsed name is an answer, not a failure)
* split error into a machine-readable code and a human message
* resolver: reduce comments
* resolver: reduce comments, remove REVIEW.html
* extend SMP protocol to support name availability queries with accurate and meaningful replies
* review fixes
* more review fixes
* docs shortening and other review fixes
* add catch all for furture variants
* adversarial review (against simplex-chat) fix
* next iteration fixes
* adapt house style
* eth_call guard and cache constants
* revert NAVL command and wrap it all into RSLV
* doc fixes
* Update src/Simplex/Messaging/Server/Names.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Protocol.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Protocol.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Protocol.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* Update src/Simplex/Messaging/Protocol.hs
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* protocol types refactoring
* next iteration on types only
* rentPrices map
* claude answering ep review. to be continued...
* separate labelhash and plaintext names cleanly
* align implementation with latest type changes to test against client
* fix adversarial review findings
* trim diff
* align resolver with contract changes for names v2
* fix reverse compatibility with .testing mainnet
* fix more robustly
* NameQuery simplification
* revert drive-by refactoring
* implement full type change and introduce resolver endpoint versioning
* fix stale docs
* derive NameRegistration JSON the same way on every build
sumTypeJSON switches to the _owsf form on swift builds, but this JSON is
the RNAME payload and the resolver's HTTP contract, so a swift client and
a Linux relay would disagree on every field. taggedObjectJSON is what it
already resolves to everywhere else.
The label modifier keeps the reservedReason_ collision escape out of the
API, as AgentWorkersDetails does: both arms now say reservedReason.
* fix resolver boundary: status before body, cover /v2, drop dead field
httpGet read the response body before checking the status, so an oversized
error page surfaced as a transient "response too large" instead of the
authoritative status. Reverting it to its previous shape restores that and
removes the status test both callers had been re-deriving.
registration() had no tests at all, though it is the endpoint SMP v22
consumes. RegistrationV2Tests covers the three answer shapes, the error
paths and the exact key set of each, which is the wire contract.
auctionUntil was always None with no consumer. The spec claimed a reason
word travels unchanged; a resolver can only send a word it has, and SNRC's
registry records a number.
* fix review findings
* resolver errors say what went wrong, not "no such name"
/v2/resolve answers 200, 400 or 502, and an unregistered name is
NRAvailable, so no status means "not registered". Mapping 400/404/410 to
NOT_FOUND made a misconfigured relay deny every name, and hid a relay
upgraded ahead of its resolver. All three now surface as RESOLVER.
rslvNotFound would have gone dead, so it counts what its name says: an
availability answer the encoder downgrades for a session below v22. The
wire is unchanged.
A hashed query the registrar cannot name is refused with 502 rather than
answered with a record named "unknown", which the client rejects anyway.
NRRUnknown is capped to 32 printable characters again, as the spec says.
A registered name that is also reserved no longer offers a date it will
never free up on. rentPrices is registrationPrices throughout, and
yearPriceUSD is USDCents rather than a bare Int64.
* fix regressions found reviewing the last two commits
resolveNameMsg read the version off thParams', which on the PFWD path is
the proxy's session, not the client's. It takes the version as an argument
now, so each call site passes its own — the forwarded one uses fwdVersion.
reservedReasonOf matched the reason words before capping, so "internal
review" became NRRUnknown "internal", which encodes back as NRRInternal.
Capping precedes the match, so what is kept encodes to what it decoded.
Four agent tests still pinned NAME NOT_FOUND from a 404 stub, and two spec
statements still described the old mapping. A registrar that does not
record labels cannot answer a hashed query, which the resolver README now
says.
* docs sweep
* simplify encoding
* drop resolver caching (#1866)
* rename
* remove trailing_ filter
* fix resolver v2 for subnames (#1867)
* fix resolver v2 for subnames
* simplify doc
* resolver should report response truth freshness (#1868)
* first shot at reporting freshness
* fix review findings
* renaming
---------
Co-authored-by: sh <github.shum@liber.li>
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* feat: add server public information handling in XFTP protocol
* test
---------
Co-authored-by: sh <github.shum@liber.li>
Co-authored-by: Evgeny Poberezkin <evgeny@poberezkin.com>
* agent: fast queue rotation does not requiring the current server to be online
* update plan
* update plan and rfc
* corrections
* update plan
* implementation
* test
* refactor
* test switching notificaitons
* rename
* fix, refactor
* fix possible crash
* simplify
* refactor
* simplify
* refactor
* simplify
* order, avoid re-reading connection
---------
Co-authored-by: Evgeny @ SimpleX Chat <259188159+evgeny-simplex@users.noreply.github.com>
* agent: report PRXY broker errors as proxy-to-relay errors
The proxy returns PROXY BROKER errors only when it fails to connect to the
destination relay, but for PRXY they were mapped to SMP <proxy> (PROXY ...),
losing the relay address, so the clients reported them as errors of the
connection to the forwarding server. Map them to PROXY {proxyServer,
relayServer, ...}, the same shape PFWD errors already use.
* Apply suggestion from @epoberezkin
* agent: keep ProxyProtocolError for PRXY broker errors
Reverts 826a2377.
ProxyResponseError wraps PCEResponseError, a response that failed to
parse, and both clients match protocolError when rendering this error,
so the connect alert falls through to the raw error dump - and released
clients cannot render it at all. temporaryAgentError and serverHostError
also match ProxyProtocolError only, so the failure stops being retried
and proxy fallback no longer engages.
---------
Co-authored-by: Evgeny <evgeny@poberezkin.com>
* smp-server: add serverInfoBytes to THandleParams and related functions
* server information
* fix test
---------
Co-authored-by: Ed Asriyan <service.github@asriyan.me>