diff --git a/account/account_test.go b/account/account_test.go index 250b1b5c..48717411 100644 --- a/account/account_test.go +++ b/account/account_test.go @@ -2,6 +2,7 @@ package account_test import ( "context" + "encoding/json" "flag" "fmt" "math/big" @@ -13,6 +14,9 @@ import ( "github.com/joho/godotenv" "github.com/NethermindEth/starknet.go/account" + "github.com/NethermindEth/starknet.go/artifacts" + "github.com/NethermindEth/starknet.go/contracts" + "github.com/NethermindEth/starknet.go/hash" "github.com/NethermindEth/starknet.go/mocks" "github.com/NethermindEth/starknet.go/rpc" "github.com/NethermindEth/starknet.go/test" @@ -529,6 +533,73 @@ func TestTransactionHashDeclare(t *testing.T) { require.Equal(t, expectedHash.String(), hash.String(), "TransactionHashDeclare not what expected") } +func TestAddDeclareTxn(t *testing.T) { + // https://goerli.voyager.online/tx/0x76af2faec46130ffad1ab2f615ad16b30afcf49cfbd09f655a26e545b03a21d + if testEnv != "testnet" { + t.Skip("Skipping test as it requires a testnet environment") + } + expectedTxHash := utils.TestHexToFelt(t, "0x76af2faec46130ffad1ab2f615ad16b30afcf49cfbd09f655a26e545b03a21d") + expectedClassHash := utils.TestHexToFelt(t, "0x76af2faec46130ffad1ab2f615ad16b30afcf49cfbd09f655a26e545b03a21d") + + AccountAddress := utils.TestHexToFelt(t, "0x0088d0038623a89bf853c70ea68b1062ccf32b094d1d7e5f924cda8404dc73e1") + PubKey := utils.TestHexToFelt(t, "0x7ed3c6482e12c3ef7351214d1195ee7406d814af04a305617599ff27be43883") + PrivKey := utils.TestHexToFelt(t, "0x07514c4f0de1f800b0b0c7377ef39294ce218a7abd9a1c9b6aa574779f7cdc6a") + + ks := starknetgo.NewMemKeystore() + fakePrivKeyBI, ok := new(big.Int).SetString(PrivKey.String(), 0) + require.True(t, ok) + ks.Put(PubKey.String(), fakePrivKeyBI) + + client, err := rpc.NewClient(base) + require.NoError(t, err, "Error in rpc.NewClient") + provider := rpc.NewProvider(client) + + acnt, err := account.NewAccount(provider, AccountAddress, PubKey.String(), ks) + require.NoError(t, err) + + // Class Hash + exampleSierraClass := artifacts.ExampleWorldSierra + var class rpc.ContractClass + err = json.Unmarshal(exampleSierraClass, &class) + require.NoError(t, err) + classHash, err := hash.ClassHash(class) + require.NoError(t, err) + + // Compiled Class Hash + exampleCasmClass := artifacts.ExampleWorldCasm + var casmClass contracts.CasmClass + err = json.Unmarshal(exampleCasmClass, &casmClass) + require.NoError(t, err) + compClassHash := hash.CompiledClassHash(casmClass) + + nonce, err := acnt.Nonce(context.Background(), rpc.BlockID{Tag: "latest"}, acnt.AccountAddress) + require.NoError(t, err) + + tx := rpc.DeclareTxnV2{ + Nonce: utils.TestHexToFelt(t, *nonce), + MaxFee: utils.TestHexToFelt(t, "0x50c8f3053db"), + Type: rpc.TransactionType_Declare, + Version: rpc.TransactionV2, + Signature: []*felt.Felt{}, + SenderAddress: AccountAddress, + CompiledClassHash: compClassHash, + ClassHash: classHash, + ContractClass: class, + } + + err = acnt.SignDeclareTransaction(context.Background(), &tx) + require.NoError(t, err) + + resp, err := acnt.AddDeclareTransaction(context.Background(), tx) + + if err != nil { + require.Equal(t, err.Error(), rpc.ErrDuplicateTx.Error()) + } else { + require.Equal(t, expectedTxHash.String(), resp.TransactionHash.String(), "AddDeclareTransaction TxHash not what expected") + require.Equal(t, expectedClassHash.String(), resp.ClassHash.String(), "AddDeclareTransaction ClassHash not what expected") + } +} + func newDevnet(t *testing.T, url string) ([]test.TestAccount, error) { devnet := test.NewDevNet(url) acnts, err := devnet.Accounts() diff --git a/rpc/write.go b/rpc/write.go index 2a96d032..1a088cba 100644 --- a/rpc/write.go +++ b/rpc/write.go @@ -25,6 +25,14 @@ func (provider *Provider) AddInvokeTransaction(ctx context.Context, invokeTxn In } func (provider *Provider) AddDeclareTransaction(ctx context.Context, declareTransaction AddDeclareTxnInput) (*AddDeclareTransactionResponse, error) { + + switch txn := declareTransaction.(type) { + case DeclareTxnV2: + // DeclareTxnV2 should not have a populated class hash field. It is only needed for signing. + txn.ClassHash = nil + declareTransaction = txn + } + var result AddDeclareTransactionResponse if err := do(ctx, provider.c, "starknet_addDeclareTransaction", &result, declareTransaction); err != nil { if unexpectedErr, ok := isErrUnexpectedError(err); ok {