diff --git a/adapters/projects/dorahacks/signup.go b/adapters/projects/dorahacks/signup.go new file mode 100644 index 0000000..446d326 --- /dev/null +++ b/adapters/projects/dorahacks/signup.go @@ -0,0 +1,88 @@ +package dorahacks + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/taikoxyz/trailblazer-adapters/adapters" +) + +const ( + // event SignUp(uint256 indexed _stateIdx, PubKey _userPubKey, uint256 _voiceCreditBalance); + logSignupSignatureHex string = "0xc7563c66f89e2fb0839e2b64ed54fe4803ff9428777814772ccfe4c385072c4b" +) + +type SignupIndexer struct { + client *ethclient.Client + addresses []common.Address +} + +func NewSignupIndexer(client *ethclient.Client, addresses []common.Address) *SignupIndexer { + return &SignupIndexer{ + client: client, + addresses: addresses, + } +} + +var _ adapters.LogIndexer[adapters.Whitelist] = &SignupIndexer{} + +func (indexer *SignupIndexer) Addresses() []common.Address { + return indexer.addresses +} + +func (indexer *SignupIndexer) Index(ctx context.Context, logs ...types.Log) ([]adapters.Whitelist, error) { + var ws []adapters.Whitelist + + for _, l := range logs { + if !indexer.isSignup(l) { + continue + } + + block, err := indexer.client.BlockByNumber(ctx, big.NewInt(int64(l.BlockNumber))) + if err != nil { + return nil, err + } + + txHash := l.TxHash + receipt, err := indexer.client.TransactionReceipt(ctx, txHash) + if err != nil { + return nil, err + } + if receipt.Status == 0 { + // tx failed, continue + continue + } + + tx, pending, err := indexer.client.TransactionByHash(ctx, txHash) + if err != nil { + return nil, err + } + if pending { + // tx pending, continue + continue + } + + sender, err := indexer.client.TransactionSender(ctx, tx, block.Hash(), receipt.TransactionIndex) + if err != nil { + return nil, err + } + + w := &adapters.Whitelist{ + User: sender, // msg.sender equals signup for DoraHacks MACI + Time: block.Time(), + BlockNumber: block.NumberU64(), + TxHash: txHash, + } + + ws = append(ws, *w) + } + + return ws, nil +} + +func (indexer *SignupIndexer) isSignup(l types.Log) bool { + return l.Topics[0].Hex() == logSignupSignatureHex +} diff --git a/adapters/projects/dorahacks/signup_test.go b/adapters/projects/dorahacks/signup_test.go new file mode 100644 index 0000000..cfcaab2 --- /dev/null +++ b/adapters/projects/dorahacks/signup_test.go @@ -0,0 +1,36 @@ +package dorahacks_test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/taikoxyz/trailblazer-adapters/adapters" + "github.com/taikoxyz/trailblazer-adapters/adapters/projects/dorahacks" +) + +func TestSignupIndexer(t *testing.T) { + taikoRPC := "https://rpc.taiko.xyz" + blocknumber := int64(861132) + + ctx := context.Background() + + client, err := ethclient.Dial(taikoRPC) + require.NoError(t, err) + + indexer := dorahacks.NewSignupIndexer(client, []common.Address{common.HexToAddress(dorahacks.VotingAddress)}) + + logs, err := adapters.GetLogs(ctx, client, indexer.Addresses(), blocknumber) + require.NoError(t, err) + + ws, err := indexer.Index(ctx, logs...) + assert.NoError(t, err) + assert.Len(t, ws, 1) + assert.Equal(t, common.HexToAddress("0xA9d1f06b6AF87B312aBbb523A5e41995F199930b"), ws[0].User) + assert.Equal(t, uint64(861132), ws[0].BlockNumber) + assert.Equal(t, uint64(1739528687), ws[0].Time) + assert.Equal(t, common.HexToHash("0x04f0a71af85058eeedd078cb2a21e18c82dbf93d814dcf0e051ad6c891116b60"), ws[0].TxHash) +}