Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
102 commits
Select commit Hold shift + click to select a range
7ca9b6d
adding changes for snip29.
Salonii02 Jun 30, 2025
1bc1dd6
fix: outdated function name call due to merge with main
thiagodeev Aug 29, 2025
9a4de8d
chore: remove new paymaster tests from the mock_test.go file
thiagodeev Aug 29, 2025
36d971d
refactor: move paymaster code to a dedicated paymaster pkg
thiagodeev Aug 29, 2025
c89995b
refactor: update Paymaster client and the NewPaymasterClient() logic
thiagodeev Aug 29, 2025
6887e55
chore: regenerate paymaster mock
thiagodeev Aug 29, 2025
5e60153
chore: go mod tidy
thiagodeev Aug 29, 2025
ea31ab7
test: add setup function for paymaster tests with mock and integratio…
thiagodeev Sep 2, 2025
7e8c1ee
fix: fix circular import error by removing the paymaster mock and int…
thiagodeev Sep 2, 2025
2e36e60
refactor: simplify paymaster test setup functions by introducing Mock…
thiagodeev Sep 2, 2025
66b270d
test: add IsAvailable method tests for both integration and mock scen…
thiagodeev Sep 2, 2025
ac81e9c
fix: linter errors + wrong additional parameter in the paymaster RPC …
thiagodeev Sep 2, 2025
b1df8e1
docs: update comments for Paymaster methods and TokenData structure f…
thiagodeev Sep 2, 2025
f939221
test: add GetSupportedTokens method tests and enable parallel executi…
thiagodeev Sep 2, 2025
db84d45
test: enhance GetSupportedTokens test with mock test and enable paral…
thiagodeev Sep 4, 2025
345876b
docs: enhance comments for TrackingIdResponse and add new enum for tx…
thiagodeev Sep 5, 2025
ea3faf7
refactor: update comments for BuildTransaction method and enhance Use…
thiagodeev Sep 5, 2025
a5cab64
feat: add JSON marshaling and unmarshaling for TxnStatus to improve s…
thiagodeev Sep 5, 2025
f26ae82
refactor: move BuildTransaction method and related types to a separat…
thiagodeev Sep 5, 2025
c247c33
feat: add PaymasterInterface with method signatures
thiagodeev Sep 5, 2025
42d9ffa
refactor: improve UserTransaction type with new types
thiagodeev Sep 5, 2025
363dc2a
refactor: update transaction building types to use pointers and enhan…
thiagodeev Sep 5, 2025
feb1521
refactor: enhance UserParameters with optional TimeBounds
thiagodeev Sep 5, 2025
c529a99
test: new test for the UserTxnType type and a helper to facilitate en…
thiagodeev Sep 5, 2025
fa6bc53
test: add new tests for FeeModeType
thiagodeev Sep 5, 2025
c8d6d2a
test: add integration test for BuildTransaction and improve parallel …
thiagodeev Sep 5, 2025
da34055
fix: linter errors
thiagodeev Sep 5, 2025
cee0a52
refactor: introduce UserParamVersion type for execution parameter ver…
thiagodeev Sep 9, 2025
10e56f4
test: add unit tests for UserParamVersion type to validate input and …
thiagodeev Sep 9, 2025
0476e20
test: update integration test for BuildTransaction to utilize UserPar…
thiagodeev Sep 9, 2025
b714871
feat: add Paymaster-specific error handling and structured error data…
thiagodeev Sep 12, 2025
e8bbd6f
feat: improve error handling in BuildTransaction by wrapping errors w…
thiagodeev Sep 12, 2025
293abad
test: update test environment handling and add main test for Paymaste…
thiagodeev Sep 12, 2025
272e118
test: enhance test environment setup for Paymaster tests and improve …
thiagodeev Sep 12, 2025
9d932a0
test: remove redundant paymaster tests
thiagodeev Sep 12, 2025
51eb283
fix: linter errors
thiagodeev Sep 12, 2025
0c4c865
test: enhance BuildTransaction test for 'deploy' transaction type and…
thiagodeev Sep 12, 2025
c45c587
test: refactor SetupPaymaster to return spy for enhanced testing and …
thiagodeev Sep 15, 2025
c30ed53
test: update BuildTransaction test to assert JSON equality with spy's…
thiagodeev Sep 15, 2025
ad35642
test: enhance BuildTransaction test for 'deploy' transaction type wit…
thiagodeev Sep 15, 2025
8da843d
chore: move Call and UserInvoke types to build_txn.go for better orga…
thiagodeev Sep 15, 2025
91936f7
test: add utility function for STRK account data retrieval
thiagodeev Sep 15, 2025
ddd8a7a
test: add 'invoke' transaction type tests with sponsored and default …
thiagodeev Sep 16, 2025
ffe1328
chore: update BuildTransactionResponse to use typedData.TypedData for…
thiagodeev Sep 16, 2025
29ca4ee
feat: implement the fee mode changes in the SNIP-29 introduced by the…
thiagodeev Sep 17, 2025
e8fd861
test: add ExecuteTransaction test file
thiagodeev Sep 24, 2025
7d3f597
test: enhance TestBuildTransaction with deploy-and-invoke transaction…
thiagodeev Sep 17, 2025
3509f9b
test: add mock tests for deploy transaction type in TestBuildTransaction
thiagodeev Sep 17, 2025
4de4e32
test: add mock tests for invoke transaction type in TestBuildTransaction
thiagodeev Sep 17, 2025
1a2c5dc
test: add mock tests for deploy_and_invoke transaction type in TestBu…
thiagodeev Sep 17, 2025
2b2b79c
feat: implement ExecuteTransaction functionality in paymaster
thiagodeev Sep 17, 2025
fef8b6e
test: update ExecuteTransaction tests and refactor related functions
thiagodeev Sep 19, 2025
43fd273
fix: improve error handling in ExecuteTransaction method
thiagodeev Sep 19, 2025
4e3c542
test: enhance ExecuteTransaction tests with additional logging and in…
thiagodeev Sep 19, 2025
e1cab78
test: enhance ExecuteTransaction tests with improved logging and invo…
thiagodeev Sep 24, 2025
93c2903
test: update buildDeployTxn for Argent account class support
thiagodeev Sep 25, 2025
66a2ea3
test: enhance ExecuteTransaction tests with deploy_and_invoke transac…
thiagodeev Sep 26, 2025
66c0e6b
test: improve transaction building functions with dedicated data crea…
thiagodeev Sep 26, 2025
535e1f7
test: refactor ExecuteTransaction test to utilize buildDeployAndInvok…
thiagodeev Sep 26, 2025
05f9087
test: add mock tests for ExecuteTransaction with test case for the de…
thiagodeev Sep 26, 2025
86c46ae
test: add invoke transaction test case to ExecuteTransaction mock tests
thiagodeev Sep 26, 2025
8a03b59
test: add deploy_and_invoke transaction test case to ExecuteTransacti…
thiagodeev Sep 26, 2025
4bbe0c9
fix: linter errors
thiagodeev Sep 26, 2025
c0f9344
refactor: remove unused outside execution typed data structures and r…
thiagodeev Sep 26, 2025
d9d97a1
refactor: separate the IsAvailable method and related tests to separa…
thiagodeev Sep 26, 2025
e3becfb
refactor: separate the GetSupportedTokens method and related tests to…
thiagodeev Sep 26, 2025
a11064b
refactor: separate the TrackingIdToLatestHash method to a separate file
thiagodeev Sep 26, 2025
2b785f4
refactor: make TrackingIdToLatestHash return rpc error
thiagodeev Sep 26, 2025
f181af6
test: add unit test for TrackingIdToLatestHash method in paymaster
thiagodeev Sep 26, 2025
272e9f3
test: add unit tests for TxnStatus enum in paymaster
thiagodeev Sep 26, 2025
5a10d91
refactor: move TxnStatus and TrackingIdResponse to tracking_id.go
thiagodeev Sep 26, 2025
a005aa4
refactor: move TokenData type to the get_tokens.go file to better org…
thiagodeev Sep 26, 2025
da70bc9
refactor: rename types_paymaster.go to errors.go
thiagodeev Sep 26, 2025
49df45d
refactor: make PaymasterInterface a private type
thiagodeev Sep 26, 2025
3af2759
docs: clarify Cairo version comment in AccDeploymentData struct
thiagodeev Sep 29, 2025
5f29855
test: move CompareEnumsHelper to the main_test.go file
thiagodeev Sep 29, 2025
34470df
refactor: update FeeMode and TipPriority structures for clarity
thiagodeev Sep 29, 2025
4ba3fe8
refactor: rename NewPaymasterClient to New
thiagodeev Sep 29, 2025
a1cfae8
feat: add paymaster example
thiagodeev Sep 29, 2025
3a54039
Merge branch 'main' into implement-SNIP-29-issue-745
thiagodeev Sep 30, 2025
4b0040d
docs: add description to the options parameter in the paymaster.New()…
thiagodeev Sep 30, 2025
46e8849
feat: new deploy txn paymaster example
thiagodeev Sep 30, 2025
815aed0
feat: new deploy_and_invoke txn paymaster example
thiagodeev Sep 30, 2025
b0f3eb2
docs: enhance paymaster example with detailed usage instructions abou…
thiagodeev Sep 30, 2025
5348031
docs: add README for paymaster example with detailed instructions on …
thiagodeev Sep 30, 2025
fe98f1b
feat: add AVNU_API_KEY var support in paymaster examples
thiagodeev Sep 30, 2025
906b1c6
docs: update README and examples to include paymaster interaction
thiagodeev Sep 30, 2025
d65078b
feat: add paymaster integration tests workflow
thiagodeev Oct 1, 2025
82df67e
fix: linter errors
thiagodeev Oct 1, 2025
93d1ffa
Merge branch 'main' into implement-SNIP-29-issue-745
thiagodeev Oct 15, 2025
af63339
refactor: update code to new changes from main
thiagodeev Oct 15, 2025
a0f648f
fix: linter errors
thiagodeev Oct 15, 2025
7339f9d
chore: increase hugeParam threshold
thiagodeev Oct 17, 2025
333c678
refactor: make BuildTransaction accept and return values instead of p…
thiagodeev Oct 17, 2025
edcf96b
docs: explain the reason of not use omitempty in TimeBounds
thiagodeev Oct 17, 2025
e5b1fba
refactor: make ExecuteTransaction accept and return values instead of…
thiagodeev Oct 17, 2025
4ada05b
chore: update examples with the new changes
thiagodeev Oct 17, 2025
ca0a823
docs: nolint statement automatically removed with the new hugeParam t…
thiagodeev Oct 17, 2025
f7affd4
Merge branch 'main' into implement-SNIP-29-issue-745
thiagodeev Oct 17, 2025
913a0d8
chore: rename ConstructorCalldata to Calldata in AccDeploymentData
thiagodeev Oct 17, 2025
7aefaf5
chore: rename AccDeploymentData to AccountDeploymentData
thiagodeev Oct 17, 2025
bf5f133
refactor: change UserTxnType to use int values instead of string
thiagodeev Oct 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/test_mock_and_examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
cd ../readEvents && go build
cd ../simpleCall && go build
cd ../simpleDeclare && go build
cd ../paymaster && go build
cd ../typedData && go build
cd ../websocket && go build

Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/test_paymaster.yml
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
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 }}
8 changes: 8 additions & 0 deletions .golangci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ linters:
min-occurrences: 3
gocritic:
enable-all: true
settings:
hugeParam:
sizeThreshold: 256
gocyclo:
min-complexity: 15
govet:
Expand Down Expand Up @@ -109,7 +112,12 @@ linters:
- gosec
- lll
- mnd
- funlen # it's ok for the examples to have big main() functions
path: examples/
- linters:
- gocritic #commentedOutCode: "curve.SignFelts..." is there just as an explanation
- unused # it's part of the example to have two unused functions
path: examples/paymaster/
- linters:
- exhaustruct
- noctx
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ operations on the wallets. The package has excellent documentation for a smooth
- [invoke transaction example](./examples/invoke) to add a new invoke transaction on testnet.
- [declare transaction example](./examples/simpleDeclare) to add a new contract on testnet.
- [deploy contract UDC example](./examples/deployContractUDC) to deploy an ERC20 token using [UDC (Universal Deployer Contract)](https://docs.openzeppelin.com/contracts-cairo/1.0.0/udc) on testnet.
- [paymaster example](./examples/paymaster) to learn how to interact with a paymaster and send transactions with it.
- [typed data example](./examples/typedData) to sign and verify a typed data.
- [websocket example](./examples/websocket) to learn how to subscribe to WebSocket methods.

Expand Down
5 changes: 4 additions & 1 deletion examples/.env.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@
#ACCOUNT_ADDRESS=0xyour_account_address
#PUBLIC_KEY=0xyour_starknet_public_key
#PRIVATE_KEY=0xyour_private_key
#ACCOUNT_CAIRO_VERSION=2
#ACCOUNT_CAIRO_VERSION=2

# ----- use this variable for specific cases in the paymaster example
#AVNU_API_KEY=your-api-key
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ To run an example:
R: See [typedData](./typedData/main.go).
1. How to use WebSocket methods? How to subscribe, unsubscribe, handle errors, and read values from them?
R: See [websocket](./websocket/main.go).
1. How to interact with a paymaster? How to send transactions with it?
R: See [paymaster](./paymaster/main.go).
5 changes: 5 additions & 0 deletions examples/internal/setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ func GetAccountCairoVersion() account.CairoVersion {
}
}

// Validates whether the AVNU_API_KEY variable has been set in the '.env' file and returns it; panics otherwise.
func GetAVNUApiKey() string {
return getEnv("AVNU_API_KEY")
}

// Loads an env variable by name and returns it; panics otherwise.
func getEnv(envName string) string {
env := os.Getenv(envName)
Expand Down
22 changes: 22 additions & 0 deletions examples/paymaster/README.md
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.
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.
132 changes: 132 additions & 0 deletions examples/paymaster/deploy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
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(
AVNUPaymasterURL,
client.WithHeader("x-paymaster-api-key", AVNUApiKey),
)
if err != nil {
panic(fmt.Sprintf("Error connecting to the paymaster provider with the API key: %s", 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: 2, // The OZ account version is 2.
}

// 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.Sprintf("Error building the deploy transaction: %s", 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.Sprintf("Error executing the deploy transaction with the paymaster: %s", err))
}

fmt.Println("Deploy transaction successfully executed by the paymaster")
fmt.Println("Tracking ID:", response.TrackingID)
fmt.Println("Transaction Hash:", response.TransactionHash)
}
Loading