Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
rianhughes committed Nov 27, 2023
1 parent a94ff83 commit 62433bc
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 14 deletions.
21 changes: 9 additions & 12 deletions account/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package account
import (
"context"
"errors"
"fmt"
"time"

"github.com/NethermindEth/juno/core/crypto"
Expand Down Expand Up @@ -33,7 +34,7 @@ type AccountInterface interface {
TransactionHashInvoke(invokeTxn rpc.InvokeTxnType) (*felt.Felt, error)
TransactionHashDeployAccount(tx rpc.DeployAccountType, contractAddress *felt.Felt) (*felt.Felt, error)
TransactionHashDeclare(tx rpc.DeclareTxnType) (*felt.Felt, error)
SignInvokeTransaction(ctx context.Context, tx *rpc.InvokeTxnV1) error
SignInvokeTransaction(ctx context.Context, tx rpc.InvokeTxnType) ([]*felt.Felt, error)
SignDeployAccountTransaction(ctx context.Context, tx *rpc.DeployAccountTxn, precomputeAddress *felt.Felt) error
SignDeclareTransaction(ctx context.Context, tx *rpc.DeclareTxnV2) error
PrecomputeAddress(deployerAddress *felt.Felt, salt *felt.Felt, classHash *felt.Felt, constructorCalldata []*felt.Felt) (*felt.Felt, error)
Expand Down Expand Up @@ -107,18 +108,14 @@ func (account *Account) Sign(ctx context.Context, msg *felt.Felt) ([]*felt.Felt,
// - invokeTx: the InvokeTxnV1 struct representing the transaction to be invoked.
// Returns:
// - error: an error if there was an error in the signing or invoking process
func (account *Account) SignInvokeTransaction(ctx context.Context, invokeTx *rpc.InvokeTxnV1) error {
func (account *Account) SignInvokeTransaction(ctx context.Context, invokeTx rpc.InvokeTxnType) ([]*felt.Felt, error) {

txHash, err := account.TransactionHashInvoke(*invokeTx)
txHash, err := account.TransactionHashInvoke(invokeTx)
if err != nil {
return err
}
signature, err := account.Sign(ctx, txHash)
if err != nil {
return err
return nil, err
}
invokeTx.Signature = signature
return nil
fmt.Println("txHash", txHash)
return account.Sign(ctx, txHash)
}

// SignDeployAccountTransaction signs a deploy account transaction.
Expand Down Expand Up @@ -301,7 +298,7 @@ func (account *Account) TransactionHashInvoke(tx rpc.InvokeTxnType) (*felt.Felt,
)
case rpc.InvokeTxnV3:
// https://github.com/starknet-io/SNIPs/blob/main/SNIPS/snip-8.md#protocol-changes
if txn.Version == "" || txn.ResourceBounds == (rpc.ResourceBoundsMapping{}) || len(txn.Calldata) == 0 || txn.Nonce == nil || txn.SenderAddress == nil || txn.PayMasterData == nil || txn.AccountDeploymentData == nil {
if txn.Version == "" || txn.ResourceBoundsMapping == (rpc.ResourceBoundsMapping{}) || len(txn.Calldata) == 0 || txn.Nonce == nil || txn.SenderAddress == nil || txn.PayMasterData == nil || txn.AccountDeploymentData == nil {
return nil, ErrNotAllParametersSet
}

Expand All @@ -318,7 +315,7 @@ func (account *Account) TransactionHashInvoke(tx rpc.InvokeTxnType) (*felt.Felt,
PREFIX_TRANSACTION,
txnVersionFelt,
txn.SenderAddress,
tipAndResourcesHash(txn.Tip.Impl().Uint64(), txn.ResourceBounds),
tipAndResourcesHash(txn.Tip.Impl().Uint64(), txn.ResourceBoundsMapping),
crypto.PoseidonArray(txn.PayMasterData...),
account.ChainId,
txn.Nonce,
Expand Down
155 changes: 153 additions & 2 deletions account/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,98 @@ func TestSignMOCK(t *testing.T) {
}

}
func TestAddInvokeV3(t *testing.T) {

type testSetType struct {
ExpectedError *rpc.RPCError
CairoContractVersion int
SetKS bool
AccountAddress *felt.Felt
PubKey *felt.Felt
PrivKey *felt.Felt
InvokeTx rpc.InvokeTxnV3
FnCall rpc.FunctionCall
TxDetails rpc.TxDetails
}
testSet := map[string][]testSetType{
"mock": {},
"devnet": {},
"integration": {
{

ExpectedError: rpc.ErrDuplicateTx,
CairoContractVersion: 0,
AccountAddress: utils.TestHexToFelt(t, "0x043784df59268c02b716e20bf77797bd96c68c2f100b2a634e448c35e3ad363e"),
SetKS: true,
PubKey: utils.TestHexToFelt(t, "0x049f060d2dffd3bf6f2c103b710baf519530df44529045f92c3903097e8d861f"),
PrivKey: utils.TestHexToFelt(t, "0x043b7fe9d91942c98cd5fd37579bd99ec74f879c4c79d886633eecae9dad35fa"),
InvokeTx: rpc.InvokeTxnV3{
Nonce: new(felt.Felt).SetUint64(0),
Version: rpc.TransactionV3,
Type: rpc.TransactionType_Invoke,
SenderAddress: utils.TestHexToFelt(t, "0x043784df59268c02b716e20bf77797bd96c68c2f100b2a634e448c35e3ad363e"),
NonceDataMode: rpc.DAModeL1,
FeeMode: rpc.DAModeL1,
ResourceBoundsMapping: rpc.ResourceBoundsMapping{
L1Gas: rpc.ResourceBounds{
MaxAmount: utils.TestHexToFelt(t, "0x186a0"),
MaxPricePerUnit: utils.TestHexToFelt(t, "0x5af3107a4000"),
},
L2Gas: rpc.ResourceBounds{
MaxAmount: new(felt.Felt),
MaxPricePerUnit: new(felt.Felt),
},
},
Tip: new(felt.Felt),
PayMasterData: []*felt.Felt{},
AccountDeploymentData: []*felt.Felt{},
},
FnCall: rpc.FunctionCall{
ContractAddress: utils.TestHexToFelt(t, "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"),
EntryPointSelector: utils.GetSelectorFromNameFelt("transfer"),
Calldata: []*felt.Felt{
utils.TestHexToFelt(t, "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"),
utils.TestHexToFelt(t, "0x1"),
},
},
},
},
}[testEnv]

for _, test := range testSet {
client, err := rpc.NewClient(base)
require.NoError(t, err, "Error in rpc.NewClient")
provider := rpc.NewProvider(client)

// Set up ks
ks := account.NewMemKeystore()
if test.SetKS {
fakePrivKeyBI, ok := new(big.Int).SetString(test.PrivKey.String(), 0)
require.True(t, ok)
ks.Put(test.PubKey.String(), fakePrivKeyBI)
}

acnt, err := account.NewAccount(provider, test.AccountAddress, test.PubKey.String(), ks)
require.NoError(t, err)

test.InvokeTx.Calldata, err = acnt.FmtCalldata([]rpc.FunctionCall{test.FnCall}, test.CairoContractVersion)
require.NoError(t, err)

test.InvokeTx.Signature, err = acnt.SignInvokeTransaction(context.Background(), test.InvokeTx)
require.NoError(t, err)

qwe, err := json.MarshalIndent(test.InvokeTx, "", "")
fmt.Println(string(qwe))

resp, err := acnt.AddInvokeTransaction(context.Background(), test.InvokeTx)
fmt.Println(resp, err)
if err != nil {
require.Equal(t, err.Error(), test.ExpectedError.Error())
require.Nil(t, resp)
}

}
}

// TestAddInvoke is a test function that verifies the behavior of the AddInvokeTransaction method.
//
Expand Down Expand Up @@ -566,7 +658,7 @@ func TestAddInvoke(t *testing.T) {
test.InvokeTx.Calldata, err = acnt.FmtCalldata([]rpc.FunctionCall{test.FnCall}, test.CairoContractVersion)
require.NoError(t, err)

err = acnt.SignInvokeTransaction(context.Background(), &test.InvokeTx)
test.InvokeTx.Signature, err = acnt.SignInvokeTransaction(context.Background(), test.InvokeTx)
require.NoError(t, err)

resp, err := acnt.AddInvokeTransaction(context.Background(), test.InvokeTx)
Expand Down Expand Up @@ -757,7 +849,7 @@ func TestTransactionHashInvokeV3(t *testing.T) {
Signature: []*felt.Felt{
utils.TestHexToFelt(t, "0x71a9b2cd8a8a6a4ca284dcddcdefc6c4fd20b92c1b201bd9836e4ce376fad16"),
utils.TestHexToFelt(t, "0x6bef4745194c9447fdc8dd3aec4fc738ab0a560b0d2c7bf62fbf58aef3abfc5")},
ResourceBounds: rpc.ResourceBoundsMapping{
ResourceBoundsMapping: rpc.ResourceBoundsMapping{
L1Gas: rpc.ResourceBounds{
MaxAmount: utils.TestHexToFelt(t, "0x186a0"),
MaxPricePerUnit: utils.TestHexToFelt(t, "0x5af3107a4000"),
Expand Down Expand Up @@ -1100,6 +1192,65 @@ func TestAddDeclareTxn(t *testing.T) {
}
}

func TestAddDeployAccountTxn(t *testing.T) {
if testEnv != "integration" {
t.Skip("Skipping test as it requires a integration environment")
}
client, err := rpc.NewClient(base)
require.NoError(t, err, "Error in rpc.NewClient")
provider := rpc.NewProvider(client)

AccountAddress := utils.TestHexToFelt(t, "0x043784df59268c02b716e20bf77797bd96c68c2f100b2a634e448c35e3ad363e")
PubKey := utils.TestHexToFelt(t, "0x043784df59268c02b716e20bf77797bd96c68c2f100b2a634e448c35e3ad363e")
PrivKey := utils.TestHexToFelt(t, "0x043b7fe9d91942c98cd5fd37579bd99ec74f879c4c79d886633eecae9dad35fa")

// Set up ks
ks := account.NewMemKeystore()
fakePrivKeyBI, ok := new(big.Int).SetString(PrivKey.String(), 0)
require.True(t, ok)
ks.Put(PubKey.String(), fakePrivKeyBI)

acnt, err := account.NewAccount(provider, AccountAddress, PubKey.String(), ks)
require.NoError(t, err)

classHash := utils.TestHexToFelt(t, "0x7b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69") // preDeployed classhash
require.NoError(t, err)

tx := rpc.DeployAccountTxnV3{
Nonce: &felt.Zero, // Contract accounts start with nonce zero.
Type: rpc.TransactionType_DeployAccount,
Version: rpc.TransactionV3,
Signature: []*felt.Felt{},
ClassHash: classHash,
NonceDataMode: rpc.DAModeL1,
FeeMode: rpc.DAModeL1,
ResourceBoundsMapping: rpc.ResourceBoundsMapping{
L1Gas: rpc.ResourceBounds{
MaxAmount: utils.TestHexToFelt(t, "0x186a0"),
MaxPricePerUnit: utils.TestHexToFelt(t, "0x5af3107a4000"),
},
L2Gas: rpc.ResourceBounds{
MaxAmount: new(felt.Felt),
MaxPricePerUnit: new(felt.Felt),
},
},
Tip: new(felt.Felt),
PayMasterData: []*felt.Felt{},
ContractAddressSalt: new(felt.Felt),
ConstructorCalldata: []*felt.Felt{
utils.TestHexToFelt(t, "AccountAddress"),
},
}

precomputedAddress, err := acnt.PrecomputeAddress(&felt.Zero, fakeUserPub, classHash, tx.ConstructorCalldata)
require.NoError(t, acnt.SignDeployAccountTransaction(context.Background(), &tx, precomputedAddress))

resp, err := acnt.AddDeployAccountTransaction(context.Background(), rpc.BroadcastDeployAccountTxn{DeployAccountTxn: tx})
require.NoError(t, err, "AddDeployAccountTransaction gave an Error")
require.NotNil(t, resp, "AddDeployAccountTransaction resp not nil")

}

// newDevnet creates a new devnet with the given URL.
//
// Parameters:
Expand Down

0 comments on commit 62433bc

Please sign in to comment.