diff --git a/.github/workflows/main_ci_check.yml b/.github/workflows/main_ci_check.yml index 065db2f4..ebaf54a6 100644 --- a/.github/workflows/main_ci_check.yml +++ b/.github/workflows/main_ci_check.yml @@ -16,12 +16,13 @@ jobs: - 5050:5050 steps: - - uses: actions/checkout@v3 + - name: Checkout branch + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: 1.18 + go-version-file: go.mod - name: wait for devnet to be up... run: ./.bin/devnet.sh diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e88f05b7..2527caad 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,12 +19,13 @@ jobs: - 5050:5050 steps: - - uses: actions/checkout@v3 + - name: Checkout branch + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: 1.18 + go-version-file: go.mod - name: wait for devnet to be up... run: ./.bin/devnet.sh diff --git a/.github/workflows/test_account.yml b/.github/workflows/test_account.yml index e98a27ee..ec6784e3 100644 --- a/.github/workflows/test_account.yml +++ b/.github/workflows/test_account.yml @@ -19,10 +19,10 @@ jobs: steps: - name: Checkout branch - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v4.1.0 + uses: actions/setup-go@v4 with: go-version-file: go.mod diff --git a/.github/workflows/test_rpc.yml b/.github/workflows/test_rpc.yml index b80d5e50..4a5b26b5 100644 --- a/.github/workflows/test_rpc.yml +++ b/.github/workflows/test_rpc.yml @@ -18,12 +18,13 @@ jobs: - 5050:5050 steps: - - uses: actions/checkout@v3 + - name: Checkout branch + uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: 1.18 + go-version-file: go.mod - name: wait for devnet to be up... run: ./.bin/devnet.sh diff --git a/README.md b/README.md index 61d37846..b44273ae 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,7 @@ go run main.go | `starknet_getTransactionByHash` | :heavy_check_mark: | | `starknet_getTransactionByBlockIdAndIndex` | :heavy_check_mark: | | `starknet_getTransactionReceipt` | :heavy_check_mark: | +| `starknet_getTransactionStatus` | :heavy_check_mark: | | `starknet_getClass` | :heavy_check_mark: | | `starknet_getClassHashAt` | :heavy_check_mark: | | `starknet_getClassAt` | :heavy_check_mark: | diff --git a/account/account.go b/account/account.go index 20ccc438..8964a4dd 100644 --- a/account/account.go +++ b/account/account.go @@ -396,16 +396,16 @@ func (account *Account) Syncing(ctx context.Context) (*rpc.SyncStatus, error) { return account.provider.Syncing(ctx) } -func (account *Account) TraceBlockTransactions(ctx context.Context, blockHash *felt.Felt) ([]rpc.Trace, error) { - return account.provider.TraceBlockTransactions(ctx, blockHash) +func (account *Account) TraceBlockTransactions(ctx context.Context, blockID rpc.BlockID) ([]rpc.Trace, error) { + return account.provider.TraceBlockTransactions(ctx, blockID) } func (account *Account) TransactionReceipt(ctx context.Context, transactionHash *felt.Felt) (rpc.TransactionReceipt, error) { return account.provider.TransactionReceipt(ctx, transactionHash) } -func (account *Account) TransactionTrace(ctx context.Context, transactionHash *felt.Felt) (rpc.TxnTrace, error) { - return account.provider.TransactionTrace(ctx, transactionHash) +func (account *Account) TraceTransaction(ctx context.Context, transactionHash *felt.Felt) (rpc.TxnTrace, error) { + return account.provider.TraceTransaction(ctx, transactionHash) } func (account *Account) TransactionByBlockIdAndIndex(ctx context.Context, blockID rpc.BlockID, index uint64) (rpc.Transaction, error) { @@ -416,6 +416,10 @@ func (account *Account) TransactionByHash(ctx context.Context, hash *felt.Felt) return account.provider.TransactionByHash(ctx, hash) } +func (account *Account) GetTransactionStatus(ctx context.Context, Txnhash *felt.Felt) (*rpc.TxnStatusResp, error) { + return account.provider.GetTransactionStatus(ctx, Txnhash) +} + func (account *Account) FmtCalldata(fnCalls []rpc.FunctionCall, cairoVersion int) ([]*felt.Felt, error) { switch cairoVersion { case 0: diff --git a/account/account_test.go b/account/account_test.go index 372cfbf6..393af5c9 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -776,7 +776,6 @@ func TestAddDeclareTxn(t *testing.T) { SenderAddress: AccountAddress, CompiledClassHash: compClassHash, ClassHash: classHash, - ContractClass: class, } err = acnt.SignDeclareTransaction(context.Background(), &tx) diff --git a/examples/deployAccount/go.mod b/examples/deployAccount/go.mod index c031a165..d2d1fc18 100644 --- a/examples/deployAccount/go.mod +++ b/examples/deployAccount/go.mod @@ -1,6 +1,6 @@ module account -go 1.18 +go 1.21 require ( github.com/NethermindEth/juno v0.3.1 @@ -14,14 +14,15 @@ replace github.com/NethermindEth/starknet.go => ../../ require ( github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.11.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.0 // indirect - github.com/google/go-querystring v1.1.0 // indirect github.com/gorilla/websocket v1.4.2 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/stretchr/testify v1.8.1 // indirect @@ -33,4 +34,5 @@ require ( golang.org/x/sys v0.3.0 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/examples/deployAccount/go.work b/examples/deployAccount/go.work index b32bc53a..01071242 100644 --- a/examples/deployAccount/go.work +++ b/examples/deployAccount/go.work @@ -1,4 +1,4 @@ -go 1.18 +go 1.21 use ( . diff --git a/examples/simpleCall/go.mod b/examples/simpleCall/go.mod index 264a4e75..00b13ecc 100644 --- a/examples/simpleCall/go.mod +++ b/examples/simpleCall/go.mod @@ -1,6 +1,6 @@ module account -go 1.18 +go 1.21 require ( github.com/NethermindEth/starknet.go v0.2.1-0.20220620163912-1db2ca279608 diff --git a/examples/simpleCall/go.work b/examples/simpleCall/go.work index b32bc53a..01071242 100644 --- a/examples/simpleCall/go.work +++ b/examples/simpleCall/go.work @@ -1,4 +1,4 @@ -go 1.18 +go 1.21 use ( . diff --git a/examples/simpleInvoke/README.md b/examples/simpleInvoke/README.md new file mode 100644 index 00000000..b715fb2e --- /dev/null +++ b/examples/simpleInvoke/README.md @@ -0,0 +1,9 @@ +Note: To run this example, you need a testnet endpoint. + +Steps to run this example on mainnet: + +1. rename ".env.template" to ".env.testnet" +2. uncomment, and set INTEGRATION_BASE to the testnet url //You can get it from here www.alchemy.com/starknet +3. make sure you are in the "simpleInvoke" directory +4. execute `go mod tidy` +5. execute `go run main.go` diff --git a/examples/simpleInvoke/go.mod b/examples/simpleInvoke/go.mod new file mode 100644 index 00000000..96d7a8ee --- /dev/null +++ b/examples/simpleInvoke/go.mod @@ -0,0 +1,33 @@ +module account + +go 1.20 + +require ( + github.com/NethermindEth/juno v0.3.1 + github.com/NethermindEth/starknet.go v0.4.6-0.20231005024141-742a82479868 + github.com/ethereum/go-ethereum v1.10.26 + github.com/joho/godotenv v1.4.0 +) + +require ( + github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect + github.com/bits-and-blooms/bitset v1.7.0 // indirect + github.com/consensys/gnark-crypto v0.11.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set v1.8.0 // indirect + github.com/fxamacker/cbor/v2 v2.4.0 // indirect + github.com/go-ole/go-ole v1.2.1 // indirect + github.com/go-stack/stack v1.8.0 // indirect + github.com/gorilla/websocket v1.4.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/stretchr/testify v1.8.1 // indirect + github.com/test-go/testify v1.1.4 // indirect + github.com/tklauser/go-sysconf v0.3.5 // indirect + github.com/tklauser/numcpus v0.2.2 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/crypto v0.2.0 // indirect + golang.org/x/sys v0.3.0 // indirect + gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/examples/simpleInvoke/go.work b/examples/simpleInvoke/go.work new file mode 100644 index 00000000..b32bc53a --- /dev/null +++ b/examples/simpleInvoke/go.work @@ -0,0 +1,6 @@ +go 1.18 + +use ( + . + ../.. +) diff --git a/examples/simpleInvoke/main.go b/examples/simpleInvoke/main.go new file mode 100644 index 00000000..4703acde --- /dev/null +++ b/examples/simpleInvoke/main.go @@ -0,0 +1,120 @@ +package main + +import ( + "context" + "fmt" + "math/big" + "os" + + "github.com/NethermindEth/starknet.go/account" + "github.com/NethermindEth/starknet.go/rpc" + "github.com/NethermindEth/starknet.go/utils" + ethrpc "github.com/ethereum/go-ethereum/rpc" + "github.com/joho/godotenv" +) + +// NOTE : Please add in your keys only for testing purposes, incase of a leak you would potentially lose your funds. +var ( + name string = "testnet" //env."name" + account_addr string = "0x06f36e8a0fc06518125bbb1c63553e8a7d8597d437f9d56d891b8c7d3c977716" //Replace it with your account address + privateKey string = "0x0687bf84896ee63f52d69e6de1b41492abeadc0dc3cb7bd351d0a52116915937" //Replace it with your account private key + public_key string = "0x58b0824ee8480133cad03533c8930eda6888b3c5170db2f6e4f51b519141963" //Replace it with your account public key + someContract string = "0x4c1337d55351eac9a0b74f3b8f0d3928e2bb781e5084686a892e66d49d510d" //Replace it with the contract that you want to invoke + contractMethod string = "increase_value" //Replace it with the function name that you want to invoke +) + +func main() { + //Loading the env + godotenv.Load(fmt.Sprintf(".env.%s", name)) + base := os.Getenv("INTEGRATION_BASE") //please modify the .env.testnet and replace the INTEGRATION_BASE with an starknet goerli RPC. + fmt.Println("Starting simpleInvoke example") + + //Initialising the connection + c, err := ethrpc.DialContext(context.Background(), base) + if err != nil { + fmt.Println("Failed to connect to the client, did you specify the url in the .env.testnet?") + panic(err) + } + + //Initialising the provider + clientv02 := rpc.NewProvider(c) + + //Here we are converting the account address to felt + account_address, err := utils.HexToFelt(account_addr) + if err != nil { + panic(err.Error()) + } + //Initializing the account memkeyStore + ks := account.NewMemKeystore() + fakePrivKeyBI, ok := new(big.Int).SetString(privateKey, 0) + if !ok { + panic(err.Error()) + } + ks.Put(public_key, fakePrivKeyBI) + + fmt.Println("Established connection with the client") + + //Here we are setting the maxFee + maxfee, err := utils.HexToFelt("0x9184e72a000") + if err != nil { + panic(err.Error()) + } + + //Initializing the account + accnt, err := account.NewAccount(clientv02, account_address, public_key, ks) + if err != nil { + panic(err.Error()) + } + + //Getting the nonce from the account, and then converting it into felt + nonce_string, _ := accnt.Nonce(context.Background(), rpc.BlockID{Tag: "latest"}, accnt.AccountAddress) + nonce, err := utils.HexToFelt(*nonce_string) + if err != nil { + panic(err.Error()) + } + + //Building the InvokeTx struct + InvokeTx := rpc.InvokeTxnV1{ + MaxFee: maxfee, + Version: rpc.TransactionV1, + Nonce: nonce, + Type: rpc.TransactionType_Invoke, + SenderAddress: accnt.AccountAddress, + } + + //Converting the contractaddress from hex to felt + contractAddress, err := utils.HexToFelt(someContract) + if err != nil { + panic(err.Error()) + } + + //Building the functioncall struct, where : + FnCall := rpc.FunctionCall{ + ContractAddress: contractAddress, //contractAddress is the contract that we wanna call + EntryPointSelector: utils.GetSelectorFromNameFelt(contractMethod), //this is the function that we wanna call + } + + //Mentioning the contract version + CairoContractVersion := 2 + + //Building the Calldata with the help of FmtCalldata where we pass in the FnCall struct along with the Cairo version + InvokeTx.Calldata, err = accnt.FmtCalldata([]rpc.FunctionCall{FnCall}, CairoContractVersion) + if err != nil { + panic(err.Error()) + } + + //Signing of the the transaction that is done by the account + err = accnt.SignInvokeTransaction(context.Background(), &InvokeTx) + if err != nil { + panic(err.Error()) + } + + //After the signing we finally call the AddInvokeTransaction in order to invoke the contract function + resp, err := accnt.AddInvokeTransaction(context.Background(), InvokeTx) + if err != nil { + panic(err.Error()) + } + //This returns us with the transaction hash + fmt.Println("Response : ", resp.TransactionHash) + +} diff --git a/go.mod b/go.mod index ac4ecd47..4302cc47 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/NethermindEth/starknet.go -go 1.18 +go 1.21 require ( github.com/NethermindEth/juno v0.3.1 @@ -10,7 +10,6 @@ require ( github.com/nsf/jsondiff v0.0.0-20210926074059-1e845ec5d249 github.com/pkg/errors v0.9.1 github.com/test-go/testify v1.1.4 - github.com/urfave/cli/v2 v2.10.2 golang.org/x/crypto v0.2.0 ) @@ -19,7 +18,6 @@ require ( github.com/bits-and-blooms/bitset v1.7.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.11.0 // indirect - github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/fxamacker/cbor/v2 v2.4.0 // indirect @@ -28,13 +26,11 @@ require ( github.com/gorilla/websocket v1.4.2 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/stretchr/testify v1.8.1 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect github.com/x448/float16 v0.8.4 // indirect - github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect @@ -42,6 +38,5 @@ require ( require ( github.com/google/go-cmp v0.5.7 - github.com/google/go-querystring v1.1.0 golang.org/x/sys v0.3.0 // indirect ) diff --git a/go.sum b/go.sum index 0f771740..991cf63d 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,6 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.11.0 h1:QqzHQlwEqlQr5jfWblGDkwlKHpT+4QodYqqExkAtyks= github.com/consensys/gnark-crypto v0.11.0/go.mod h1:Iq/P3HHl0ElSjsg2E1gsMwhAyxnxoKK5nVyZKd+/KhU= -github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= -github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -36,11 +34,8 @@ github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= -github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -65,8 +60,6 @@ github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68 github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= -github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -83,12 +76,8 @@ github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= -github.com/urfave/cli/v2 v2.10.2 h1:x3p8awjp/2arX+Nl/G2040AZpOCHS/eMJJ1/a+mye4Y= -github.com/urfave/cli/v2 v2.10.2/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= diff --git a/mocks/mock_rpc_provider.go b/mocks/mock_rpc_provider.go index 7005032d..ba64ca45 100644 --- a/mocks/mock_rpc_provider.go +++ b/mocks/mock_rpc_provider.go @@ -276,6 +276,21 @@ func (mr *MockRpcProviderMockRecorder) Events(ctx, input interface{}) *gomock.Ca return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Events", reflect.TypeOf((*MockRpcProvider)(nil).Events), ctx, input) } +// GetTransactionStatus mocks base method. +func (m *MockRpcProvider) GetTransactionStatus(ctx context.Context, transactionHash *felt.Felt) (*rpc.TxnStatusResp, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTransactionStatus", ctx, transactionHash) + ret0, _ := ret[0].(*rpc.TxnStatusResp) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTransactionStatus indicates an expected call of GetTransactionStatus. +func (mr *MockRpcProviderMockRecorder) GetTransactionStatus(ctx, transactionHash interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTransactionStatus", reflect.TypeOf((*MockRpcProvider)(nil).GetTransactionStatus), ctx, transactionHash) +} + // Nonce mocks base method. func (m *MockRpcProvider) Nonce(ctx context.Context, blockID rpc.BlockID, contractAddress *felt.Felt) (*string, error) { m.ctrl.T.Helper() @@ -367,18 +382,33 @@ func (mr *MockRpcProviderMockRecorder) Syncing(ctx interface{}) *gomock.Call { } // TraceBlockTransactions mocks base method. -func (m *MockRpcProvider) TraceBlockTransactions(ctx context.Context, blockHash *felt.Felt) ([]rpc.Trace, error) { +func (m *MockRpcProvider) TraceBlockTransactions(ctx context.Context, blockID rpc.BlockID) ([]rpc.Trace, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TraceBlockTransactions", ctx, blockHash) + ret := m.ctrl.Call(m, "TraceBlockTransactions", ctx, blockID) ret0, _ := ret[0].([]rpc.Trace) ret1, _ := ret[1].(error) return ret0, ret1 } // TraceBlockTransactions indicates an expected call of TraceBlockTransactions. -func (mr *MockRpcProviderMockRecorder) TraceBlockTransactions(ctx, blockHash interface{}) *gomock.Call { +func (mr *MockRpcProviderMockRecorder) TraceBlockTransactions(ctx, blockID interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TraceBlockTransactions", reflect.TypeOf((*MockRpcProvider)(nil).TraceBlockTransactions), ctx, blockID) +} + +// TraceTransaction mocks base method. +func (m *MockRpcProvider) TraceTransaction(ctx context.Context, transactionHash *felt.Felt) (rpc.TxnTrace, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TraceTransaction", ctx, transactionHash) + ret0, _ := ret[0].(rpc.TxnTrace) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// TraceTransaction indicates an expected call of TraceTransaction. +func (mr *MockRpcProviderMockRecorder) TraceTransaction(ctx, transactionHash interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TraceBlockTransactions", reflect.TypeOf((*MockRpcProvider)(nil).TraceBlockTransactions), ctx, blockHash) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TraceTransaction", reflect.TypeOf((*MockRpcProvider)(nil).TraceTransaction), ctx, transactionHash) } // TransactionByBlockIdAndIndex mocks base method. @@ -425,18 +455,3 @@ func (mr *MockRpcProviderMockRecorder) TransactionReceipt(ctx, transactionHash i mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionReceipt", reflect.TypeOf((*MockRpcProvider)(nil).TransactionReceipt), ctx, transactionHash) } - -// TransactionTrace mocks base method. -func (m *MockRpcProvider) TransactionTrace(ctx context.Context, transactionHash *felt.Felt) (rpc.TxnTrace, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TransactionTrace", ctx, transactionHash) - ret0, _ := ret[0].(rpc.TxnTrace) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// TransactionTrace indicates an expected call of TransactionTrace. -func (mr *MockRpcProviderMockRecorder) TransactionTrace(ctx, transactionHash interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TransactionTrace", reflect.TypeOf((*MockRpcProvider)(nil).TransactionTrace), ctx, transactionHash) -} diff --git a/rpc/block.go b/rpc/block.go index 7625d357..aa4b7de6 100644 --- a/rpc/block.go +++ b/rpc/block.go @@ -22,11 +22,8 @@ func (provider *Provider) BlockNumber(ctx context.Context) (uint64, error) { // BlockHashAndNumber gets block information given the block number or its hash. func (provider *Provider) BlockHashAndNumber(ctx context.Context) (*BlockHashAndNumberOutput, error) { var block BlockHashAndNumberOutput - if err := do(ctx, provider.c, "starknet_blockHashAndNumber", &block); err != nil { - if errors.Is(err, errNotFound) { - return nil, ErrNoBlocks - } - return nil, err + if err := do(ctx, provider.c, "starknet_blockHashAndNumber", &block); err != nil { + return nil, tryUnwrapToRPCErr(err, ErrNoBlocks ) } return &block, nil } @@ -53,19 +50,17 @@ func WithBlockTag(tag string) BlockID { func (provider *Provider) BlockWithTxHashes(ctx context.Context, blockID BlockID) (interface{}, error) { var result BlockTxHashes if err := do(ctx, provider.c, "starknet_getBlockWithTxHashes", &result, blockID); err != nil { - if errors.Is(err, errNotFound) { - return nil, ErrBlockNotFound - } - return nil, err + return nil, tryUnwrapToRPCErr(err, ErrBlockNotFound) } // if header.Hash == nil it's a pending block if result.BlockHeader.BlockHash == nil { return &PendingBlockTxHashes{ - ParentHash: result.ParentHash, - Timestamp: result.Timestamp, - SequencerAddress: result.SequencerAddress, - Transactions: result.Transactions, + PendingBlockHeader{ + ParentHash: result.ParentHash, + Timestamp: result.Timestamp, + SequencerAddress: result.SequencerAddress}, + result.Transactions, }, nil } @@ -75,11 +70,8 @@ func (provider *Provider) BlockWithTxHashes(ctx context.Context, blockID BlockID // StateUpdate gets the information about the result of executing the requested block. func (provider *Provider) StateUpdate(ctx context.Context, blockID BlockID) (*StateUpdateOutput, error) { var state StateUpdateOutput - if err := do(ctx, provider.c, "starknet_getStateUpdate", &state, blockID); err != nil { - if errors.Is(err, errNotFound) { - return nil, ErrBlockNotFound - } - return nil, err + if err := do(ctx, provider.c, "starknet_getStateUpdate", &state, blockID); err != nil { + return nil,tryUnwrapToRPCErr(err,ErrBlockNotFound ) } return &state, nil } @@ -100,18 +92,16 @@ func (provider *Provider) BlockTransactionCount(ctx context.Context, blockID Blo func (provider *Provider) BlockWithTxs(ctx context.Context, blockID BlockID) (interface{}, error) { var result Block if err := do(ctx, provider.c, "starknet_getBlockWithTxs", &result, blockID); err != nil { - if errors.Is(err, errNotFound) { - return nil, ErrBlockNotFound - } - return nil, err + return nil, tryUnwrapToRPCErr(err,ErrBlockNotFound ) } // if header.Hash == nil it's a pending block if result.BlockHeader.BlockHash == nil { return &PendingBlock{ - ParentHash: result.ParentHash, - Timestamp: result.Timestamp, - SequencerAddress: result.SequencerAddress, - Transactions: result.Transactions, + PendingBlockHeader{ + ParentHash: result.ParentHash, + Timestamp: result.Timestamp, + SequencerAddress: result.SequencerAddress}, + result.Transactions, }, nil } return &result, nil diff --git a/rpc/block_test.go b/rpc/block_test.go index 58beccd2..c9c2d390 100644 --- a/rpc/block_test.go +++ b/rpc/block_test.go @@ -127,12 +127,14 @@ func TestBlockWithTxHashes(t *testing.T) { testSet := map[string][]testSetType{ "mock": { { - BlockID: BlockID{Tag: "latest"}, + BlockID: BlockID{Tag: "latest"}, + ExpectedError: nil, ExpectedPendingBlockWithTxHashes: &PendingBlockTxHashes{ - ParentHash: &felt.Zero, - Timestamp: 123, - SequencerAddress: &felt.Zero, - Transactions: txHashes, + PendingBlockHeader{ + ParentHash: &felt.Zero, + Timestamp: 123, + SequencerAddress: &felt.Zero}, + txHashes, }, }, { @@ -166,14 +168,12 @@ func TestBlockWithTxHashes(t *testing.T) { }, "mainnet": {}, }[testEnv] - + for _, test := range testSet { spy := NewSpy(testConfig.provider.c) testConfig.provider.c = spy result, err := testConfig.provider.BlockWithTxHashes(context.Background(), test.BlockID) - if err != test.ExpectedError { - t.Fatal("BlockWithTxHashes match the expected error:", err) - } + require.Equal(t, test.ExpectedError, err, "Error in BlockWithTxHashes") switch resultType := result.(type) { case *BlockTxHashes: block, ok := result.(*BlockTxHashes) @@ -207,7 +207,7 @@ func TestBlockWithTxHashes(t *testing.T) { if !ok { t.Fatalf("should return *PendingBlockTxHashes, instead: %T\n", result) } - + require.Equal(t, pBlock.ParentHash, test.ExpectedPendingBlockWithTxHashes.ParentHash, "Error in PendingBlockTxHashes ParentHash") require.Equal(t, pBlock.SequencerAddress, test.ExpectedPendingBlockWithTxHashes.SequencerAddress, "Error in PendingBlockTxHashes SequencerAddress") require.Equal(t, pBlock.Timestamp, test.ExpectedPendingBlockWithTxHashes.Timestamp, "Error in PendingBlockTxHashes Timestamp") diff --git a/rpc/call.go b/rpc/call.go index d499df3a..44b52eae 100644 --- a/rpc/call.go +++ b/rpc/call.go @@ -2,7 +2,7 @@ package rpc import ( "context" - "errors" + "github.com/NethermindEth/juno/core/felt" ) @@ -15,15 +15,8 @@ func (provider *Provider) Call(ctx context.Context, request FunctionCall, blockI } var result []*felt.Felt if err := do(ctx, provider.c, "starknet_call", &result, request, blockID); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrContractError): - return nil, ErrContractError - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrContractError, ErrBlockNotFound) } return result, nil } diff --git a/rpc/contract.go b/rpc/contract.go index 940c550a..c56868f1 100644 --- a/rpc/contract.go +++ b/rpc/contract.go @@ -3,7 +3,7 @@ package rpc import ( "context" "encoding/json" - "errors" + "fmt" "github.com/NethermindEth/juno/core/felt" @@ -14,13 +14,8 @@ import ( func (provider *Provider) Class(ctx context.Context, blockID BlockID, classHash *felt.Felt) (ClassOutput, error) { var rawClass map[string]any if err := do(ctx, provider.c, "starknet_getClass", &rawClass, blockID, classHash); err != nil { - switch { - case errors.Is(err, ErrClassHashNotFound): - return nil, ErrClassHashNotFound - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrClassHashNotFound, ErrBlockNotFound) } return typecastClassOutput(&rawClass) @@ -31,13 +26,8 @@ func (provider *Provider) Class(ctx context.Context, blockID BlockID, classHash func (provider *Provider) ClassAt(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (ClassOutput, error) { var rawClass map[string]any if err := do(ctx, provider.c, "starknet_getClassAt", &rawClass, blockID, contractAddress); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) } return typecastClassOutput(&rawClass) } @@ -69,13 +59,8 @@ func typecastClassOutput(rawClass *map[string]any) (ClassOutput, error) { func (provider *Provider) ClassHashAt(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (*felt.Felt, error) { var result *felt.Felt if err := do(ctx, provider.c, "starknet_getClassHashAt", &result, blockID, contractAddress); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) } return result, nil } @@ -85,13 +70,8 @@ func (provider *Provider) StorageAt(ctx context.Context, contractAddress *felt.F var value string hashKey := fmt.Sprintf("0x%x", utils.GetSelectorFromName(key)) if err := do(ctx, provider.c, "starknet_getStorageAt", &value, contractAddress, hashKey, blockID); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return "", ErrContractNotFound - case errors.Is(err, ErrBlockNotFound): - return "", ErrBlockNotFound - } - return "", err + + return "", tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) } return value, nil } @@ -100,13 +80,8 @@ func (provider *Provider) StorageAt(ctx context.Context, contractAddress *felt.F func (provider *Provider) Nonce(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (*string, error) { nonce := "" if err := do(ctx, provider.c, "starknet_getNonce", &nonce, blockID, contractAddress); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound, ErrBlockNotFound) } return &nonce, nil } @@ -115,15 +90,8 @@ func (provider *Provider) Nonce(ctx context.Context, blockID BlockID, contractAd func (provider *Provider) EstimateFee(ctx context.Context, requests []EstimateFeeInput, blockID BlockID) ([]FeeEstimate, error) { var raw []FeeEstimate if err := do(ctx, provider.c, "starknet_estimateFee", &raw, requests, blockID); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrContractError): - return nil, ErrContractError - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound,ErrContractError, ErrBlockNotFound) } return raw, nil } @@ -132,15 +100,8 @@ func (provider *Provider) EstimateFee(ctx context.Context, requests []EstimateFe func (provider *Provider) EstimateMessageFee(ctx context.Context, msg MsgFromL1, blockID BlockID) (*FeeEstimate, error) { var raw FeeEstimate if err := do(ctx, provider.c, "starknet_estimateMessageFee", &raw, msg, blockID); err != nil { - switch { - case errors.Is(err, ErrContractNotFound): - return nil, ErrContractNotFound - case errors.Is(err, ErrContractError): - return nil, ErrContractError - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrContractNotFound,ErrContractError, ErrBlockNotFound) } return &raw, nil } diff --git a/rpc/events.go b/rpc/events.go index a50860b8..d8d63651 100644 --- a/rpc/events.go +++ b/rpc/events.go @@ -2,24 +2,15 @@ package rpc import ( "context" - "errors" + ) // Events returns all events matching the given filter func (provider *Provider) Events(ctx context.Context, input EventsInput) (*EventChunk, error) { var result EventChunk if err := do(ctx, provider.c, "starknet_getEvents", &result, input); err != nil { - switch { - case errors.Is(err, ErrPageSizeTooBig): - return nil, ErrPageSizeTooBig - case errors.Is(err, ErrInvalidContinuationToken): - return nil, ErrInvalidContinuationToken - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - case errors.Is(err, ErrTooManyKeysInFilter): - return nil, ErrTooManyKeysInFilter - } - return nil, err + + return nil, tryUnwrapToRPCErr(err, ErrPageSizeTooBig , ErrInvalidContinuationToken , ErrBlockNotFound ,ErrTooManyKeysInFilter) } return &result, nil } diff --git a/rpc/mock_test.go b/rpc/mock_test.go index f96492b5..97e4982f 100644 --- a/rpc/mock_test.go +++ b/rpc/mock_test.go @@ -629,21 +629,26 @@ func mock_starknet_getBlockWithTxHashes(result interface{}, method string, args "0x40c82f79dd2bc1953fc9b347a3e7ab40fe218ed5740bf4e120f74e8a3c9ac99", "0x28981b14353a28bc46758dff412ac544d16f2ffc8dde31867855592ea054ab1", }) - if(err != nil){ + if err != nil { return err } if blockId.Tag == "latest" { - pBlock, err := json.Marshal(PendingBlockTxHashes{ - ParentHash: &felt.Zero, - Timestamp: 123, - SequencerAddress: &felt.Zero, - Transactions: txHashes, - }) + pBlock, err := json.Marshal( + PendingBlockTxHashes{ + PendingBlockHeader{ + ParentHash: &felt.Zero, + Timestamp: 123, + SequencerAddress: &felt.Zero}, + txHashes, + }) + if err != nil { + return err + } + err = json.Unmarshal(pBlock, &r) if err != nil { return err } - json.Unmarshal(pBlock, &r) } else { blockHash, err := utils.HexToFelt("0xbeef") if err != nil { @@ -675,11 +680,11 @@ func mock_starknet_traceBlockTransactions(result interface{}, method string, arg if len(args) != 1 { return errWrongArgs } - blockHash, ok := args[0].(*felt.Felt) + blockID, ok := args[0].(BlockID) if !ok { - return errors.Wrap(errWrongArgs, fmt.Sprintf("args[0] should be felt, got %T\n", args[0])) + return errors.Wrap(errWrongArgs, fmt.Sprintf("args[0] should be BlockID, got %T\n", args[0])) } - if blockHash.String() == "0x3ddc3a8aaac071ecdc5d8d0cfbb1dc4fc6a88272bc6c67523c9baaee52a5ea2" { + if blockID.Hash.String() == "0x3ddc3a8aaac071ecdc5d8d0cfbb1dc4fc6a88272bc6c67523c9baaee52a5ea2" { var rawBlockTrace struct { Result []Trace `json:"result"` diff --git a/rpc/provider.go b/rpc/provider.go index 99bc3fc2..c8d85b5a 100644 --- a/rpc/provider.go +++ b/rpc/provider.go @@ -42,17 +42,18 @@ type RpcProvider interface { EstimateFee(ctx context.Context, requests []EstimateFeeInput, blockID BlockID) ([]FeeEstimate, error) EstimateMessageFee(ctx context.Context, msg MsgFromL1, blockID BlockID) (*FeeEstimate, error) Events(ctx context.Context, input EventsInput) (*EventChunk, error) + GetTransactionStatus(ctx context.Context, transactionHash *felt.Felt) (*TxnStatusResp, error) Nonce(ctx context.Context, blockID BlockID, contractAddress *felt.Felt) (*string, error) SimulateTransactions(ctx context.Context, blockID BlockID, txns []Transaction, simulationFlags []SimulationFlag) ([]SimulatedTransaction, error) StateUpdate(ctx context.Context, blockID BlockID) (*StateUpdateOutput, error) StorageAt(ctx context.Context, contractAddress *felt.Felt, key string, blockID BlockID) (string, error) SpecVersion(ctx context.Context) (string, error) Syncing(ctx context.Context) (*SyncStatus, error) - TraceBlockTransactions(ctx context.Context, blockHash *felt.Felt) ([]Trace, error) + TraceBlockTransactions(ctx context.Context, blockID BlockID) ([]Trace, error) TransactionByBlockIdAndIndex(ctx context.Context, blockID BlockID, index uint64) (Transaction, error) TransactionByHash(ctx context.Context, hash *felt.Felt) (Transaction, error) TransactionReceipt(ctx context.Context, transactionHash *felt.Felt) (TransactionReceipt, error) - TransactionTrace(ctx context.Context, transactionHash *felt.Felt) (TxnTrace, error) + TraceTransaction(ctx context.Context, transactionHash *felt.Felt) (TxnTrace, error) } var _ RpcProvider = &Provider{} diff --git a/rpc/tests/trace/0xff66e14fc6a96f3289203690f5f876cb4b608868e8549b5f6a90a21d4d6329.json b/rpc/tests/trace/0xff66e14fc6a96f3289203690f5f876cb4b608868e8549b5f6a90a21d4d6329.json index 9f8edf11..5d6ae2c8 100644 --- a/rpc/tests/trace/0xff66e14fc6a96f3289203690f5f876cb4b608868e8549b5f6a90a21d4d6329.json +++ b/rpc/tests/trace/0xff66e14fc6a96f3289203690f5f876cb4b608868e8549b5f6a90a21d4d6329.json @@ -170,6 +170,7 @@ "calls": [], "events": [ { + "order": 0, "keys": [ "0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff" ], @@ -287,6 +288,7 @@ "calls": [], "events": [ { + "order": 1, "keys": [ "0x134692b230b9e1ffa39098904722134159652b09c5bc41d88d6698779d228ff" ], @@ -298,6 +300,7 @@ ] }, { + "order": 2, "keys": [ "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ], @@ -345,6 +348,7 @@ "calls": [], "events": [ { + "order": 3, "keys": [ "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ], @@ -396,6 +400,7 @@ "calls": [], "events": [ { + "order": 4, "keys": [ "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ], @@ -424,6 +429,7 @@ ], "events": [ { + "order": 5, "keys": [ "0x5ad857f66a5b55f1301ff1ed7e098ac6d4433148f0b72ebc4a2945ab85ad53" ], @@ -482,6 +488,7 @@ "calls": [], "events": [ { + "order": 0, "keys": [ "0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9" ], @@ -498,6 +505,77 @@ ], "events": [], "messages": [] + }, + "type": "INVOKE", + "state_diff": { + "storage_diffs": [ + { + "address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", + "storage_entries": [ + { + "key": "0x49a8ef79cab313360767015d427d0307368eff5c2c81b019aff018ec638eef2", + "value": "0x763b821506b19086e9" + }, + { + "key": "0x625da4622cb73a56b1f10ac489e48b4e8af830a368fb3e21db8b7868c315ff0", + "value": "0x19094ba60d592b" + }, + { + "key": "0x5496768776e3db30053404f18067d81a6e06f5a2b0de326e21298fd9d569a9a", + "value": "0x11e93b002a1d5c717d" + } + ] + }, + { + "address": "0x10884171baf1914edc28d7afb619b40a4051cfae78a094a55d230f19e944a28", + "storage_entries": [ + { + "key": "0x2487f67598912d31ab84d8fa97c9e78332d00795ecdad092ea09f9c9c14a9a3", + "value": "0x1e226129b7e" + }, + { + "key": "0x2487f67598912d31ab84d8fa97c9e78332d00795ecdad092ea09f9c9c14a9a0", + "value": "0x4477606da4ac2b7bef" + } + ] + }, + { + "address": "0x22b05f9396d2c48183f6deaf138a57522bcc8b35b67dee919f76403d1783136", + "storage_entries": [ + { + "key": "0x110e2f729c9c2b988559994a3daccd838cf52faf88e18101373e67dd061455a", + "value": "0x7743be9a9d8fae" + }, + { + "key": "0x625da4622cb73a56b1f10ac489e48b4e8af830a368fb3e21db8b7868c315ff0", + "value": "0x631cb839" + } + ] + }, + { + "address": "0x53c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", + "storage_entries": [ + { + "key": "0x625da4622cb73a56b1f10ac489e48b4e8af830a368fb3e21db8b7868c315ff0", + "value": "0x17fc5" + }, + { + "key": "0x49a8ef79cab313360767015d427d0307368eff5c2c81b019aff018ec638eef2", + "value": "0x257875e1c11" + } + ] + } + ], + "nonces": [ + { + "contract_address": "0x61d862eb8baf0dc8e14159d0dd16abcff933c798ecf252ce81685d74c237516", + "nonce": "0x58" + } + ], + "deployed_contracts": [], + "deprecated_declared_classes": [], + "declared_classes": [], + "replaced_classes": [] } }, "id": 1 diff --git a/rpc/trace.go b/rpc/trace.go index 167c4ee3..66496cef 100644 --- a/rpc/trace.go +++ b/rpc/trace.go @@ -3,12 +3,13 @@ package rpc import ( "context" "encoding/json" + "errors" "github.com/NethermindEth/juno/core/felt" ) // For a given executed transaction, return the trace of its execution, including internal calls -func (provider *Provider) TransactionTrace(ctx context.Context, transactionHash *felt.Felt) (TxnTrace, error) { +func (provider *Provider) TraceTransaction(ctx context.Context, transactionHash *felt.Felt) (TxnTrace, error) { var rawTxnTrace map[string]any if err := do(ctx, provider.c, "starknet_traceTransaction", &rawTxnTrace, transactionHash); err != nil { if noTraceAvailableError, ok := isErrNoTraceAvailableError(err); ok { @@ -22,28 +23,29 @@ func (provider *Provider) TransactionTrace(ctx context.Context, transactionHash return nil, err } - // if execute_invocation exists, then it's an InvokeTxnTrace type - if _, exists := rawTxnTrace["execute_invocation"]; exists { + switch rawTxnTrace["type"] { + case string(TransactionType_Invoke): var trace InvokeTxnTrace err = json.Unmarshal(rawTraceByte, &trace) if err != nil { return nil, err } return trace, nil - } - - // if constructor_invocation exists, then it's a DeployAccountTxnTrace type - if _, exists := rawTxnTrace["constructor_invocation"]; exists { + case string(TransactionType_Declare): + var trace DeclareTxnTrace + err = json.Unmarshal(rawTraceByte, &trace) + if err != nil { + return nil, err + } + return trace, nil + case string(TransactionType_DeployAccount): var trace DeployAccountTxnTrace err = json.Unmarshal(rawTraceByte, &trace) if err != nil { return nil, err } return trace, nil - } - - // if function_invocation exists, then it's an L1HandlerTxnTrace type - if _, exists := rawTxnTrace["function_invocation"]; exists { + case string(TransactionType_L1Handler): var trace L1HandlerTxnTrace err = json.Unmarshal(rawTraceByte, &trace) if err != nil { @@ -51,21 +53,15 @@ func (provider *Provider) TransactionTrace(ctx context.Context, transactionHash } return trace, nil } + return nil, errors.New("Unknown transaction type") - // the other possible choice is for it to be a DeclareTxnTrace type - var trace DeclareTxnTrace - err = json.Unmarshal(rawTraceByte, &trace) - if err != nil { - return nil, err - } - return trace, nil } // Retrieve traces for all transactions in the given block -func (provider *Provider) TraceBlockTransactions(ctx context.Context, blockHash *felt.Felt) ([]Trace, error) { +func (provider *Provider) TraceBlockTransactions(ctx context.Context, blockID BlockID) ([]Trace, error) { var output []Trace - if err := do(ctx, provider.c, "starknet_traceBlockTransactions", &output, blockHash); err != nil { - return nil, tryUnwrapToRPCErr(err, ErrInvalidBlockHash) + if err := do(ctx, provider.c, "starknet_traceBlockTransactions", &output, blockID); err != nil { + return nil, tryUnwrapToRPCErr(err, ErrBlockNotFound) } return output, nil diff --git a/rpc/trace_test.go b/rpc/trace_test.go index f75f23cc..62b746a6 100644 --- a/rpc/trace_test.go +++ b/rpc/trace_test.go @@ -63,7 +63,7 @@ func TestTransactionTrace(t *testing.T) { }[testEnv] for _, test := range testSet { - resp, err := testConfig.provider.TransactionTrace(context.Background(), test.TransactionHash) + resp, err := testConfig.provider.TraceTransaction(context.Background(), test.TransactionHash) if err != nil { require.Equal(t, test.ExpectedError, err) } else { @@ -136,7 +136,7 @@ func TestTraceBlockTransactions(t *testing.T) { } type testSetType struct { - BlockHash *felt.Felt + BlockID BlockID ExpectedResp []Trace ExpectedErr *RPCError } @@ -145,19 +145,19 @@ func TestTraceBlockTransactions(t *testing.T) { "mainnet": {}, "mock": { testSetType{ - BlockHash: utils.TestHexToFelt(t, "0x3ddc3a8aaac071ecdc5d8d0cfbb1dc4fc6a88272bc6c67523c9baaee52a5ea2"), + BlockID: BlockID{Hash: utils.TestHexToFelt(t, "0x3ddc3a8aaac071ecdc5d8d0cfbb1dc4fc6a88272bc6c67523c9baaee52a5ea2")}, ExpectedResp: expectedResp, ExpectedErr: nil, }, testSetType{ - BlockHash: utils.TestHexToFelt(t, "0x0"), + BlockID: BlockID{Hash: utils.TestHexToFelt(t, "0x0")}, ExpectedResp: nil, ExpectedErr: ErrInvalidBlockHash, }}, }[testEnv] for _, test := range testSet { - resp, err := testConfig.provider.TraceBlockTransactions(context.Background(), test.BlockHash) + resp, err := testConfig.provider.TraceBlockTransactions(context.Background(), test.BlockID) if err != nil { require.Equal(t, test.ExpectedErr, err) diff --git a/rpc/transaction.go b/rpc/transaction.go index bca94c66..0e09f9a4 100644 --- a/rpc/transaction.go +++ b/rpc/transaction.go @@ -62,11 +62,8 @@ func (provider *Provider) TransactionByHash(ctx context.Context, hash *felt.Felt // todo: update to return a custom Transaction type, then use adapt function var tx TXN if err := do(ctx, provider.c, "starknet_getTransactionByHash", &tx, hash); err != nil { - if errors.Is(err, ErrHashNotFound) { - return nil, ErrHashNotFound - } - return nil, err - } + return nil, tryUnwrapToRPCErr(err,ErrHashNotFound) +} return adaptTransaction(tx) } @@ -74,13 +71,9 @@ func (provider *Provider) TransactionByHash(ctx context.Context, hash *felt.Felt func (provider *Provider) TransactionByBlockIdAndIndex(ctx context.Context, blockID BlockID, index uint64) (Transaction, error) { var tx TXN if err := do(ctx, provider.c, "starknet_getTransactionByBlockIdAndIndex", &tx, blockID, index); err != nil { - switch { - case errors.Is(err, ErrInvalidTxnIndex): - return nil, ErrInvalidTxnIndex - case errors.Is(err, ErrBlockNotFound): - return nil, ErrBlockNotFound - } - return nil, err + + return nil,tryUnwrapToRPCErr(err, ErrInvalidTxnIndex ,ErrBlockNotFound) + } return adaptTransaction(tx) } @@ -90,10 +83,23 @@ func (provider *Provider) TransactionReceipt(ctx context.Context, transactionHas var receipt UnknownTransactionReceipt err := do(ctx, provider.c, "starknet_getTransactionReceipt", &receipt, transactionHash) if err != nil { - if errors.Is(err, ErrHashNotFound) { - return nil, ErrHashNotFound - } - return nil, err + return nil, tryUnwrapToRPCErr(err,ErrHashNotFound) } return receipt.TransactionReceipt, nil } + +// GetTransactionStatus gets the transaction status (possibly reflecting that the tx is still in the mempool, or dropped from it) +// Parameters: +// - ctx: the context.Context object for cancellation and timeouts. +// - transactionHash: the transaction hash as a felt +// Returns: +// - *GetTxnStatusResp: The transaction status +// - error, if one arose. +func (provider *Provider) GetTransactionStatus(ctx context.Context, transactionHash *felt.Felt) (*TxnStatusResp, error) { + var receipt TxnStatusResp + err := do(ctx, provider.c, "starknet_getTransactionStatus", &receipt, transactionHash) + if err != nil { + return nil, tryUnwrapToRPCErr(err, ErrHashNotFound) + } + return &receipt, nil +} diff --git a/rpc/transaction_test.go b/rpc/transaction_test.go index 5920dd2f..2b2c5e73 100644 --- a/rpc/transaction_test.go +++ b/rpc/transaction_test.go @@ -309,3 +309,30 @@ func TestDeployOrDeclareReceipt(t *testing.T) { } } + +// TestGetTransactionStatus tests starknet_getTransactionStatus +func TestGetTransactionStatus(t *testing.T) { + testConfig := beforeEach(t) + + type testSetType struct { + TxnHash *felt.Felt + ExpectedResp TxnStatusResp + } + + testSet := map[string][]testSetType{ + "mock": {}, + "testnet": { + { + TxnHash: utils.TestHexToFelt(t, "0x46a9f52a96b2d226407929e04cb02507e531f7c78b9196fc8c910351d8c33f3"), + ExpectedResp: TxnStatusResp{FinalityStatus: TxnStatus_Accepted_On_L1, ExecutionStatus: TxnExecutionStatusSUCCEEDED}, + }, + }, + "mainnet": {}, + }[testEnv] + + for _, test := range testSet { + resp, err := testConfig.provider.GetTransactionStatus(context.Background(), test.TxnHash) + require.NoError(t, err) + require.Equal(t, *resp, test.ExpectedResp) + } +} diff --git a/rpc/types_block.go b/rpc/types_block.go index 143ee34a..ec2b007c 100644 --- a/rpc/types_block.go +++ b/rpc/types_block.go @@ -89,14 +89,8 @@ type Block struct { } type PendingBlock struct { - // ParentHash The hash of this block's parent - ParentHash *felt.Felt `json:"parent_hash"` - // Timestamp the time in which the block was created, encoded in Unix time - Timestamp uint64 `json:"timestamp"` - // SequencerAddress the StarkNet identity of the sequencer submitting this block - SequencerAddress *felt.Felt `json:"sequencer_address"` - // Transactions The transactions in this block - Transactions BlockTransactions `json:"transactions"` + PendingBlockHeader + BlockTransactions } type BlockTxHashes struct { @@ -107,13 +101,7 @@ type BlockTxHashes struct { } type PendingBlockTxHashes struct { - // ParentHash The hash of this block's parent - ParentHash *felt.Felt `json:"parent_hash"` - // Timestamp the time in which the block was created, encoded in Unix time - Timestamp uint64 `json:"timestamp"` - // SequencerAddress the StarkNet identity of the sequencer submitting this block - SequencerAddress *felt.Felt `json:"sequencer_address"` - // Transactions The hashes of the transactions included in this block + PendingBlockHeader Transactions []*felt.Felt `json:"transactions"` } @@ -130,4 +118,28 @@ type BlockHeader struct { Timestamp uint64 `json:"timestamp"` // SequencerAddress the StarkNet identity of the sequencer submitting this block SequencerAddress *felt.Felt `json:"sequencer_address"` + // The price of l1 gas in the block + L1GasPrice ResourcePrice `json:"l1_gas_price"` + // Semver of the current Starknet protocol + StarknetVersion string `json:"starknet_version"` +} + +type PendingBlockHeader struct { + // ParentHash The hash of this block's parent + ParentHash *felt.Felt `json:"parent_hash"` + // Timestamp the time in which the block was created, encoded in Unix time + Timestamp uint64 `json:"timestamp"` + // SequencerAddress the StarkNet identity of the sequencer submitting this block + SequencerAddress *felt.Felt `json:"sequencer_address"` + // The price of l1 gas in the block + L1GasPrice ResourcePrice `json:"l1_gas_price"` + // Semver of the current Starknet protocol + StarknetVersion string `json:"starknet_version"` +} + +type ResourcePrice struct { + // The price of one unit of the given resource, denominated in strk + PriceInStrk NumAsHex `json:"price_in_strk,omitempty"` + // The price of one unit of the given resource, denominated in wei + PriceInWei NumAsHex `json:"price_in_wei"` } diff --git a/rpc/types_broadcast_transaction.go b/rpc/types_broadcast_transaction.go index 66f324e7..c8af8086 100644 --- a/rpc/types_broadcast_transaction.go +++ b/rpc/types_broadcast_transaction.go @@ -37,23 +37,23 @@ type BroadcastInvokev1Txn struct { type BroadcastDeclareV1Txn struct { Type TransactionType `json:"type"` // SenderAddress the address of the account contract sending the declaration transaction - SenderAddress *felt.Felt `json:"sender_address"` - MaxFee *felt.Felt `json:"max_fee"` - Version TransactionVersion `json:"version"` - Signature []*felt.Felt `json:"signature"` - Nonce *felt.Felt `json:"nonce"` - DeprecatedContractClass `json:"contract_class"` + SenderAddress *felt.Felt `json:"sender_address"` + MaxFee *felt.Felt `json:"max_fee"` + Version NumAsHex `json:"version"` + Signature []*felt.Felt `json:"signature"` + Nonce *felt.Felt `json:"nonce"` + ContractClass DeprecatedContractClass `json:"contract_class"` } type BroadcastDeclareV2Txn struct { Type TransactionType `json:"type"` // SenderAddress the address of the account contract sending the declaration transaction - SenderAddress *felt.Felt `json:"sender_address"` - CompiledClassHash *felt.Felt `json:"compiled_class_hash"` - MaxFee *felt.Felt `json:"max_fee"` - Version TransactionVersion `json:"version"` - Signature []*felt.Felt `json:"signature"` - Nonce *felt.Felt `json:"nonce"` - ContractClass `json:"contract_class"` + SenderAddress *felt.Felt `json:"sender_address"` + CompiledClassHash *felt.Felt `json:"compiled_class_hash"` + MaxFee *felt.Felt `json:"max_fee"` + Version NumAsHex `json:"version"` + Signature []*felt.Felt `json:"signature"` + Nonce *felt.Felt `json:"nonce"` + ContractClass ContractClass `json:"contract_class"` } type BroadcastDeployAccountTxn struct { diff --git a/rpc/types_event.go b/rpc/types_event.go index a8998e2e..04285ae6 100644 --- a/rpc/types_event.go +++ b/rpc/types_event.go @@ -2,6 +2,12 @@ package rpc import "github.com/NethermindEth/juno/core/felt" +type OrderedEvent struct { + // The order of the event within the transaction + Order int `json:"order"` + Event Event +} + type Event struct { FromAddress *felt.Felt `json:"from_address"` Keys []*felt.Felt `json:"keys"` diff --git a/rpc/types_trace.go b/rpc/types_trace.go index 9520a56d..5c84c22a 100644 --- a/rpc/types_trace.go +++ b/rpc/types_trace.go @@ -37,28 +37,35 @@ var _ TxnTrace = L1HandlerTxnTrace{} type InvokeTxnTrace struct { ValidateInvocation FnInvocation `json:"validate_invocation"` //the trace of the __execute__ call or constructor call, depending on the transaction type (none for declare transactions) - ExecuteInvocation FnInvocation `json:"execute_invocation"` - FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + ExecuteInvocation ExecInvocation `json:"execute_invocation"` + FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + StateDiff StateDiff `json:"state_diff"` + Type TransactionType `json:"type"` } // the execution trace of a declare transaction type DeclareTxnTrace struct { - ValidateInvocation FnInvocation `json:"validate_invocation"` - FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + ValidateInvocation FnInvocation `json:"validate_invocation"` + FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + StateDiff StateDiff `json:"state_diff"` + Type TransactionType `json:"type"` } // the execution trace of a deploy account transaction type DeployAccountTxnTrace struct { ValidateInvocation FnInvocation `json:"validate_invocation"` //the trace of the __execute__ call or constructor call, depending on the transaction type (none for declare transactions) - ConstructorInvocation FnInvocation `json:"constructor_invocation"` - FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + ConstructorInvocation FnInvocation `json:"constructor_invocation"` + FeeTransferInvocation FnInvocation `json:"fee_transfer_invocation"` + StateDiff StateDiff `json:"state_diff"` + Type TransactionType `json:"type"` } // the execution trace of an L1 handler transaction type L1HandlerTxnTrace struct { //the trace of the __execute__ call or constructor call, depending on the transaction type (none for declare transactions) - FunctionInvocation FnInvocation `json:"function_invocation"` + FunctionInvocation FnInvocation `json:"function_invocation"` + Type TransactionType `json:"type"` } type EntryPointType string @@ -80,26 +87,26 @@ type FnInvocation struct { FunctionCall //The address of the invoking contract. 0 for the root invocation - CallerAddress *felt.Felt `json:"caller_address,omitempty"` + CallerAddress *felt.Felt `json:"caller_address"` // The hash of the class being called - ClassHash *felt.Felt `json:"class_hash,omitempty"` + ClassHash *felt.Felt `json:"class_hash"` - EntryPointType EntryPointType `json:"entry_point_type,omitempty"` + EntryPointType EntryPointType `json:"entry_point_type"` - CallType CallType `json:"call_type,omitempty"` + CallType CallType `json:"call_type"` //The value returned from the function invocation - Result []*felt.Felt `json:"result,omitempty"` + Result []*felt.Felt `json:"result"` // The calls made by this invocation - NestedCalls []FnInvocation `json:"calls,omitempty"` + NestedCalls []FnInvocation `json:"calls"` // The events emitted in this invocation - InvocationEvents []Event `json:"events,omitempty"` + InvocationEvents []OrderedEvent `json:"events"` // The messages sent by this invocation to L1 - L1Messages []MsgToL1 `json:"messages,omitempty"` + L1Messages []OrderedMsg `json:"messages"` } // A single pair of transaction hash and corresponding trace @@ -107,3 +114,8 @@ type Trace struct { TraceRoot TxnTrace `json:"trace_root,omitempty"` TxnHash *felt.Felt `json:"transaction_hash,omitempty"` } + +type ExecInvocation struct { + FunctionInvocation FnInvocation `json:"function_invocation,omitempty"` + RevertReason string `json:"revert_reason,omitempty"` +} diff --git a/rpc/types_transaction.go b/rpc/types_transaction.go index e6c7c930..eb763c12 100644 --- a/rpc/types_transaction.go +++ b/rpc/types_transaction.go @@ -56,49 +56,37 @@ type L1HandlerTxn struct { } type DeclareTxnV0 struct { - MaxFee *felt.Felt `json:"max_fee"` - Version TransactionVersion `json:"version"` - Signature []*felt.Felt `json:"signature"` - Nonce *felt.Felt `json:"nonce"` - Type TransactionType `json:"type"` - + Type TransactionType `json:"type"` // SenderAddress the address of the account contract sending the declaration transaction - SenderAddress *felt.Felt `json:"sender_address"` - - DeprecatedContractClass `json:"contract_class,omitempty"` - ClassHash *felt.Felt `json:"class_hash,omitempty"` + SenderAddress *felt.Felt `json:"sender_address"` + MaxFee *felt.Felt `json:"max_fee"` + Version TransactionVersion `json:"version"` + Signature []*felt.Felt `json:"signature"` + ClassHash *felt.Felt `json:"class_hash"` } type DeclareTxnV1 struct { - MaxFee *felt.Felt `json:"max_fee"` - Version TransactionVersion `json:"version"` - Signature []*felt.Felt `json:"signature"` - Nonce *felt.Felt `json:"nonce"` - Type TransactionType `json:"type"` - - // ClassHash the hash of the declared class - ClassHash *felt.Felt `json:"class_hash,omitempty"` - - DeprecatedContractClass `json:"contract_class,omitempty"` - + Type TransactionType `json:"type"` // SenderAddress the address of the account contract sending the declaration transaction - SenderAddress *felt.Felt `json:"sender_address"` + SenderAddress *felt.Felt `json:"sender_address"` + MaxFee *felt.Felt `json:"max_fee"` + Version TransactionVersion `json:"version"` + Signature []*felt.Felt `json:"signature"` + Nonce *felt.Felt `json:"nonce"` + // ClassHash the hash of the declared class + ClassHash *felt.Felt `json:"class_hash"` } type DeclareTxnV2 struct { - MaxFee *felt.Felt `json:"max_fee"` - Version TransactionVersion `json:"version"` - Signature []*felt.Felt `json:"signature"` - Nonce *felt.Felt `json:"nonce"` - Type TransactionType `json:"type"` - + Type TransactionType `json:"type"` // SenderAddress the address of the account contract sending the declaration transaction - SenderAddress *felt.Felt `json:"sender_address"` - - CompiledClassHash *felt.Felt `json:"compiled_class_hash"` - - ContractClass `json:"contract_class,omitempty"` - ClassHash *felt.Felt `json:"class_hash,omitempty"` + SenderAddress *felt.Felt `json:"sender_address"` + CompiledClassHash *felt.Felt `json:"compiled_class_hash"` + MaxFee *felt.Felt `json:"max_fee"` + Version TransactionVersion `json:"version"` + Signature []*felt.Felt `json:"signature"` + Nonce *felt.Felt `json:"nonce"` + ClassHash *felt.Felt `json:"class_hash"` } // DeployTxn The structure of a deploy transaction. Note that this transaction type is deprecated and will no longer be supported in future versions diff --git a/rpc/types_transaction_receipt.go b/rpc/types_transaction_receipt.go index 195614b5..43e1b2d3 100644 --- a/rpc/types_transaction_receipt.go +++ b/rpc/types_transaction_receipt.go @@ -135,17 +135,59 @@ func (tr L1HandlerTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { return tr.ExecutionStatus } -type PendingDeployTransactionReceipt struct { - CommonTransactionReceipt +type PendingL1HandlerTransactionReceipt struct { + Type TransactionType `json:"type"` + // The message hash as it appears on the L1 core contract + MsgHash NumAsHex `json:"message_hash"` + PendingCommonTransactionReceiptProperties +} + +func (tr PendingL1HandlerTransactionReceipt) Hash() *felt.Felt { + return tr.TransactionHash +} + +func (tr PendingL1HandlerTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { + return tr.ExecutionStatus +} + +type PendingDeclareTransactionReceipt struct { + Type TransactionType `json:"type"` + PendingCommonTransactionReceiptProperties +} + +func (tr PendingDeclareTransactionReceipt) Hash() *felt.Felt { + return tr.TransactionHash +} + +func (tr PendingDeclareTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { + return tr.ExecutionStatus +} + +type PendingDeployAccountTransactionReceipt struct { + Type TransactionType `json:"type"` // The address of the deployed contract ContractAddress *felt.Felt `json:"contract_address"` + PendingCommonTransactionReceiptProperties +} + +func (tr PendingDeployAccountTransactionReceipt) Hash() *felt.Felt { + return tr.TransactionHash } -func (tr PendingDeployTransactionReceipt) Hash() *felt.Felt { +func (tr PendingDeployAccountTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { + return tr.ExecutionStatus +} + +type PendingInvokeTransactionReceipt struct { + Type TransactionType `json:"type"` + PendingCommonTransactionReceiptProperties +} + +func (tr PendingInvokeTransactionReceipt) Hash() *felt.Felt { return tr.TransactionHash } -func (tr PendingDeployTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { +func (tr PendingInvokeTransactionReceipt) GetExecutionStatus() TxnExecutionStatus { return tr.ExecutionStatus } @@ -160,7 +202,29 @@ type PendingCommonTransactionReceiptProperties struct { FinalityStatus TxnFinalityStatus `json:"finality_status"` RevertReason string `json:"revert_reason"` // Events The events emitted as part of this transaction - Events []Event `json:"events"` + Events []Event `json:"events"` + ExecutionResources ExecutionResources `json:"execution_resources"` +} + +type ExecutionResources struct { + // The number of Cairo steps used + Steps NumAsHex `json:"steps"` + // The number of unused memory cells (each cell is roughly equivalent to a step) + MemoryHoles NumAsHex `json:"memory_holes,omitempty"` + // The number of RANGE_CHECK builtin instances + RangeCheckApps NumAsHex `json:"range_check_builtin_applications"` + // The number of Pedersen builtin instances + PedersenApps NumAsHex `json:"pedersen_builtin_applications"` + // The number of Poseidon builtin instances + PoseidonApps NumAsHex `json:"poseidon_builtin_applications"` + // The number of EC_OP builtin instances + ECOPApps NumAsHex `json:"ec_op_builtin_applications"` + // The number of ECDSA builtin instances + ECDSAApps NumAsHex `json:"ecdsa_builtin_applications"` + // The number of BITWISE builtin instances + BitwiseApps NumAsHex `json:"bitwise_builtin_applications"` + // The number of KECCAK builtin instances + KeccakApps NumAsHex `json:"keccak_builtin_applications"` } func (tr PendingCommonTransactionReceiptProperties) Hash() *felt.Felt { @@ -176,6 +240,12 @@ type TransactionReceipt interface { GetExecutionStatus() TxnExecutionStatus } +type OrderedMsg struct { + // The order of the message within the transaction + Order int `json:"order"` + MsgToL1 MsgToL1 +} + type MsgToL1 struct { // FromAddress The address of the L2 contract sending the message FromAddress *felt.Felt `json:"from_address"` @@ -227,12 +297,20 @@ func unmarshalTransactionReceipt(t interface{}) (TransactionReceipt, error) { // Pending doesn't have a block number if casted["block_hash"] == nil { switch TransactionType(typ.(string)) { - case TransactionType_Deploy: - var txn PendingDeployTransactionReceipt + case TransactionType_Invoke: + var txn PendingInvokeTransactionReceipt remarshal(casted, &txn) return txn, nil - default: - var txn PendingCommonTransactionReceiptProperties + case TransactionType_DeployAccount: + var txn PendingDeployAccountTransactionReceipt + remarshal(casted, &txn) + return txn, nil + case TransactionType_L1Handler: + var txn PendingL1HandlerTransactionReceipt + remarshal(casted, &txn) + return txn, nil + case TransactionType_Declare: + var txn PendingDeclareTransactionReceipt remarshal(casted, &txn) return txn, nil } @@ -264,3 +342,18 @@ func unmarshalTransactionReceipt(t interface{}) (TransactionReceipt, error) { return nil, fmt.Errorf("unknown transaction type: %v", t) } + +// The finality status of the transaction, including the case the txn is still in the mempool or failed validation during the block construction phase +type TxnStatus string + +const ( + TxnStatus_Received TxnStatus = "RECEIVED" + TxnStatus_Rejected TxnStatus = "REJECTED" + TxnStatus_Accepted_On_L2 TxnStatus = "ACCEPTED_ON_L2" + TxnStatus_Accepted_On_L1 TxnStatus = "ACCEPTED_ON_L1" +) + +type TxnStatusResp struct { + ExecutionStatus TxnExecutionStatus `json:"execution_status,omitempty"` + FinalityStatus TxnStatus `json:"finality_status"` +} diff --git a/typed/typed.go b/typed/typed.go index 1bddc958..23f09647 100644 --- a/typed/typed.go +++ b/typed/typed.go @@ -105,11 +105,11 @@ func NewTypedData(types map[string]TypeDef, pType string, dom Domain) (td TypedD return td, nil } -// (ref: https://github.com/0xs34n/starknet.js/blob/767021a203ac0b9cdb282eb6d63b33bfd7614858/src/utils/typedData/index.ts#L166) +// (ref: https://github.com/starknet-io/starknet.js/blob/d7bfc37ede85448e0a55ee4efe65200ff2c45f91/src/utils/typedData.ts#L249) func (td TypedData) GetMessageHash(account *big.Int, msg TypedMessage, sc curve.StarkCurve) (hash *big.Int, err error) { - elements := []*big.Int{utils.UTF8StrToBig("Starknet Message")} + elements := []*big.Int{utils.UTF8StrToBig("StarkNet Message")} - domEnc, err := td.GetTypedMessageHash("StarknetDomain", td.Domain, sc) + domEnc, err := td.GetTypedMessageHash("StarkNetDomain", td.Domain, sc) if err != nil { return hash, fmt.Errorf("could not hash domain: %w", err) } diff --git a/typed/typed_test.go b/typed/typed_test.go index 9065fbbb..c75887ae 100644 --- a/typed/typed_test.go +++ b/typed/typed_test.go @@ -36,14 +36,14 @@ func (mail Mail) FmtDefinitionEncoding(field string) (fmtEnc []*big.Int) { func MockTypedData() (ttd TypedData) { exampleTypes := make(map[string]TypeDef) domDefs := []Definition{{"name", "felt"}, {"version", "felt"}, {"chainId", "felt"}} - exampleTypes["StarknetDomain"] = TypeDef{Definitions: domDefs} + exampleTypes["StarkNetDomain"] = TypeDef{Definitions: domDefs} mailDefs := []Definition{{"from", "Person"}, {"to", "Person"}, {"contents", "felt"}} exampleTypes["Mail"] = TypeDef{Definitions: mailDefs} persDefs := []Definition{{"name", "felt"}, {"wallet", "felt"}} exampleTypes["Person"] = TypeDef{Definitions: persDefs} dm := Domain{ - Name: "Starknet Mail", + Name: "StarkNet Mail", Version: "1", ChainId: "1", } @@ -101,7 +101,7 @@ func BenchmarkGetMessageHash(b *testing.B) { func TestGeneral_GetDomainHash(t *testing.T) { ttd := MockTypedData() - hash, err := ttd.GetTypedMessageHash("StarknetDomain", ttd.Domain, curve.Curve) + hash, err := ttd.GetTypedMessageHash("StarkNetDomain", ttd.Domain, curve.Curve) if err != nil { t.Errorf("Could not hash message: %v\n", err) } @@ -142,7 +142,7 @@ func TestGeneral_GetTypedMessageHash(t *testing.T) { func TestGeneral_GetTypeHash(t *testing.T) { tdd := MockTypedData() - hash, err := tdd.GetTypeHash("StarknetDomain") + hash, err := tdd.GetTypeHash("StarkNetDomain") if err != nil { t.Errorf("error enccoding type %v\n", err) } @@ -152,7 +152,7 @@ func TestGeneral_GetTypeHash(t *testing.T) { t.Errorf("type hash: %v does not match expected %v\n", utils.BigToHex(hash), exp) } - enc := tdd.Types["StarknetDomain"] + enc := tdd.Types["StarkNetDomain"] if utils.BigToHex(enc.Encoding) != exp { t.Errorf("type hash: %v does not match expected %v\n", utils.BigToHex(hash), exp) }