Repository navigation
OneKey supports Sui - #217
Conversation
Connect each chain through the provider the OneKey extension injects, checked against OneKey's own provider and background sources. Bitcoin moves to the Unisat-style $onekey.btc API and Solana to $onekey.solana: the previous sats-connect and $onekey.sol paths never matched what the extension exposes, so both chains failed to connect. Sui, TRON and Stellar signatures are checked against the requested transaction before they are returned. NEAR and TON can only sign and send, so they go through the toolbox's sign-and-send path. The unused EVM signer is removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…nd OneKey Both wallets talk to the same TON Connect bridge, so the connect, send and transfer logic moves to one helper. Each wallet passes its own provider and errors, so OKX keeps its existing error keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…tichain-support # Conflicts: # bun.lock # packages/wallet-extensions/package.json
…cels OneKey queues every pending approval, so requesting all networks at once kept opening windows after the user cancelled one. Networks are now requested in order; a cancel stops the loop and keeps the ones already approved, as OKX does. Other failures skip that network with a warning. The TON Connect helper keeps the wallet's error code on a rejected connection, so a manifest error is no longer mistaken for a cancel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
… test The test left a manifestUrl in the shared config, so the OKX test that expects no manifest failed whenever it ran afterwards. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…d tronWeb When a site was already connected, tron_requestAccounts answered at once but the injected tronWeb still had no default address, so TRON reported a user rejection and stopped the whole connection. The address now comes from tron_accounts and signing goes through the provider's sign method. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
Sui cannot be tested against the OneKey extension yet, so it leaves this change and returns in a follow-up. The rejection test now uses Stellar as the chain that must not be requested. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
Connect Sui through the provider the OneKey extension injects and sign with its signTransaction. The signed bytes are compared with the requested transaction before the signature is returned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
Signing hangs in OneKey's confirmation screen, so Cardano leaves this change until that is resolved and returns in a follow-up. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…ctions Cancelling the EVM approval now stops the remaining approval windows: ethers reports OneKey's rejection as ACTION_REJECTED, which was not recognised. TRON and TON only count a declined approval as a rejection and skip the chain on any other failure. The TON Connect helper decides this itself, so OKX also reports manifest errors as connection failures. TON moves into the OneKey helpers and EVM chains are matched with EVMChains instead of a separate list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…out its sign() OneKey can answer 4000 to tron_requestAccounts right after the user approves, so the connected account from tron_accounts now decides whether TRON connected. Signing calls tron_signTransaction directly: OneKey's injected sign() calls a tronWeb.utils.isString its TronWeb no longer has, which made every TRON signature fail. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…requested OneKey received the same transaction object the check and the result used, so a provider that rewrote it in place passed the check. It now gets a copy, and the txID check and the returned transaction come from the requested one. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QKkbKMCDEvXWUuh6hv
…tichain-support # Conflicts: # bun.lock # packages/wallet-extensions/package.json
Resolves the conflicts left by the squash-merge of the OneKey networks update and its release: keeps the Sui connector and its tests on top of the released helpers and drops the already published changeset. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QNFUSnoUdjpgbvcx2V
|
/dominion review |
PR review · publishedOutcome: inconclusive. 1 finding: 1 low. Open the published review for the TL;DR, findings and fixes.
Run details
|
There was a problem hiding this comment.
TL;DR
This PR adds Sui connect, send and swap support for OneKey, and checks that signatures cover the requested transaction. The main issue is minor: the Sui signature check takes a needless base64 round-trip that can throw a raw decode error. The adversarial lane errored and its sandbox experiments produced no meaningful evidence, so that evidence is missing. Compatibility with the real OneKey extension is also untested.
This review is inconclusive. Some evidence is missing or failed, so it does not establish that the change is safe. 1 finding: 1 low.
adversarialdid not complete: assess adversarial experiments: adversarial experiments did not establish meaningful behavior and test-quality evidence
Low
Sui signature check uses a needless base64 round-trip
packages/wallet-extensions/src/onekey/helpers.ts:109 · code-style-complexity
The check that OneKey signed the requested Sui transaction is written as base64.encode(base64.decode(result.bytes)) !== serialized. The base64 decoder in @scure/base is strict, so any input it accepts re-encodes to the same string. The round-trip therefore adds no tolerance over a direct string comparison. Its only extra effect is a second, hidden failure path: malformed bytes throws a raw decode error instead of the OneKey signingError used everywhere else in this file. It also makes readers work out why the value is re-encoded, which hides the simple rule that the wallet's bytes must equal the requested bytes. The Tron and Stellar signers express the same check directly (txID !== requested.txID, signed.hash().equals(...)).
Fix: Compare the strings directly: if (result.bytes !== serialized) throw signingError(Chain.Sui, "OneKey signed a different transaction than the one requested");. Malformed and mismatched bytes then raise the same SwapKit signing error. The existing tests still cover the match and mismatch cases.
Review coverage and raw evidence
Reviewed head 56d26d124536688393ee6ba6c303d73ea447119d against base 15a8aad354f57b568673aebf35989edc9123b53c. Run 134c820d-1977-457b-92e3-7236b3e0ba8a.
logic — passed (0 findings)
Reviewed all five changed files, connection/error handling, signing integration, exports and test preservation. No concrete regressions found; no existing tests or guards were removed or weakened. Graph context was available but limited for dynamic/external dependencies; Argus coverage was partial. Tests were not executed, and real OneKey extension compatibility remains unverified.
adversarial — error (0 findings)
assess adversarial experiments: adversarial experiments did not establish meaningful behavior and test-quality evidence
Experiment probe-1 (behavior): passed, exit 0, 1948 ms.
Experiment probe-2 (test-quality): violated, exit 1, 1706 ms.
code-style-complexity — passed (1 findings)
I reviewed every changed file in the patch: the changeset, the OneKey Sui tests, helpers.ts, index.ts and types.ts. I compared the new Sui signer with the existing OneKey Tron, Stellar, Bitcoin and Near signers in helpers.ts. The Sui addition follows the file's existing pattern: a per-chain getXWalletMethods function, getProvider, a lazy toolbox import, connectionRejectedError/signingError, and a switch case in getWalletMethods. I found one simplification, a needless base64 round-trip in the signature check. The SUI_MAINNET constant also sits apart from the file's other constant, TRON_USER_REJECTED, but that is too minor to report. The Argus/Jev advisory pass was partial (coverage_incomplete): it produced no candidates, did not evaluate the .changeset markdown file, and omitted 173 reference files. Its gaps did not limit this review, because I read the needed source directly from the checkout.
Original specialist findings
F1 · low · code-style-complexity · packages/wallet-extensions/src/onekey/helpers.ts:109
Issue: The check that OneKey signed the requested Sui transaction is written as base64.encode(base64.decode(result.bytes)) !== serialized. @scure/base's base64 decoder is strict, so any input it accepts re-encodes to the same string. The round-trip therefore adds no tolerance over comparing the strings directly. Its only extra effect is a second, hidden failure path: malformed bytes throws a raw decode error instead of the OneKey signingError used everywhere else in this file. Readers have to work out why the value is being re-encoded, which hides the simple rule that the wallet's bytes must equal the requested bytes. The Tron and Stellar signers express the same check directly (txID !== requested.txID, signed.hash().equals(...)).
Solution: Compare the strings directly: if (result.bytes !== serialized) throw signingError(Chain.Sui, "OneKey signed a different transaction than the one requested");. Malformed or mismatched bytes then both produce the same SwapKit signing error, and the existing tests still cover the match and mismatch cases.
The base64 decoder is strict, so decoding and re-encoding the wallet's bytes could only ever return the same string or throw a raw decode error. A direct comparison keeps the same check and reports malformed bytes through the OneKey signing error like the other signers. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Y7T5QNFUSnoUdjpgbvcx2V
OneKey users can connect Sui and send or swap on it.
Signatures returned by the wallet are checked to make sure they cover exactly the transaction the user was asked to sign.
Kept separate until it can be tested with the OneKey extension; it builds on the OneKey networks update.
Linear: API-3831