Skip to content

Commit

Permalink
fix: transfer txn with auto deploy.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zhangguiguang committed Jan 9, 2024
1 parent 41779ed commit 652addc
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 45 deletions.
96 changes: 55 additions & 41 deletions core/starknet/chain.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ type Chain struct {
rpc *account.Account
}

func NewChainWithRpc(baseRpc string) (*Chain, error) {
func NewChainWithRpc(baseRpc string) (c *Chain, err error) {
defer base.CatchPanicAndMapToBasicError(&err)

cli, err := ethrpc.DialContext(context.Background(), baseRpc)
if err != nil {
return nil, err
Expand Down Expand Up @@ -117,6 +119,9 @@ func (c *Chain) SendSignedTransaction(signedTxn base.SignedTransaction) (hash *b
}

if txn.depolyTxn != nil {
var err error
defer base.CatchPanicAndMapToBasicError(&err)

resp, err := c.rpc.AddDeployAccountTransaction(context.Background(), rpc.BroadcastDeployAccountTxn{
DeployAccountTxn: *txn.depolyTxn,
})
Expand All @@ -125,49 +130,58 @@ func (c *Chain) SendSignedTransaction(signedTxn base.SignedTransaction) (hash *b
}
return &base.OptionalString{Value: fullString(*resp.TransactionHash)}, nil
}
if txn.invokeTxn != nil {
resp, err := c.rpc.AddInvokeTransaction(context.Background(), txn.invokeTxn)

if txn.invokeTxn == nil {
return nil, base.ErrMissingTransaction
}
// send invoke txn
resp, err := c.rpc.AddInvokeTransaction(context.Background(), txn.invokeTxn)
if err != nil {
var err error
defer base.CatchPanicAndMapToBasicError(&err)

if !txn.NeedAutoDeploy {
return nil, err
}
deployed, err := c.IsContractAddressDeployed(txn.invokeTxn.SenderAddress.String())
if err != nil || deployed.Value == true {
return nil, err // if query failed, return the previous error.
}

// we need deploy the account firstly, and resend the original txn with fixed Nonce 1
pubHex := txn.Account.PublicKeyHex()
pubFelt, err := utils.HexToFelt(pubHex)
if err != nil {
return nil, err
}
version, err := CheckCairoVersionFelt(txn.invokeTxn.SenderAddress, pubFelt)
if err != nil {
if !txn.NeedAutoDeploy {
return nil, err
}
deployed, err_ := c.IsContractAddressDeployed(txn.invokeTxn.SenderAddress.String())
if err_ != nil || deployed.Value == true {
return nil, err // if query failed, return the previous error.
}

// we need deploy the account firstly, and resend the original txn with fixed Nonce 1
pubHex := txn.Account.PublicKeyHex()
pubFelt, err := utils.HexToFelt(pubHex)
if err != nil {
return nil, err
}
version, err := CheckCairoVersionFelt(txn.invokeTxn.SenderAddress, pubFelt)
if err != nil {
return nil, err
}
deployTxn, err := c.deployAccountTxnWithVersion(pubHex, "", version == 0)
if err != nil {
return nil, err
}
signedDeployTxn, err := deployTxn.SignedTransactionWithAccount(txn.Account)
if err != nil {
return nil, err
}
_, err = c.SendSignedTransaction(signedDeployTxn)
if err != nil {
return nil, err
}
// now resend the original txn, the nonce is 1 now
txn.invokeTxn.Nonce = new(felt.Felt).SetUint64(1)
resp, err = c.rpc.AddInvokeTransaction(context.Background(), txn.invokeTxn)
if err != nil {
return nil, err
}
return nil, err
}
deployTxn, err := c.deployAccountTxnWithVersion(pubHex, "", version == 0)
if err != nil {
return nil, err
}
signedDeployTxn, err := deployTxn.SignedTransactionWithAccount(txn.Account)
if err != nil {
return nil, err
}
_, err = c.SendSignedTransaction(signedDeployTxn)
if err != nil {
return nil, err
}
// now resend the original txn, the nonce is 1 now
txn.invokeTxn.Nonce = new(felt.Felt).SetUint64(1)
err = txn.ResignInvokeTransaction(c, txn.Account)
if err != nil {
return nil, err
}
resp, err = c.rpc.AddInvokeTransaction(context.Background(), txn.invokeTxn)
if err != nil {
return nil, err
}
return &base.OptionalString{Value: fullString(*resp.TransactionHash)}, nil
}
return nil, base.ErrMissingTransaction
return &base.OptionalString{Value: fullString(*resp.TransactionHash)}, nil
}

// Fetch transaction details through transaction hash
Expand Down
17 changes: 16 additions & 1 deletion core/starknet/chain_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,25 @@ import (
"testing"

"github.com/coming-chat/wallet-SDK/core/base"
"github.com/coming-chat/wallet-SDK/core/testcase"
"github.com/stretchr/testify/require"
"github.com/xiang-xx/starknet.go/rpc"
)

func ETH(e float64) testcase.Amount {
return testcase.Amount{
Amount: e,
Multiple: 1e18,
}
}

func Gwei(e float64) testcase.Amount {
return testcase.Amount{
Amount: e,
Multiple: 1e9,
}
}

func MainnetChain() *Chain {
c, _ := NewChainWithRpc(BaseRpcUrlMainnet)
return c
Expand Down Expand Up @@ -71,7 +86,7 @@ func TestTransfer(t *testing.T) {
token, err := chain.NewToken(ETHTokenAddress)
require.Nil(t, err)

txn, err := token.BuildTransfer(acc.Address(), acc.Address(), "10000000")
txn, err := token.BuildTransfer(acc.Address(), acc.Address(), Gwei(3).String())
require.Nil(t, err)

gasFee, err := chain.EstimateTransactionFeeUseAccount(txn, acc)
Expand Down
3 changes: 0 additions & 3 deletions core/starknet/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,6 @@ func (t *Token) BuildTransferAll(sender, receiver string) (txn base.Transaction,
func (c *Chain) queryCairoVersionForFormatCalldata(contractAddress felt.Felt) int {
classInfo, err := c.rpc.ClassAt(context.Background(), latestBlockId, &contractAddress)
if err != nil {
if err.Error() == rpc.ErrContractNotFound.Error() {
return 0
}
return 2 // default
}
switch info := classInfo.(type) {
Expand Down
9 changes: 9 additions & 0 deletions core/starknet/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ func (txn *SignedTransaction) HexString() (res *base.OptionalString, err error)
return nil, base.ErrUnsupportedFunction
}

func (txn *SignedTransaction) ResignInvokeTransaction(chain *Chain, acc *Account) error {
txnHash, err := chain.rpc.TransactionHashInvoke(*txn.invokeTxn)
if err != nil {
return err
}
txn.invokeTxn.Signature, err = acc.SignHash(txnHash)
return err
}

func AsSignedTransaction(txn base.SignedTransaction) *SignedTransaction {
if res, ok := txn.(*SignedTransaction); ok {
return res
Expand Down

0 comments on commit 652addc

Please sign in to comment.