-
Notifications
You must be signed in to change notification settings - Fork 138
Paymaster PR 5: examples + CI workflow #809
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
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
b502ed5
feat: add a new paymaster example to demonstrate interaction with pay…
thiagodeev 68adaf3
ci: add tests for the paymaster in the CI workflow
thiagodeev 1761fa0
ci: update GitHub Actions to use latest versions of checkout and setu…
thiagodeev 3f0b971
docs: update README for paymaster example to include SNIP-29 link
thiagodeev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| name: paymaster integration tests | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - main | ||
|
|
||
| jobs: | ||
| run: | ||
| runs-on: ubuntu-22.04 | ||
|
|
||
| steps: | ||
| - name: Checkout branch | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up Go | ||
| uses: actions/setup-go@v4 | ||
thiagodeev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| with: | ||
| go-version-file: go.mod | ||
|
|
||
| - name: Run paymaster tests | ||
| run: cd paymaster && go test -timeout 300s -v -env integration . | ||
| env: | ||
| STARKNET_PRIVATE_KEY: ${{ secrets.TESTNET_ACCOUNT_PRIVATE_KEY }} | ||
| STARKNET_PUBLIC_KEY: ${{ secrets.TESTNET_ACCOUNT_PUBLIC_KEY }} | ||
| STARKNET_ACCOUNT_ADDRESS: ${{ secrets.TESTNET_ACCOUNT_ADDRESS }} | ||
| AVNU_API_KEY: ${{ secrets.AVNU_API_KEY }} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| This example demonstrates how to send transactions on Starknet with a paymaster using the Starkent.go SNIP-29 implementation, allowing you to pay fees with tokens other than STRK. | ||
thiagodeev marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| It has three files: main.go, deploy.go, and deploy_and_invoke.go. | ||
|
|
||
| The main.go file shows how to send an invoke transaction using a paymaster with the "default" fee mode, where you pay fees using supported tokens (like STRK). It demonstrates the complete 3-step process: building the transaction via the paymaster, signing it with your account, and executing the transaction. | ||
|
|
||
| The deploy.go file demonstrates how to deploy a new account using a paymaster with the "sponsored" fee mode, where an entity covers the transaction fees. | ||
| The deploy_and_invoke.go file shows how to deploy an account and invoke a function in the same transaction using a paymaster, combining both deployment and execution in a single request. | ||
| Both of these `deploy...`examples require a valid paymaster API key. | ||
|
|
||
| All examples demonstrate integration with the AVNU paymaster service and require SNIP-9 compatible accounts. | ||
|
|
||
| Steps: | ||
| 1. Rename the ".env.template" file located at the root of the "examples" folder to ".env" | ||
| 2. Uncomment, and assign your Sepolia testnet endpoint to the `RPC_PROVIDER_URL` variable in the ".env" file | ||
| 3. Uncomment, and assign your SNIP-9 compatible account address to the `ACCOUNT_ADDRESS` variable in the ".env" file (make sure to have some STRK tokens in it) | ||
| 4. Uncomment, and assign your starknet public key to the `PUBLIC_KEY` variable in the ".env" file | ||
| 5. Uncomment, and assign your private key to the `PRIVATE_KEY` variable in the ".env" file | ||
| 6. Make sure you are in the "paymaster" directory | ||
| 7. Execute `go run .` to run the basic paymaster invoke example | ||
| 8. To run the deploy examples (requires API key), uncomment the function calls at the end of main.go and execute again. Also, uncomment, and assign your paymaster API key to the `AVNU_API_KEY` variable in the ".env" file | ||
|
|
||
| The transaction hashes, tracking IDs, and execution status will be returned at the end of each example. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,133 @@ | ||
| package main | ||
|
|
||
| import ( | ||
| "context" | ||
| "fmt" | ||
|
|
||
| "github.com/NethermindEth/juno/core/felt" | ||
| "github.com/NethermindEth/starknet.go/account" | ||
| "github.com/NethermindEth/starknet.go/client" | ||
| setup "github.com/NethermindEth/starknet.go/examples/internal" | ||
| "github.com/NethermindEth/starknet.go/internal/utils" | ||
| pm "github.com/NethermindEth/starknet.go/paymaster" | ||
| ) | ||
|
|
||
| // OpenZeppelin account class hash that supports outside executions | ||
| const OZAccountClassHash = "0x05b4b537eaa2399e3aa99c4e2e0208ebd6c71bc1467938cd52c798c601e43564" | ||
|
|
||
| // An example of how to deploy a contract with a paymaster. | ||
| func deployWithPaymaster() { | ||
| fmt.Println("Starting paymaster example - deploying an account") | ||
|
|
||
| // Load variables from '.env' file | ||
| AVNUApiKey := setup.GetAVNUApiKey() | ||
|
|
||
| // Since all accounts in Starknet are smart contracts, we need to deploy them first before we can use them. | ||
| // And to do so, we need to calculate the address of the new account and fund it with | ||
| // enough STRK tokens before deploying it. This tokens will be used to pay the fees for the `deploy` txn. | ||
| // | ||
| // Deploy an account with a paymaster using the `default` fee mode doesn't make much sense, as we will | ||
| // need to send some tokens for the account anyway. So, we will use the `sponsored` fee mode now, | ||
| // which will allow the paymaster to fully cover the fees for the `deploy` txn. This mode requires | ||
| // an API key from an entity. You can only run this example with it. | ||
|
|
||
| // Let's initialise the paymaster client, but now, we will also pass our API key to the client. | ||
| // In the AVNU paymaster, the API key is a http header called `x-paymaster-api-key`. | ||
| // In the current Starknet.go client, you can set a custom http header using the `client.WithHeader` option. | ||
| paymaster, err := pm.New( | ||
| context.Background(), | ||
| AVNUPaymasterURL, | ||
| client.WithHeader("x-paymaster-api-key", AVNUApiKey), | ||
| ) | ||
| if err != nil { | ||
| panic(fmt.Errorf("error connecting to the paymaster provider with the API key: %w", err)) | ||
| } | ||
|
|
||
| fmt.Println("Established connection with the paymaster provider") | ||
| fmt.Print("Step 1: Build the deploy transaction\n\n") | ||
|
|
||
| // First, let's get all the data we need for deploy an account. | ||
| _, pubKey, privK := account.GetRandomKeys() // Get random keys for the account | ||
| fmt.Println("Public key:", pubKey) | ||
| fmt.Println("Private key:", privK) | ||
| classHash, _ := utils.HexToFelt( | ||
| OZAccountClassHash, | ||
| ) // It needs to be an SNIP-9 compatible account | ||
| constructorCalldata := []*felt.Felt{ | ||
| pubKey, | ||
| } // The OZ account constructor requires the public key | ||
| salt, _ := utils.HexToFelt("0xdeadbeef") // Just a random salt | ||
| // Precompute the address of the new account based on the salt, class hash and constructor calldata | ||
| precAddress := account.PrecomputeAccountAddress(salt, classHash, constructorCalldata) | ||
|
|
||
| fmt.Println("Precomputed address:", precAddress) | ||
|
|
||
| // Now we can create the deploy data for the transaction. | ||
| deployData := &pm.AccountDeploymentData{ | ||
| Address: precAddress, // The precomputed address of the new account | ||
| ClassHash: classHash, | ||
| Salt: salt, | ||
| Calldata: constructorCalldata, | ||
| SignatureData: []*felt.Felt{}, // Optional. For the OZ account, we don't need to add anything in the signature data. | ||
| Version: pm.Cairo1, | ||
| } | ||
|
|
||
| // With the deploy data, we can build the transaction by calling the `paymaster_buildTransaction` method. | ||
| // REMEMBER: this will only work if you have a valid API key configured. | ||
| // | ||
| // A full explanation about the paymaster_buildTransaction method can be found in the `main.go` file of this same example. | ||
| builtTxn, err := paymaster.BuildTransaction(context.Background(), &pm.BuildTransactionRequest{ | ||
| Transaction: pm.UserTransaction{ | ||
| Type: pm.UserTxnDeploy, // we are building an `deploy` transaction | ||
| Deployment: deployData, | ||
| }, | ||
| Parameters: pm.UserParameters{ | ||
| Version: pm.UserParamV1, | ||
| FeeMode: pm.FeeMode{ | ||
| Mode: pm.FeeModeSponsored, // We then set the fee mode to `sponsored` | ||
| Tip: &pm.TipPriority{ | ||
| Priority: pm.TipPriorityNormal, | ||
| }, | ||
| }, | ||
| }, | ||
| }) | ||
| if err != nil { | ||
| panic(fmt.Errorf("error building the deploy transaction: %w", err)) | ||
| } | ||
| fmt.Println("Transaction successfully built by the paymaster") | ||
| PrettyPrint(builtTxn) | ||
|
|
||
| // Since we are deploying an account, we don't need to sign the transaction, just execute it. | ||
|
|
||
| fmt.Println("Step 2: Send the signed transaction") | ||
|
|
||
| // With our built deploy transaction, we can send it to the paymaster by calling the `paymaster_executeTransaction` method. | ||
| response, err := paymaster.ExecuteTransaction( | ||
| context.Background(), | ||
| &pm.ExecuteTransactionRequest{ | ||
| Transaction: pm.ExecutableUserTransaction{ | ||
| Type: pm.UserTxnDeploy, | ||
| Deployment: builtTxn.Deployment, // The deployment data is the same. We can use our `deployData` variable, or | ||
| // the `builtTxn.Deployment` value. | ||
| }, | ||
| Parameters: pm.UserParameters{ | ||
| Version: pm.UserParamV1, | ||
|
|
||
| // Using the same fee options as in the `paymaster_buildTransaction` method. | ||
| FeeMode: pm.FeeMode{ | ||
| Mode: pm.FeeModeSponsored, | ||
| Tip: &pm.TipPriority{ | ||
| Priority: pm.TipPriorityNormal, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| ) | ||
| if err != nil { | ||
| panic(fmt.Errorf("error executing the deploy transaction with the paymaster: %w", err)) | ||
| } | ||
|
|
||
| fmt.Println("Deploy transaction successfully executed by the paymaster") | ||
| fmt.Println("Tracking ID:", response.TrackingID) | ||
| fmt.Println("Transaction Hash:", response.TransactionHash) | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.