Feat/sep43 sign auth entry#50
Conversation
There was a problem hiding this comment.
Pull request overview
Adds SEP-43 signAuthEntry support to the Stellar snap, enabling dapps (and the local dev dapp) to request signatures over Soroban authorization entry preimages (HashIdPreimage with envelopeTypeSorobanAuthorization) with a dedicated confirmation UX.
Changes:
- Introduces a new SEP-43 keyring handler (
signAuthEntry) with request/response validation, decoding for user display, and Ed25519 signing ofsha256(preimageBytes). - Adds a new confirmation dialog view (
ConfirmSignAuthEntry) and wires it into the confirmation controller + user input event handlers. - Updates keyring method registration, account capability metadata, dev-only RPC routing, and extends unit test coverage across wallet/keyring/api layers.
Reviewed changes
Copilot reviewed 25 out of 25 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| packages/snap/src/ui/confirmation/views/ConfirmSignAuthEntry/events.tsx | Adds confirm/cancel UI event handlers for the new auth-entry confirmation dialog. |
| packages/snap/src/ui/confirmation/views/ConfirmSignAuthEntry/ConfirmSignAuthEntry.tsx | Implements the confirmation UI rendering Soroban auth-entry summary and signer/origin/network details. |
| packages/snap/src/ui/confirmation/controller.tsx | Wires new SignAuthEntry interface key to the corresponding confirmation view. |
| packages/snap/src/ui/confirmation/api.ts | Adds ConfirmationInterfaceKey.SignAuthEntry. |
| packages/snap/src/services/wallet/Wallet.ts | Adds Wallet.signAuthEntry that hashes preimage bytes and signs the digest (no SEP-53 prefix). |
| packages/snap/src/services/wallet/Wallet.test.ts | Adds unit tests verifying signAuthEntry hashing/signature behavior and encodings. |
| packages/snap/src/services/wallet/exceptions.ts | Adds SignAuthEntryException. |
| packages/snap/src/services/account/AccountService.ts | Advertises signAuthEntry as a supported method on Stellar accounts. |
| packages/snap/src/services/account/AccountService.test.ts | Updates expected supported methods to include signAuthEntry. |
| packages/snap/src/index.ts | Adds dev-only RPC alias stellar_signAuthEntry routing to the handler. |
| packages/snap/src/handlers/user-input/userInput.ts | Registers auth-entry confirmation UI event handlers with the user-input handler. |
| packages/snap/src/handlers/keyring/signAuthEntry.ts | Introduces the SEP-43 signAuthEntry keyring handler and Soroban preimage decoding for UI. |
| packages/snap/src/handlers/keyring/signAuthEntry.test.ts | Adds handler tests for confirm/reject and invalid-request scenarios. |
| packages/snap/src/handlers/keyring/keyring.test.ts | Adds keyring submitRequest coverage for signAuthEntry routing and response validation. |
| packages/snap/src/handlers/keyring/index.ts | Exports the new handler module. |
| packages/snap/src/handlers/keyring/base.ts | Updates base handler docstring to include SignAuthEntry. |
| packages/snap/src/handlers/keyring/api.ts | Adds new method enum value + request/response superstructs for signAuthEntry. |
| packages/snap/src/handlers/keyring/api.test.ts | Adds superstruct validation tests for signAuthEntry request/response envelopes. |
| packages/snap/src/context.ts | Instantiates and registers SignAuthEntryHandler in the handler map and exports it. |
| packages/snap/src/api/xdr.ts | Adds HashIdPreimageXdrStruct validation for Soroban authorization preimages. |
| packages/snap/snap.manifest.json | Updates the bundle shasum for the new build output. |
| packages/snap/messages.json | Adds i18n strings for the new auth-entry confirmation dialog. |
| packages/snap/locales/es.json | Adds locale entries for the new auth-entry confirmation dialog. |
| packages/snap/locales/en.json | Adds locale entries for the new auth-entry confirmation dialog. |
| packages/site/src/pages/index.tsx | Extends the local dev dapp UI to call stellar_signAuthEntry and display responses. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
thanks for the work
LGTM! just few nits comment
in addition.
i like the PR has so many details, i think i will try to do the same
but since QA will not visit this PR
lets move them to sub task that you are doing, and pick some important step/information into story
| <SnapText>{nonce}</SnapText> | ||
| </Box> | ||
|
|
||
| {subInvocationsCount > 0 ? ( |
There was a problem hiding this comment.
shall we follow freighter wallet for the information that we display (no need 100%)
https://github.com/stellar/freighter/blob/1ee0e0c8141167021d597c1d4786bee3d75e5124/extension/src/popup/views/SignAuthEntry/index.tsx#L272
And i do think auth entry is a good info to display
There was a problem hiding this comment.
Done you can test with this XDR AAAACXrDOZdUTjF10ma9AiQ5sizbFlCMARY/JuXLKj4QRal5AAAAADreaLEATEtAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAh0cmFuc2ZlcgAAAAIAAAASAAAAAAAAAAAXmJXrnYi/8w2mnLPffCyumwfXR1G+1z2CgWGZvcdM9AAAAAoAAAAAAAAAAAAAAAAAD0JAAAAAAQAAAAAAAAABAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAAHYXBwcm92ZQAAAAACAAAAEgAAAAAAAAAAqWUiKUM8kOWf3SM9URxLuIgw/VPfd7r+pRiXkHzR8NQAAAADAAAD6AAAAAA=
| ): Promise<string> { | ||
| try { | ||
| const preimageBuffer = bufferToUint8Array(authEntry, 'base64'); | ||
| const preimageHash = await sha256(preimageBuffer); |
There was a problem hiding this comment.
sorry, i miss the review here, may i ask why we need sha256?
because only SEP53 require signMessage to have sha256 (becoz it need to combine the prefix)
Stellar official site recommend reference
https://github.com/stellar/js-stellar-base/blob/e3d6fc3351e7d242b374c7c6057668366364a279/src/auth.js#L97
Feligher wallet reference
https://github.com/stellar/freighter/blob/b19a3b899f2273f022421924f4d423ccd0058dcb/extension/src/background/messageListener/handlers/signAuthEntry.ts#L63
There was a problem hiding this comment.
Hey good question, sha256 is actually required here. Both references you linked do the same thing:
- js-stellar-base/src/auth.js
authorizeEntry→hash(preimage.toXDR())before signing - Freighter's signAuthEntry.ts →
keyPair.sign(hash(authorizationEntry))
Btw hash() in stellar-sdk is sha256 — see @stellar/stellar-base/src/hashing.js
function hash(data) {
var hasher = new sha256();
hasher.update(data, 'utf8');
return hasher.digest();
}
Same digest, different name. We're using sha256 directly
The Soroban host verifies signatures against sha256(preimage), so without the hash step our signatures wouldn't verify on-chain. Different reason from the SEP-53 prefix in signMessage, but both end up needing sha256.
There was a problem hiding this comment.
shall we use this hash function instead then?
| const { contractAddress, functionName, args, subInvocations } = invocation; | ||
|
|
||
| return ( | ||
| <Box direction="vertical"> |
There was a problem hiding this comment.
Will reorder to match Freighter


Explanation
Adds the third SEP-43 method,
stellar_signAuthEntry, to the snap. Dapps can now request the user to sign a Soroban authorization entry (HashIdPreimagewithenvelopeTypeSorobanAuthorization) — the lower-level primitive used for pre-authorizing contract invocations and custom-account auth flows. Behavior matches signMessage / signTransaction:onRpcRequest(stellar_signAuthEntry) and via the keyringsubmitRequestroute.validateOrigin.opts.networkPassphrasewith-3.ConfirmSignAuthEntry) renders contract, function, expiration ledger, nonce, optional nested-authorizations count, origin, account, and network, with a warning that the user is authorizing a contract to act on their behalf.{ signedAuthEntry: <base64>, signerAddress }(SHA-256 of the raw HashIdPreimage bytes, signed Ed25519 — no SEP-53 message prefix).{ signedAuthEntry: '', signerAddress, error: { code: -4 } }.{ ..., error: { code: -3 } }.Test plan (QA)
Setup:
yarn start, open the test dapp at http://localhost:8000, connect MetaMask Flask, install the snap.1. Happy path — confirm
In the test dapp, click the Sign auth entry button.
Paste this XDR (valid HashIdPreimage, mainnet, transfer, no sub-invocations):
AAAACXrDOZdUTjF10ma9AiQ5sizbFlCMARY/JuXLKj4QRal5AAAAAAdbzRUAD0JAAAAAAAAAAAECAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAh0cmFuc2ZlcgAAAAAAAAAAExpect dialog:
{ "signedAuthEntry": "<non-empty base64>", "signerAddress": "<G…>" }2. User rejects
Errors to encounter (QA)
These all share the same dapp-side response shape —
signedAuthEntry: '',signerAddress: '<G…>' or '',error: { code, message, ext? }— and none should display the confirmation dialog (except case 7, user rejection).errorauthEntry: "not-base64"code: -3,extreferencesrequest.params.authEntry.envelopeTypeSorobanAuthorization(e.g. paste asignTransactionenvelope XDR into theauthEntryfield).code: -3,extincludesHashIdPreimage is not a Soroban authorization preimage.scope: "stellar:testnet"(use the dapp's testnet toggle, or the snap-shell).code: -3.opts.networkPassphraseopts: { networkPassphrase: "Test SDF Network ; September 2015" }.code: -3,extmentions mainnet.opts.submitopts: { submit: true }(the snap is sign-only, never submits).code: -3.opts.submitUrlopts: { submitUrl: "https://horizon.stellar.org" }.code: -3.code: -4(User rejected the request). The dialog does appear here — only error case where it should.Edge cases (no error)
opts.addressis informationalopts: { address: <other funded account in same wallet> }.opts.address); responsesignerAddressmatches the connected account.authEntryauthEntryis always a base64 XDR, never UTF-8.-3), which is correct. Mention this only so QA knows not to file a bug.References
Checklist