Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AssembledTransaction.needsNonInvokerSigningBy() assumes all auth addresses are stellar accounts #1030

Open
JakeUrban opened this issue Aug 17, 2024 · 8 comments · May be fixed by #1044
Open
Assignees
Labels

Comments

@JakeUrban
Copy link
Contributor

Describe the bug

needsNonInvokerSigningBy()'s filter() condition returns authorization entires whose address.signature value is scvVoid. In my case, this address was a contract. I was trying to figure out how to sign a transaction that used custom auth.

However, the returned list is then mapped through a function that assumes all addresses are stellar account public keys. This lead to a TypeError: accountId not set error.

To Reproduce

Use the following transaction to construct an AssembledTransaction and call needsNonInvokerSigningBy():

AAAAAgAAAADhY+75HJcYjxA07MhDzZk/DwQzVITe9slCwDgcEGcc+AACfJ8AEJEBAAAAAwAAAAEAAAAAAAAAAAAAAABmv+l8AAAAAAAAAAEAAAAAAAAAGAAAAAAAAAABOSACpv7RbyYK4XnWgj9AJ/GjrIPjLEoWJa/Iqo1a//YAAAAEbWludAAAAAIAAAASAAAAAAAAAADhY+75HJcYjxA07MhDzZk/DwQzVITe9slCwDgcEGcc+AAAAAoAAAAAAAAAAAAAAAAAAABkAAAAAQAAAAEAAAABEGJ2U3ldj9dca1n1NK0i2XkfL/5zXZsxAOIxUmn9RWknYhAjSWxRgQAAAAAAAAABAAAAAAAAAAE5IAKm/tFvJgrhedaCP0An8aOsg+MsShYlr8iqjVr/9gAAAARtaW50AAAAAgAAABIAAAAAAAAAAOFj7vkclxiPEDTsyEPNmT8PBDNUhN72yULAOBwQZxz4AAAACgAAAAAAAAAAAAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAEAAAAAAAAAAAagL+zRaDmKTHWcB67aFNUZNLVg6ojcyrbO1u3Sg/KcAAAAAYAAAABOSACpv7RbyYK4XnWgj9AJ/GjrIPjLEoWJa/Iqo1a//YAAAAUAAAAAQAAAAYAAAABwfs5RVshthImbX+wmqWS0t1AjL4y5EjMMtSk/oEy11AAAAAUAAAAAQAAAAeheXOfVamUQyN7XuqlXPfXnmxx6tJxnGFVIA2YxmGnMwAAAAIAAAABAAAAAOFj7vkclxiPEDTsyEPNmT8PBDNUhN72yULAOBwQZxz4AAAAAlRFU1Q0AAAAAAAAAAAAAAAagL+zRaDmKTHWcB67aFNUZNLVg6ojcyrbO1u3Sg/KcAAAAAYAAAABEGJ2U3ldj9dca1n1NK0i2XkfL/5zXZsxAOIxUmn9RWkAAAAVJ2IQI0lsUYEAAAAAABUmowAADXgAAADEAAAAAAACfDsAAAAA

Expected behavior

The function should not assume all auth entries addresses are stellar accounts -- it should also support contract addresses.

@JakeUrban JakeUrban added the bug label Aug 17, 2024
@JakeUrban
Copy link
Contributor Author

JakeUrban commented Aug 17, 2024

Looking at the implementation of signAuthEntries(), it appears as if we'll also need to update the function to support passing contract addresses. Right now it, as well as the stellar-base function it calls, authorizeEntry(), only supports signing with stellar accounts.

@JakeUrban
Copy link
Contributor Author

@leighmcculloch I'm curious on your take here -- we should be able to support auth entries that need signatures from signers of contracts right? The SDK doesn't need to know what auth scheme the contract uses.

@Shaptic
Copy link
Contributor

Shaptic commented Aug 17, 2024

I’m confused as to what it means for a contract to sign for something when it doesn’t have a private key.

@JakeUrban
Copy link
Contributor Author

In short, if a contract (A) calls require_auth() on an Address, and that address is a contract (B), the host will call B.__check_auth() and pass it the authorization entries and context for the transaction. The contract can then apply arbitrary rules and ultimately return true/false to authorize/fail the transaction. The rules it implements could be that one or more entries have to have a signature from a particular key it tracks in its storage, or it could something like "you can only call this contract every X ledgers".

This is what we've called custom auth or a custom account as an admin on the contract in our docs.

@leighmcculloch
Copy link
Member

@leighmcculloch I'm curious on your take here -- we should be able to support auth entries that need signatures from signers of contracts right? The SDK doesn't need to know what auth scheme the contract uses.

