-
Notifications
You must be signed in to change notification settings - Fork 709
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
Implement SNIP-9 #1111
base: develop
Are you sure you want to change the base?
Implement SNIP-9 #1111
Conversation
To explain my choice of hashing algorithms: In the SNIP-9 specification it's stated that SNIP-12 should be used for hashing. There are 2 revisions of |
thanks!! we will take a deep look! |
We should add documentation for OutsideExecution usage |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general lgtm.
- docs
- e2e account test
src/types/outsideExecution.ts
Outdated
|
||
export const OutsideExecutionCallerAny = encodeShortString('ANY_CALLER'); | ||
|
||
export class OutsideExecution { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We used (because of initial setup) types dir for pure type definitions and utils for implementations.
I think this is fine but it will break existing convenience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I will leave the interface inside types
and move the class and implementation into utils
, if it's fine
__tests__/outsideExecution.ts
Outdated
|
||
expect(abiData).toEqual(expectedResult); | ||
}); | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there an Acc implementing this snip so we can test it on Account?
If so I would like to have a full e2e test with ACC using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, Argent and Braavos support it at least on Sepolia, I'll write the missing test in a few days, sorry for the delay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just realized that OZ account contract doesn't support SNIP-9 yet. And both Argent and Braavos are distributed under GPL, so I can't just take their compiled contracts and put them into __mocks__
directory. I can request a feature on OZ but nobody knows how long it will take. If I compile a "dummy" account contract with minimal execute_from_outside
implementation and use it in tests, will it count as a valid test?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tagging Argent folks, @janek26 @dhruvkelawala hi! for testing purposes, does GPL license allow usage of your Account contract for testing this SNIP? @kfastov I don't think we would have problems with the GPL license, this is a non-profit library in any case :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ivpavici all good to use our contracts. double checked it with Sergio.
@kfastov hi! Will you have time to add these couple of things left? 🙏 |
Hello! Sorry for being slow, had to make a forced break in development, but now I am here again. |
@kfastov hi hi! gentle ping about this PR :) |
@ivpavici Thank you for waiting so long 🙏. I'll push the updates tomorrow |
Sorry out of time today, but I'll certainly do it on Friday |
@ivpavici @tabaktoni I've added docs and changed the file structure to match convention. Can you please review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pointed out some minor issues, in general lgtm.
There are also four TODOs that appear to mostly be stragglers, they are either done or the mentioned choices seem fine to me.
docs: remove unnecessary section for OutsideExecution guide
@penovicp Can you please check now? |
} | ||
// if not, return it | ||
return nonce; | ||
// TODO process errors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kfastov is this a leftover or?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll do couple more checks (suggested by @PhilippeR26 ) and decide if there need to be any error checks here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For information, current ArgentX account contract is version v0.4.0.
I have to check if it has impacts on snip-9 implementation.
Hello, import { OutsideExecution, OutsideExecutionOptions } from 'starknet'; In fact it seems that nothing has been exported to the user level. |
Is your code handling smoothly accounts that are not implementing the ERC165 (introspection)? |
Oops, my bad, I'll fix it now |
docs: update documentation to match the code
@kfastov Have you finalized your modifications ? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't checked the code, the test & the doc.
I focused on my own tests and the resulting UX.
In most cases, it works, but this case is still crashing : #1111 (comment) (in Account.getSnip9Version()
).
I tested the following accounts :
- ArgentX 0.4.0 : v2
- Braavos 1.0.0 : v2
- ArgentX 0.3.1 : v1
- OpenZeppelin 0.14.0 : not supported
- special : ERC165 & SNIP-9 not supported.
If you want to play with them : https://github.com/PhilippeR26/starknet.js-workshop-typescript/blob/main/src/scripts/Starknet131/Starknet131-devnet/16.ExecuteFromOutside.ts
Nevertheless, I am not happy about the user experience ; it's really not straightforward and pleasant. I think that this new OutsideExecution class is the origin of the problem.
I tested several things, and I think that we are able to have a such code on user side, with many things calculated automatically in the Account class :
// option has no nonce ; it will be generated automatically.
const options: OutsideExecutionOptions = {
caller: "ANY_CALLER", // and not outsideExecution.OutsideExecutionCallerAny
execute_after: Math.floor(Date.now() / 1000) - 3600, // 1 hour ago
execute_before: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now
};
const call1 = {
contractAddress: ethAddress,
entrypoint: 'transfer',
calldata: {
recipient: account1.address,
amount: cairo.uint256(10n ** 15n),
},
};
const call2 = {
contractAddress: ethAddress,
entrypoint: 'transfer',
calldata: {
recipient: account2.address,
amount: cairo.uint256(2n * 10n ** 15n),
},
};
// account A is compatible with SNIP-9
const outsideTransaction1 = await accountA.getOutsideTransaction(options, call1);
const outsideTransaction2 = await accountA.getOutsideTransaction(options, call2);
// accountB can be not compatible with SNIP-9
// no mandatory order to proceed
const res0 = accountB.executeFromOutside(outsideTransaction2, addressOfAccountA);
await myProvider.waitForTransaction(res0.transaction_hash);
const res1 = accountB.executeFromOutside(outsideTransaction1, addressOfAccountA);
await myProvider.waitForTransaction(res1.transaction_hash);
You can see as easy it can be.
Please consider to change the Account class in accordance to this proposal.
PS : getSnip9Version()
should respond "UNSUPPORTED", and not "0" as currently.
Motivation and Resolution
This PR implements the SNIP-9 (outside execution) standard in starknet.js. SNIP-9 enables protocols to submit transactions on behalf of a user account, as long as they have the relevant signatures. This feature provides flexibility for various use cases such as delayed orders and fee subsidies.
The implementation follows the SNIP-9 specification and introduces new types, utilities, and account methods to support off-chain signatures. It includes the OutsideExecution class, which represents an outside transaction to be executed on behalf of the user account. The Account class has been extended with methods to get the supported SNIP-9 version, check nonce validity, and execute an outside execution.
RPC version (if applicable)
N/A
Usage related changes
OutsideExecution
,OutsideCall
, andEOutsideExecutionVersion
.Account
class with methods to support SNIP-9:getSnip9Version
: Retrieves the supported SNIP-9 version of the account.isValidSnip9Nonce
: Checks if a given nonce is valid for the account.executeFromOutside
: Executes an outside execution on behalf of the account.Development related changes
buildExecuteFromOutsideCallData()
andgetSnip9Nonce()
.Checklist:
Things left:
Fixes #948