Skip to content

feat(stellar-wallet-snap): add batch proof-of-ownership signing - #267

Open
hmalik88 wants to merge 14 commits into
mainfrom
hm/mul-2186
Open

feat(stellar-wallet-snap): add batch proof-of-ownership signing#267
hmalik88 wants to merge 14 commits into
mainfrom
hm/mul-2186

Conversation

@hmalik88

@hmalik88 hmalik88 commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Explanation

This PR adds signProofOfOwnershipBatch support to the Stellar Wallet Snap.
The new method lets MetaMask request proof-of-ownership signatures for multiple Stellar accounts in one Snap RPC call. Results preserve input order and return per-item success/error objects, so one invalid account or message does not fail the entire batch.

References

N/A

Checklist

  • I've updated the test suite for new or updated code as appropriate
  • I've updated documentation (JSDoc, Markdown, etc.) for new or updated code as appropriate
  • I've communicated my changes to consumers by updating changelogs for packages I've changed
  • I've introduced breaking changes in this PR and have prepared draft pull requests for clients and consumer packages to resolve them

@hmalik88
hmalik88 marked this pull request as ready for review September 4, 2026 14:44
@hmalik88
hmalik88 requested a review from a team as a code owner September 4, 2026 14:44
@hmalik88
hmalik88 deployed to default-branch September 4, 2026 14:44 — with GitHub Actions Active

@stanleyyconsensys stanleyyconsensys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Almost LGTM, Great work,
i especially like the array with length style, i agree we should do it if we have a expected length (will try to copy the pattern to other API later)

It is our of scope of this PR, but shall we also update the singleton request of ProofOfOwnerShip SignProofOfOwnershipJsonRpcRequestStruct to use the shared struct?

Left some nit suggestions that may benefit to all non-evm SNAP

and left a question for the permission

*/
export const SignProofOfOwnershipBatchSuccessStruct = object({
accountId: UuidStruct,
signature: pattern(string(), /^0x[0-9a-f]{128}$/u),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit:

lets create a utils for 64Byte0xHexStruct?
as SignProofOfOwnershipJsonRpcResponseStruct also share that patten as well

or you can leave it here, we can move to some share utils later

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.

Done! 52fea36

I can lift this up to snap-networks-utils later if I see I'm using it elsewhere.

if (account === undefined) {
results[index] = {
accountId,
error: `Account not found: ${accountId}`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit:

IMO, we should have a shared message / shared error const or key , as i found that we are doing the same message for other non-evm snap

e.g

results[index] = {
          accountId,
          error: SignProofOfOwnerShipBatch.AccountNotFound,
}

results[index] = {
          accountId,
          error: SignProofOfOwnerShipBatch.AccountAddressNotMatch,
}

results[index] = {
          accountId,
          error: normalizeError(error).message, // custom error
}
...

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.

Yeah, agreed. We can add this up at the snap-networks-utils level. I can do it in a follow-up PR.

const signingRequests: SigningRequest[] = [];

items.forEach(({ accountId, message }, index) => {
const account = accountsById.get(accountId.toLowerCase());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit:

looks like we are using account.entropySource as a sign request key
may be we should enforce this attribute not miss?

but i guess this is fine, as when we derive address, we will cross check if the address is same

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.

I think if there isn't an entropySource in the account then that's more of a data integrity issue, if it's in state it should be guaranteed to have an entropySource.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i agree, and we already have a "indirect" safe guard later -> assert address check

signature: add0x(wallet.signMessage(message, 'hex')),
};
} catch (error) {
results[index] = {

@stanleyyconsensys stanleyyconsensys Sep 7, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just FYI

sign message throw SignMessageException
we can use it to distinguish the error and use different const error key?

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.

I can do that in a follow up refactor pr using the consts you mentioned above^

Comment thread packages/stellar-wallet-snap/src/permissions.ts Outdated
@hmalik88

hmalik88 commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

@metamaskbot publish-preview

@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Preview builds have been published. Learn how to use preview builds in other projects.

Expand for full list of packages and versions.
@metamask-previews/bitcoin-wallet-snap@2.0.1-preview-57b1c19b
@metamask-previews/snap-networks-utils@1.0.0-preview-57b1c19b
@metamask-previews/solana-wallet-snap@6.0.0-preview-57b1c19b
@metamask-previews/stellar-wallet-snap@0.1.0-preview-57b1c19b
@metamask-previews/tron-wallet-snap@3.2.0-preview-57b1c19b

@stanleyyconsensys stanleyyconsensys left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

there is a sonar cloud alert about account service import multiple time, we can fix it in this PR, or any follow up PR

@sonarqubecloud

sonarqubecloud Bot commented Sep 8, 2026

Copy link
Copy Markdown

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