+1. The JS SDK should support auth entries for custom auth. The SDK won't be able to produce the signatures, but it should allow setting them.

I’m confused as to what it means for a contract to sign for something when it doesn’t have a private key.

In custom auth the contract doesn't sign for the auth, the contract validates a signature passed in. The signature can be whatever the contract expects. It could even be no signature in the event the custom auth is gating behavior based on other inputs such as the context of the call (call stack, arguments, etc).

@JakeUrban
Copy link
Contributor Author

Hey all, what is the status of this?

chadoh added a commit to AhaLabs/js-stellar-sdk that referenced this issue Sep 10, 2024
Fixes: stellar#1030

> `needsNonInvokerSigningBy()`'s `filter()` condition returns authorization entires whose address.signature value is `scvVoid`. In my case, this address was a contract. I was trying to figure out how to sign a transaction that used custom auth.
>
> However, the returned list is then mapped through a function that assumes all addresses are stellar account public keys. This lead to a `TypeError: accountId not set` error.
>
> **To Reproduce**
>
> Use the following transaction to construct an `AssembledTransaction` and call `needsNonInvokerSigningBy()`:
>
> ```
> AAAAAgAAAADhY+75HJcYjxA07MhDzZk/DwQzVITe9slCwDgcEGcc+AACfJ8AEJEBAAAAAwAAAAEAAAAAAAAAAAAAAABmv+l8AAAAAAAAAAEAAAAAAAAAGAAAAAAAAAABOSACpv7RbyYK4XnWgj9AJ/GjrIPjLEoWJa/Iqo1a//YAAAAEbWludAAAAAIAAAASAAAAAAAAAADhY+75HJcYjxA07MhDzZk/DwQzVITe9slCwDgcEGcc+AAAAAoAAAAAAAAAAAAAAAAAAABkAAAAAQAAAAEAAAABEGJ2U3ldj9dca1n1NK0i2XkfL/5zXZsxAOIxUmn9RWknYhAjSWxRgQAAAAAAAAABAAAAAAAAAAE5IAKm/tFvJgrhedaCP0An8aOsg+MsShYlr8iqjVr/9gAAAARtaW50AAAAAgAAABIAAAAAAAAAAOFj7vkclxiPEDTsyEPNmT8PBDNUhN72yULAOBwQZxz4AAAACgAAAAAAAAAAAAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAEAAAAAAAAAAAagL+zRaDmKTHWcB67aFNUZNLVg6ojcyrbO1u3Sg/KcAAAAAYAAAABOSACpv7RbyYK4XnWgj9AJ/GjrIPjLEoWJa/Iqo1a//YAAAAUAAAAAQAAAAYAAAABwfs5RVshthImbX+wmqWS0t1AjL4y5EjMMtSk/oEy11AAAAAUAAAAAQAAAAeheXOfVamUQyN7XuqlXPfXnmxx6tJxnGFVIA2YxmGnMwAAAAIAAAABAAAAAOFj7vkclxiPEDTsyEPNmT8PBDNUhN72yULAOBwQZxz4AAAAAlRFU1Q0AAAAAAAAAAAAAAAagL+zRaDmKTHWcB67aFNUZNLVg6ojcyrbO1u3Sg/KcAAAAAYAAAABEGJ2U3ldj9dca1n1NK0i2XkfL/5zXZsxAOIxUmn9RWkAAAAVJ2IQI0lsUYEAAAAAABUmowAADXgAAADEAAAAAAACfDsAAAAA
> ```
>
> **Expected behavior**
>
> The function should not assume all auth entries addresses are stellar accounts -- it should also support contract addresses.
@chadoh chadoh linked a pull request Sep 10, 2024 that will close this issue
@chadoh
Copy link
Contributor

chadoh commented Sep 10, 2024

I've fixed the nonInvokerSigningBy return in #1044, but didn't yet alter the behavior of signAuthEntries. I'm not totally sure the correct way to handle it, yet.

I love the WebAuthn tutorial you linked to, @JakeUrban, though I haven't gone the whole way through it yet. I wonder if we should turn that into an examples in https://github.com/stellar/soroban-examples, then create a real e2e test for it here (the test I added in #1044 is in the e2e folder, but it's not actually an end-to-end test).

@JakeUrban
Copy link
Contributor Author

I'm in favor of turning it into an example in the repo.

I do think updating signAuthEntries() and authorizeEntry() to support signatures from signers of contract accounts is in the critical path to smart wallet adoption though, so I think this should be prioritized. cc @janewang

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Needs Review
Development

Successfully merging a pull request may close this issue.

5 participants