Skip to content

Commit 901e4dc

Browse files
committed
feat: ini erc20 configuration transfer
1 parent 56958cb commit 901e4dc

File tree

1 file changed

+100
-0
lines changed

1 file changed

+100
-0
lines changed

intent_config_test.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package sequence_test
22

33
import (
4+
"context"
45
"fmt"
56
"math/big"
67
"testing"
@@ -10,6 +11,8 @@ import (
1011
"github.com/0xsequence/ethkit/go-ethereum/common"
1112
"github.com/0xsequence/go-sequence"
1213
v2 "github.com/0xsequence/go-sequence/core/v2"
14+
15+
"github.com/0xsequence/go-sequence/testutil"
1316
"github.com/davecgh/go-spew/spew"
1417
"github.com/stretchr/testify/assert"
1518
"github.com/stretchr/testify/require"
@@ -224,3 +227,100 @@ func TestCreateIntentConfigurationSignature_MultipleTransactions(t *testing.T) {
224227
// Expect that the signature (in hex) contains the substrings of the bundle's digest.
225228
assert.Contains(t, sigHex, bundleDigest.Hex()[2:], "signature should contain transaction bundle digest")
226229
}
230+
231+
func TestConfigurationSignatureERC20Transfer(t *testing.T) {
232+
// Create the test main signer
233+
mainSigner, err := ethwallet.NewWalletFromRandomEntropy()
234+
require.NoError(t, err)
235+
236+
// Deploy the ERC20 mock contract.
237+
erc20, _ := testChain.Deploy(t, "ERC20Mock")
238+
239+
// Now, we want to transfer 50 tokens from the wallet to a recipient.
240+
recipient := common.HexToAddress("0x3333333333333333333333333333333333333333")
241+
transferCalldata, err := erc20.Encode("transfer", recipient, big.NewInt(50))
242+
require.NoError(t, err)
243+
244+
// Create a transaction that calls the ERC20 transfer.
245+
// (Since the wallet holds the tokens, a normal transfer works to "spend" tokens.)
246+
tx := &sequence.Transaction{
247+
DelegateCall: false,
248+
RevertOnError: true,
249+
To: erc20.Address,
250+
Data: transferCalldata,
251+
// For a newly deployed wallet the nonce is 0.
252+
Nonce: big.NewInt(0),
253+
}
254+
255+
// Wrap the transaction in a single batch.
256+
txns := []*sequence.Transaction{tx}
257+
batches := [][]*sequence.Transaction{txns}
258+
259+
// Generate a configuration signature for the batch.
260+
// (The configuration signature "attests" that the wallet owner authorizes
261+
// this bundle of transactions.)
262+
configSig, err := sequence.CreateIntentConfigurationSignature(mainSigner.Address(), batches)
263+
require.NoError(t, err)
264+
// For a NoChainID signature the version byte is expected to be 0x02.
265+
assert.Equal(t, byte(0x02), configSig[0], "configuration signature should start with 0x02")
266+
267+
// Use a v2 dummy Sequence wallet
268+
wallet, err := testChain.V2DummySequenceWalletWithIntentConfig(1, batches)
269+
require.NoError(t, err)
270+
require.NotNil(t, wallet)
271+
272+
// Mint 100 tokens to the wallet.
273+
mintCalldata, err := erc20.Encode("mockMint", wallet.Address(), big.NewInt(100))
274+
require.NoError(t, err)
275+
err = testutil.SignAndSend(t, wallet, erc20.Address, mintCalldata)
276+
require.NoError(t, err)
277+
278+
// Verify that the wallet received 100 tokens.
279+
balances, err := testutil.ContractQuery(testChain.Provider, erc20.Address, "balanceOf(address)", "uint256", []string{wallet.Address().Hex()})
280+
require.NoError(t, err)
281+
require.Len(t, balances, 1)
282+
require.Equal(t, "100", balances[0])
283+
284+
// Build the overall bundle.
285+
bundle, err := sequence.CreateIntentBundle(txns)
286+
require.NoError(t, err)
287+
288+
// Get the digest of the bundle
289+
bundleDigest, err := bundle.Digest()
290+
require.NoError(t, err)
291+
292+
// Create a SignedTransactions
293+
signedTxns := &sequence.SignedTransactions{
294+
ChainID: testChain.ChainID(),
295+
WalletAddress: wallet.Address(),
296+
WalletConfig: wallet.GetWalletConfig(),
297+
WalletContext: wallet.GetWalletContext(),
298+
Transactions: txns,
299+
Signature: configSig,
300+
Digest: bundleDigest,
301+
}
302+
303+
// Send the transaction bundle – note that we do not use wallet.SignTransaction here
304+
// since we are testing that a pre-generated configuration signature works.
305+
metaTxnID, sentTx, waitReceipt, err := wallet.SendTransaction(context.Background(), signedTxns)
306+
require.NoError(t, err)
307+
require.NotEmpty(t, metaTxnID)
308+
require.NotNil(t, sentTx)
309+
310+
receipt, err := waitReceipt(context.Background())
311+
require.NoError(t, err)
312+
require.Equal(t, uint64(1), receipt.Status, "meta transaction should execute successfully")
313+
314+
// Verify that the transfer took place:
315+
// the wallet's token balance should have dropped from 100 to 50
316+
// and the recipient should have received 50 tokens.
317+
walletBalance, err := testutil.ContractQuery(testChain.Provider, erc20.Address, "balanceOf(address)", "uint256", []string{wallet.Address().Hex()})
318+
require.NoError(t, err)
319+
require.Len(t, walletBalance, 1)
320+
require.Equal(t, "50", walletBalance[0], "wallet balance should be reduced to 50")
321+
322+
recipientBalance, err := testutil.ContractQuery(testChain.Provider, erc20.Address, "balanceOf(address)", "uint256", []string{recipient.Hex()})
323+
require.NoError(t, err)
324+
require.Len(t, recipientBalance, 1)
325+
require.Equal(t, "50", recipientBalance[0], "recipient should receive 50 tokens")
326+
}

0 commit comments

Comments
 (0)