11package sequence_test
22
33import (
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