diff --git a/packages/explorer-ui/graphql/queries/index.ts b/packages/explorer-ui/graphql/queries/index.ts index 28389f8e36..aa9024a94a 100644 --- a/packages/explorer-ui/graphql/queries/index.ts +++ b/packages/explorer-ui/graphql/queries/index.ts @@ -211,6 +211,7 @@ export const DAILY_STATISTICS_BY_CHAIN = gql` blast scroll linea + worldchain total } } diff --git a/services/explorer/backfill/chain_test.go b/services/explorer/backfill/chain_test.go index 7f6e15bfa6..94b9738121 100644 --- a/services/explorer/backfill/chain_test.go +++ b/services/explorer/backfill/chain_test.go @@ -142,7 +142,8 @@ func (b *BackfillSuite) TestBackfill() { redeemLog, err := b.storeTestLog(bridgeTx, uint32(testChainID.Uint64()), 2) Nil(b.T(), err) - bridgeTx, err = bridgeRef.TestWithdraw(transactOpts.TransactOpts, common.BigToAddress(big.NewInt(gofakeit.Int64())), common.HexToAddress(testTokens[0].TokenAddress), big.NewInt(int64(gofakeit.Uint32())), big.NewInt(int64(gofakeit.Uint32())), [32]byte{byte(gofakeit.Uint64())}) + baseNum := gofakeit.Uint32() + bridgeTx, err = bridgeRef.TestWithdraw(transactOpts.TransactOpts, common.BigToAddress(big.NewInt(gofakeit.Int64())), common.HexToAddress(testTokens[0].TokenAddress), big.NewInt(int64(baseNum)), big.NewInt(int64(float64(baseNum)*0.01)), [32]byte{byte(gofakeit.Uint64())}) Nil(b.T(), err) b.storeEthTx(bridgeTx, testChainID, big.NewInt(int64(2)), 3) withdrawLog, err := b.storeTestLog(bridgeTx, uint32(testChainID.Uint64()), 2) @@ -203,7 +204,7 @@ func (b *BackfillSuite) TestBackfill() { redeemV1Log, err := b.storeTestLog(bridgeTx, uint32(testChainID.Uint64()), 3) Nil(b.T(), err) - bridgeTx, err = bridgeV1Ref.TestWithdraw(transactOpts.TransactOpts, common.BigToAddress(big.NewInt(gofakeit.Int64())), common.HexToAddress(testTokens[0].TokenAddress), big.NewInt(int64(gofakeit.Uint32())), big.NewInt(int64(gofakeit.Uint32())), [32]byte{byte(gofakeit.Uint64())}) + bridgeTx, err = bridgeV1Ref.TestWithdraw(transactOpts.TransactOpts, common.BigToAddress(big.NewInt(gofakeit.Int64())), common.HexToAddress(testTokens[0].TokenAddress), big.NewInt(int64(baseNum)), big.NewInt(int64(float64(baseNum)*0.01)), [32]byte{byte(gofakeit.Uint64())}) Nil(b.T(), err) b.storeEthTx(bridgeTx, testChainID, big.NewInt(int64(3)), 3) withdrawV1Log, err := b.storeTestLog(bridgeTx, uint32(testChainID.Uint64()), 3) @@ -878,7 +879,7 @@ func (b *BackfillSuite) withdrawParity(log *types.Log, parser *parser.BridgePars BlockNumber: log.BlockNumber, TxHash: log.TxHash.String(), Token: parsedLog.Token.String(), - Amount: parsedLog.Amount, + Amount: new(big.Int).Sub(parsedLog.Amount, parsedLog.Fee), Recipient: recipient, Fee: parsedLog.Fee, @@ -911,7 +912,7 @@ func (b *BackfillSuite) withdrawParity(log *types.Log, parser *parser.BridgePars BlockNumber: log.BlockNumber, TxHash: log.TxHash.String(), Token: parsedLog.Token.String(), - Amount: parsedLog.Amount, + Amount: new(big.Int).Sub(parsedLog.Amount, parsedLog.Fee), Recipient: recipient, Fee: parsedLog.Fee, diff --git a/services/explorer/consumer/parser/rfqparser.go b/services/explorer/consumer/parser/rfqparser.go index 8342b7efb1..0cb8606e08 100644 --- a/services/explorer/consumer/parser/rfqparser.go +++ b/services/explorer/consumer/parser/rfqparser.go @@ -63,25 +63,32 @@ func (p *RFQParser) ParserType() string { func (p *RFQParser) ParseLog(log ethTypes.Log, chainID uint32) (*model.RFQEvent, rfqTypes.EventLog, error) { logTopic := log.Topics[0] iFace, err := func(log ethTypes.Log) (rfqTypes.EventLog, error) { - switch logTopic { - case fastbridge.Topic(rfqTypes.BridgeRequestedEvent): - iFace, err := p.Filterer.ParseBridgeRequested(log) - if err != nil { - return nil, fmt.Errorf("could not parse fastbridge bridge requested : %w", err) - } - return iFace, nil - case fastbridge.Topic(rfqTypes.BridgeRelayedEvent): - iFace, err := p.Filterer.ParseBridgeRelayed(log) - if err != nil { - return nil, fmt.Errorf("could not parse fastbridge bridge relayed: %w", err) - } - return iFace, nil - - default: - logger.Warnf("ErrUnknownTopic in rfq: %s %s chain: %d address: %s", log.TxHash, logTopic.String(), chainID, log.Address.Hex()) + // Get the topic hash safely + bridgeRequestedTopic, err := fastbridge.Topic(rfqTypes.BridgeRequestedEvent) + if err == nil && logTopic == bridgeRequestedTopic { + return p.Filterer.ParseBridgeRequested(log) + } - return nil, fmt.Errorf(ErrUnknownTopic) + bridgeRelayedTopic, err := fastbridge.Topic(rfqTypes.BridgeRelayedEvent) + if err == nil && logTopic == bridgeRelayedTopic { + return p.Filterer.ParseBridgeRelayed(log) + } + bridgeProofProvidedTopic, err := fastbridge.Topic(rfqTypes.BridgeProvenEvent) + if err == nil && logTopic == bridgeProofProvidedTopic { + return p.Filterer.ParseBridgeProofProvided(log) } + bridgeDepositClaimedTopic, err := fastbridge.Topic(rfqTypes.BridgeClaimedEvent) + if err == nil && logTopic == bridgeDepositClaimedTopic { + return p.Filterer.ParseBridgeDepositClaimed(log) + } + bridgeDepositRefundedTopic, err := fastbridge.Topic(rfqTypes.BridgeRefundedEvent) + if err == nil && logTopic == bridgeDepositRefundedTopic { + return p.Filterer.ParseBridgeDepositRefunded(log) + } + + logger.Warnf("ErrUnknownTopic in rfq: %s %s chain: %d address: %s", + log.TxHash, logTopic.String(), chainID, log.Address.Hex()) + return nil, fmt.Errorf(ErrUnknownTopic) }(log) if err != nil { @@ -108,6 +115,7 @@ func (p *RFQParser) MatureLogs(ctx context.Context, rfqEvent *model.RFQEvent, iF } // If we have a timestamp, populate the following attributes of rfqEvent. + // This logic will have to be generalized as we support more tokens (we need to programatically find coingecko id based on token address) timeStampBig := uint64(*timeStamp) rfqEvent.TimeStamp = &timeStampBig @@ -115,18 +123,18 @@ func (p *RFQParser) MatureLogs(ctx context.Context, rfqEvent *model.RFQEvent, iF tokenAddressStr := common.HexToAddress(rfqEvent.OriginToken).Hex() const ethAddress = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee" - if strings.EqualFold(tokenAddressStr, ethAddress) { + switch { + case strings.EqualFold(tokenAddressStr, ethAddress) || strings.EqualFold(tokenAddressStr, "0x2170Ed0880ac9A755fd29B2688956BD959F933F8"): rfqEvent.TokenSymbol = "ETH" rfqEvent.TokenDecimal = new(uint8) *rfqEvent.TokenDecimal = 18 curCoinGeckoID = ethCoinGeckoID - } else if strings.EqualFold(tokenAddressStr, "0x2cFc85d8E48F8EAB294be644d9E25C3030863003") || strings.EqualFold(tokenAddressStr, "0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1") { + case strings.EqualFold(tokenAddressStr, "0x2cFc85d8E48F8EAB294be644d9E25C3030863003") || strings.EqualFold(tokenAddressStr, "0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1"): rfqEvent.TokenSymbol = "WLD" rfqEvent.TokenDecimal = new(uint8) *rfqEvent.TokenDecimal = 18 - curCoinGeckoID = "worldchain" - } else { - // Assuming any other token is USDC + curCoinGeckoID = "worldcoin-wld" + default: rfqEvent.TokenSymbol = "USDC" rfqEvent.TokenDecimal = new(uint8) *rfqEvent.TokenDecimal = 6 @@ -232,6 +240,14 @@ func eventToRFQEvent(event rfqTypes.EventLog, chainID uint32) model.RFQEvent { } func rfqEventToBridgeEvent(rfqEvent model.RFQEvent) model.BridgeEvent { + // Only convert BridgeRequestedEvent and BridgeRelayedEvent to bridge events + // Exclude BridgeDepositRefunded, BridgeProofProvided, and BridgeDepositClaimed + eventType := rfqEvent.EventType + if eventType != rfqTypes.BridgeRequestedEvent.Int() && + eventType != rfqTypes.BridgeRelayedEvent.Int() { + return model.BridgeEvent{} + } + bridgeType := bridgeTypes.BridgeRequestedEvent token := rfqEvent.OriginToken amount := rfqEvent.OriginAmount diff --git a/services/explorer/contracts/fastbridge/request.go b/services/explorer/contracts/fastbridge/request.go index 8b4e49b252..0c0d3f45a0 100644 --- a/services/explorer/contracts/fastbridge/request.go +++ b/services/explorer/contracts/fastbridge/request.go @@ -191,3 +191,273 @@ func (e FastBridgeBridgeRelayed) GetSendChainGas() *bool { func (e FastBridgeBridgeRelayed) GetSender() *string { return nil } + +// GetBlockNumber gets the block number for the event. +func (e FastBridgeBridgeDepositRefunded) GetBlockNumber() uint64 { + return e.Raw.BlockNumber +} + +// GetTxHash gets the tx hash for the event. +func (e FastBridgeBridgeDepositRefunded) GetTxHash() common.Hash { + return e.Raw.TxHash +} + +// GetContractAddress gets the contract address the event occurred on. +func (e FastBridgeBridgeDepositRefunded) GetContractAddress() common.Address { + return e.Raw.Address +} + +// GetEventType gets the event type for the event. +func (e FastBridgeBridgeDepositRefunded) GetEventType() fastbridge.EventType { + return fastbridge.BridgeRefundedEvent +} + +// GetEventIndex gets the event index for the event. +func (e FastBridgeBridgeDepositRefunded) GetEventIndex() uint64 { + return uint64(e.Raw.TxIndex) +} + +// GetTransactionID gets the transaction id for the event. +func (e FastBridgeBridgeDepositRefunded) GetTransactionID() [32]byte { + return e.TransactionId +} + +// GetSender gets the sender for the event. +func (e FastBridgeBridgeDepositRefunded) GetSender() *string { + return nil +} + +// GetRequest gets the request for the event. +func (e FastBridgeBridgeDepositRefunded) GetRequest() *[]byte { + return nil +} + +// GetOriginChainID gets the origin chain id for the event. +func (e FastBridgeBridgeDepositRefunded) GetOriginChainID() *big.Int { + return nil +} + +// GetDestChainID gets the destination chain id for the event. +func (e FastBridgeBridgeDepositRefunded) GetDestChainID() *big.Int { + return nil +} + +// GetOriginToken gets the origin token for the event. +func (e FastBridgeBridgeDepositRefunded) GetOriginToken() common.Address { + return common.Address{} +} + +// GetDestToken gets the destination token for the event. +func (e FastBridgeBridgeDepositRefunded) GetDestToken() common.Address { + return common.Address{} +} + +// GetOriginAmount gets the origin amount for the event. +func (e FastBridgeBridgeDepositRefunded) GetOriginAmount() *big.Int { + return nil +} + +// GetDestAmount gets the destination amount for the event. +func (e FastBridgeBridgeDepositRefunded) GetDestAmount() *big.Int { + return nil +} + +// GetSendChainGas gets the send chain gas for the event. +func (e FastBridgeBridgeDepositRefunded) GetSendChainGas() *bool { + return nil +} + +// GetChainGasAmount gets the chain gas amount for the event. +func (e FastBridgeBridgeDepositRefunded) GetChainGasAmount() *big.Int { + return nil +} + +// GetRelayer gets the relayer address for the event. +func (e FastBridgeBridgeDepositRefunded) GetRelayer() *string { + return nil +} + +// GetTo gets the to address for the event. +func (e FastBridgeBridgeDepositRefunded) GetTo() *string { + return nil +} + +// GetTxHash gets the tx hash for the event. +func (e FastBridgeBridgeProofProvided) GetTxHash() common.Hash { + return e.Raw.TxHash +} + +// GetContractAddress gets the contract address the event occurred on. +func (e FastBridgeBridgeProofProvided) GetContractAddress() common.Address { + return e.Raw.Address +} + +// GetBlockNumber gets the block number for the event. +func (e FastBridgeBridgeProofProvided) GetBlockNumber() uint64 { + return e.Raw.BlockNumber +} + +// GetEventType gets the event type for the event. +func (e FastBridgeBridgeProofProvided) GetEventType() fastbridge.EventType { + return fastbridge.BridgeProvenEvent +} + +// GetEventIndex gets the event index for the event. +func (e FastBridgeBridgeProofProvided) GetEventIndex() uint64 { + return uint64(e.Raw.TxIndex) +} + +// GetTransactionID gets the transaction id for the event. +func (e FastBridgeBridgeProofProvided) GetTransactionID() [32]byte { + return e.TransactionId +} + +// GetSender gets the sender for the event. +func (e FastBridgeBridgeProofProvided) GetSender() *string { + return nil +} + +// GetRequest gets the request for the event. +func (e FastBridgeBridgeProofProvided) GetRequest() *[]byte { + return nil +} + +// GetOriginChainID gets the origin chain id for the event. +func (e FastBridgeBridgeProofProvided) GetOriginChainID() *big.Int { + return nil +} + +// GetDestChainID gets the destination chain id for the event. +func (e FastBridgeBridgeProofProvided) GetDestChainID() *big.Int { + return nil +} + +// GetOriginToken gets the origin token for the event. +func (e FastBridgeBridgeProofProvided) GetOriginToken() common.Address { + return common.Address{} +} + +// GetDestToken gets the destination token for the event. +func (e FastBridgeBridgeProofProvided) GetDestToken() common.Address { + return common.Address{} +} + +// GetOriginAmount gets the origin amount for the event. +func (e FastBridgeBridgeProofProvided) GetOriginAmount() *big.Int { + return nil +} + +// GetDestAmount gets the destination amount for the event. +func (e FastBridgeBridgeProofProvided) GetDestAmount() *big.Int { + return nil +} + +// GetSendChainGas gets the send chain gas for the event. +func (e FastBridgeBridgeProofProvided) GetSendChainGas() *bool { + return nil +} + +// GetChainGasAmount gets the chain gas amount for the event. +func (e FastBridgeBridgeProofProvided) GetChainGasAmount() *big.Int { + return nil +} + +// GetRelayer gets the relayer address for the event. +func (e FastBridgeBridgeProofProvided) GetRelayer() *string { + return nil +} + +// GetTo gets the to address for the event. +func (e FastBridgeBridgeProofProvided) GetTo() *string { + return nil +} + +// GetTxHash gets the tx hash for the event. +func (e FastBridgeBridgeDepositClaimed) GetTxHash() common.Hash { + return e.Raw.TxHash +} + +// GetContractAddress gets the contract address the event occurred on. +func (e FastBridgeBridgeDepositClaimed) GetContractAddress() common.Address { + return e.Raw.Address +} + +// GetBlockNumber gets the block number for the event. +func (e FastBridgeBridgeDepositClaimed) GetBlockNumber() uint64 { + return e.Raw.BlockNumber +} + +// GetEventType gets the event type for the event. +func (e FastBridgeBridgeDepositClaimed) GetEventType() fastbridge.EventType { + return fastbridge.BridgeClaimedEvent +} + +// GetEventIndex gets the event index for the event. +func (e FastBridgeBridgeDepositClaimed) GetEventIndex() uint64 { + return uint64(e.Raw.TxIndex) +} + +// GetTransactionID gets the transaction id for the event. +func (e FastBridgeBridgeDepositClaimed) GetTransactionID() [32]byte { + return e.TransactionId +} + +// GetSender gets the sender for the event. +func (e FastBridgeBridgeDepositClaimed) GetSender() *string { + return nil +} + +// GetRequest gets the request for the event. +func (e FastBridgeBridgeDepositClaimed) GetRequest() *[]byte { + return nil +} + +// GetOriginChainID gets the origin chain id for the event. +func (e FastBridgeBridgeDepositClaimed) GetOriginChainID() *big.Int { + return nil +} + +// GetDestChainID gets the destination chain id for the event. +func (e FastBridgeBridgeDepositClaimed) GetDestChainID() *big.Int { + return nil +} + +// GetOriginToken gets the origin token for the event. +func (e FastBridgeBridgeDepositClaimed) GetOriginToken() common.Address { + return common.Address{} +} + +// GetDestToken gets the destination token for the event. +func (e FastBridgeBridgeDepositClaimed) GetDestToken() common.Address { + return common.Address{} +} + +// GetOriginAmount gets the origin amount for the event. +func (e FastBridgeBridgeDepositClaimed) GetOriginAmount() *big.Int { + return nil +} + +// GetDestAmount gets the destination amount for the event. +func (e FastBridgeBridgeDepositClaimed) GetDestAmount() *big.Int { + return nil +} + +// GetSendChainGas gets the send chain gas for the event. +func (e FastBridgeBridgeDepositClaimed) GetSendChainGas() *bool { + return nil +} + +// GetChainGasAmount gets the chain gas amount for the event. +func (e FastBridgeBridgeDepositClaimed) GetChainGasAmount() *big.Int { + return nil +} + +// GetRelayer gets the relayer address for the event. +func (e FastBridgeBridgeDepositClaimed) GetRelayer() *string { + return nil +} + +// GetTo gets the to address for the event. +func (e FastBridgeBridgeDepositClaimed) GetTo() *string { + return nil +} diff --git a/services/explorer/contracts/fastbridge/topics.go b/services/explorer/contracts/fastbridge/topics.go index 6845d77a51..03686c37c5 100644 --- a/services/explorer/contracts/fastbridge/topics.go +++ b/services/explorer/contracts/fastbridge/topics.go @@ -2,6 +2,7 @@ package fastbridge import ( "bytes" + "fmt" "strings" "github.com/ethereum/go-ethereum/accounts/abi" @@ -48,10 +49,10 @@ func EventTypeFromTopic(ogTopic common.Hash) *fastbridge.EventType { } // Topic gets the topic from the event type. -func Topic(eventType fastbridge.EventType) common.Hash { +func Topic(eventType fastbridge.EventType) (common.Hash, error) { topicHash, ok := TopicMap()[fastbridge.EventType(eventType.Int())] if !ok { - panic("unknown event") + return common.Hash{}, fmt.Errorf("unknown event type: %v", eventType) } - return topicHash + return topicHash, nil } diff --git a/services/explorer/graphql/client/client.go b/services/explorer/graphql/client/client.go index 704c82de6b..2c8628e41c 100644 --- a/services/explorer/graphql/client/client.go +++ b/services/explorer/graphql/client/client.go @@ -62,9 +62,10 @@ type GetBridgeTransactions struct { Time *int "json:\"time\" graphql:\"time\"" FormattedTime *string "json:\"formattedTime\" graphql:\"formattedTime\"" } "json:\"toInfo\" graphql:\"toInfo\"" - Kappa *string "json:\"kappa\" graphql:\"kappa\"" - Pending *bool "json:\"pending\" graphql:\"pending\"" - SwapSuccess *bool "json:\"swapSuccess\" graphql:\"swapSuccess\"" + Kappa *string "json:\"kappa\" graphql:\"kappa\"" + Pending *bool "json:\"pending\" graphql:\"pending\"" + SwapSuccess *bool "json:\"swapSuccess\" graphql:\"swapSuccess\"" + BridgeModule *string "json:\"bridgeModule\" graphql:\"bridgeModule\"" } "json:\"response\" graphql:\"response\"" } type GetCountByChainID struct { @@ -245,10 +246,11 @@ type GetOriginBridgeTx struct { Time *int "json:\"time\" graphql:\"time\"" FormattedTime *string "json:\"formattedTime\" graphql:\"formattedTime\"" } "json:\"bridgeTx\" graphql:\"bridgeTx\"" - Pending *bool "json:\"pending\" graphql:\"pending\"" - Type *model.BridgeTxType "json:\"type\" graphql:\"type\"" - Kappa *string "json:\"kappa\" graphql:\"kappa\"" - KappaStatus *model.KappaStatus "json:\"kappaStatus\" graphql:\"kappaStatus\"" + Pending *bool "json:\"pending\" graphql:\"pending\"" + Type *model.BridgeTxType "json:\"type\" graphql:\"type\"" + Kappa *string "json:\"kappa\" graphql:\"kappa\"" + KappaStatus *model.KappaStatus "json:\"kappaStatus\" graphql:\"kappaStatus\"" + BridgeModule *string "json:\"bridgeModule\" graphql:\"bridgeModule\"" } "json:\"response\" graphql:\"response\"" } type GetDestinationBridgeTx struct { @@ -267,10 +269,11 @@ type GetDestinationBridgeTx struct { Time *int "json:\"time\" graphql:\"time\"" FormattedTime *string "json:\"formattedTime\" graphql:\"formattedTime\"" } "json:\"bridgeTx\" graphql:\"bridgeTx\"" - Pending *bool "json:\"pending\" graphql:\"pending\"" - Type *model.BridgeTxType "json:\"type\" graphql:\"type\"" - Kappa *string "json:\"kappa\" graphql:\"kappa\"" - KappaStatus *model.KappaStatus "json:\"kappaStatus\" graphql:\"kappaStatus\"" + Pending *bool "json:\"pending\" graphql:\"pending\"" + Type *model.BridgeTxType "json:\"type\" graphql:\"type\"" + Kappa *string "json:\"kappa\" graphql:\"kappa\"" + KappaStatus *model.KappaStatus "json:\"kappaStatus\" graphql:\"kappaStatus\"" + BridgeModule *string "json:\"bridgeModule\" graphql:\"bridgeModule\"" } "json:\"response\" graphql:\"response\"" } @@ -306,6 +309,7 @@ const GetBridgeTransactionsDocument = `query GetBridgeTransactions ($chainIDTo: kappa pending swapSuccess + bridgeModule } } ` @@ -698,6 +702,7 @@ const GetOriginBridgeTxDocument = `query GetOriginBridgeTx ($chainID: Int!, $txn type kappa kappaStatus + bridgeModule } } ` @@ -737,6 +742,7 @@ const GetDestinationBridgeTxDocument = `query GetDestinationBridgeTx ($chainID: type kappa kappaStatus + bridgeModule } } ` diff --git a/services/explorer/graphql/client/queries/queries.graphql b/services/explorer/graphql/client/queries/queries.graphql index 3d351f3cc1..5c5ed67e93 100644 --- a/services/explorer/graphql/client/queries/queries.graphql +++ b/services/explorer/graphql/client/queries/queries.graphql @@ -49,6 +49,7 @@ query GetBridgeTransactions($chainIDTo: [Int],$chainIDFrom: [Int], $addressTo: S kappa pending swapSuccess + bridgeModule } } @@ -303,6 +304,7 @@ query GetOriginBridgeTx($chainID: Int!, $txnHash: String!, $bridgeType: BridgeTy type kappa kappaStatus + bridgeModule } } query GetDestinationBridgeTx($chainID: Int!, $kappa: String!, $address: String!, $timestamp: Int!, $bridgeType: BridgeType!, $historical: Boolean) { @@ -332,5 +334,6 @@ query GetDestinationBridgeTx($chainID: Int!, $kappa: String!, $address: String!, type kappa kappaStatus + bridgeModule } } diff --git a/services/explorer/graphql/server/graph/model/models_gen.go b/services/explorer/graphql/server/graph/model/models_gen.go index c090c167e4..801708bf02 100644 --- a/services/explorer/graphql/server/graph/model/models_gen.go +++ b/services/explorer/graphql/server/graph/model/models_gen.go @@ -52,20 +52,22 @@ type BlockHeight struct { // to and from transactions. If a `from` transaction does not have a corresponding // `to` transaction, `pending` will be true. type BridgeTransaction struct { - FromInfo *PartialInfo `json:"fromInfo,omitempty"` - ToInfo *PartialInfo `json:"toInfo,omitempty"` - Kappa *string `json:"kappa,omitempty"` - Pending *bool `json:"pending,omitempty"` - SwapSuccess *bool `json:"swapSuccess,omitempty"` + FromInfo *PartialInfo `json:"fromInfo,omitempty"` + ToInfo *PartialInfo `json:"toInfo,omitempty"` + Kappa *string `json:"kappa,omitempty"` + Pending *bool `json:"pending,omitempty"` + SwapSuccess *bool `json:"swapSuccess,omitempty"` + BridgeModule *string `json:"bridgeModule,omitempty"` } // BridgeWatcherTx represents a single sided bridge transaction specifically for the bridge watcher. type BridgeWatcherTx struct { - BridgeTx *PartialInfo `json:"bridgeTx,omitempty"` - Pending *bool `json:"pending,omitempty"` - Type *BridgeTxType `json:"type,omitempty"` - Kappa *string `json:"kappa,omitempty"` - KappaStatus *KappaStatus `json:"kappaStatus,omitempty"` + BridgeTx *PartialInfo `json:"bridgeTx,omitempty"` + Pending *bool `json:"pending,omitempty"` + Type *BridgeTxType `json:"type,omitempty"` + Kappa *string `json:"kappa,omitempty"` + KappaStatus *KappaStatus `json:"kappaStatus,omitempty"` + BridgeModule *string `json:"bridgeModule,omitempty"` } type ContractQuery struct { diff --git a/services/explorer/graphql/server/graph/queryutils.go b/services/explorer/graphql/server/graph/queryutils.go index 42d59f9563..00ab52dbe3 100644 --- a/services/explorer/graphql/server/graph/queryutils.go +++ b/services/explorer/graphql/server/graph/queryutils.go @@ -689,12 +689,14 @@ func GetPartialInfoFromBridgeEventHybrid(bridgeEvent sql.HybridBridgeEvent, incl if kappa == "" { kappa = bridgeEvent.TKappa.String } + bridgeModule := getBridgeModule(int(bridgeEvent.FEventType)) bridgeTx = model.BridgeTransaction{ - FromInfo: fromInfos, - ToInfo: toInfos, - Kappa: &kappa, - Pending: &pending, - SwapSuccess: &swapSuccess, + FromInfo: fromInfos, + ToInfo: toInfos, + Kappa: &kappa, + Pending: &pending, + SwapSuccess: &swapSuccess, + BridgeModule: &bridgeModule, } return &bridgeTx, nil } @@ -1775,12 +1777,14 @@ func bwBridgeMVToBWTxOrigin(bridgeEvent *sql.HybridBridgeEvent, txType model.Bri Time: ×tamp, FormattedTime: &timeStampFormatted, } + bridgeModule := getBridgeModule(int(bridgeEvent.FEventType)) result := &model.BridgeWatcherTx{ - BridgeTx: &bridgeTx, - Pending: &isPending, - Type: &txType, - Kappa: &kappa, - KappaStatus: &kappaStatus, + BridgeTx: &bridgeTx, + Pending: &isPending, + Type: &txType, + Kappa: &kappa, + KappaStatus: &kappaStatus, + BridgeModule: &bridgeModule, } return result, nil } @@ -1823,12 +1827,14 @@ func bwBridgeMVToBWTxDestination(bridgeEvent *sql.HybridBridgeEvent, txType mode Time: ×tamp, FormattedTime: &timeStampFormatted, } + bridgeModule := getBridgeModule(int(bridgeEvent.TEventType)) result := &model.BridgeWatcherTx{ - BridgeTx: &bridgeTx, - Pending: &isPending, - Type: &txType, - Kappa: &kappa, - KappaStatus: &kappaStatus, + BridgeTx: &bridgeTx, + Pending: &isPending, + Type: &txType, + Kappa: &kappa, + KappaStatus: &kappaStatus, + BridgeModule: &bridgeModule, } return result, nil } @@ -1865,3 +1871,16 @@ func (r *queryResolver) getContractAddressFromType(chainID uint32, contractType return "", fmt.Errorf("contract type not supported") } } + +func getBridgeModule(eventType int) string { + switch { + case eventType < 10: + return "SynapseBridge" + case eventType == 10: + return "SynapseCCTP" + case eventType == 12: + return "SynapseRFQ" + default: + return "" + } +} diff --git a/services/explorer/graphql/server/graph/resolver/server.go b/services/explorer/graphql/server/graph/resolver/server.go index 29689da5c4..9558cc8be2 100644 --- a/services/explorer/graphql/server/graph/resolver/server.go +++ b/services/explorer/graphql/server/graph/resolver/server.go @@ -79,19 +79,21 @@ type ComplexityRoot struct { } BridgeTransaction struct { - FromInfo func(childComplexity int) int - Kappa func(childComplexity int) int - Pending func(childComplexity int) int - SwapSuccess func(childComplexity int) int - ToInfo func(childComplexity int) int + BridgeModule func(childComplexity int) int + FromInfo func(childComplexity int) int + Kappa func(childComplexity int) int + Pending func(childComplexity int) int + SwapSuccess func(childComplexity int) int + ToInfo func(childComplexity int) int } BridgeWatcherTx struct { - BridgeTx func(childComplexity int) int - Kappa func(childComplexity int) int - KappaStatus func(childComplexity int) int - Pending func(childComplexity int) int - Type func(childComplexity int) int + BridgeModule func(childComplexity int) int + BridgeTx func(childComplexity int) int + Kappa func(childComplexity int) int + KappaStatus func(childComplexity int) int + Pending func(childComplexity int) int + Type func(childComplexity int) int } DateResult struct { @@ -409,6 +411,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.BlockHeight.Type(childComplexity), true + case "BridgeTransaction.bridgeModule": + if e.complexity.BridgeTransaction.BridgeModule == nil { + break + } + + return e.complexity.BridgeTransaction.BridgeModule(childComplexity), true + case "BridgeTransaction.fromInfo": if e.complexity.BridgeTransaction.FromInfo == nil { break @@ -444,6 +453,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.BridgeTransaction.ToInfo(childComplexity), true + case "BridgeWatcherTx.bridgeModule": + if e.complexity.BridgeWatcherTx.BridgeModule == nil { + break + } + + return e.complexity.BridgeWatcherTx.BridgeModule(childComplexity), true + case "BridgeWatcherTx.bridgeTx": if e.complexity.BridgeWatcherTx.BridgeTx == nil { break @@ -1501,6 +1517,7 @@ type BridgeTransaction { kappa: String pending: Boolean swapSuccess: Boolean + bridgeModule: String } """ PartialInfo is a transaction that occurred on one chain. @@ -1535,6 +1552,7 @@ type BridgeWatcherTx { type: BridgeTxType kappa: String kappaStatus: KappaStatus + bridgeModule: String } """ DateResult is a given statistic for a given date. @@ -3581,6 +3599,47 @@ func (ec *executionContext) fieldContext_BridgeTransaction_swapSuccess(ctx conte return fc, nil } +func (ec *executionContext) _BridgeTransaction_bridgeModule(ctx context.Context, field graphql.CollectedField, obj *model.BridgeTransaction) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_BridgeTransaction_bridgeModule(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.BridgeModule, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2áš–string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_BridgeTransaction_bridgeModule(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "BridgeTransaction", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _BridgeWatcherTx_bridgeTx(ctx context.Context, field graphql.CollectedField, obj *model.BridgeWatcherTx) (ret graphql.Marshaler) { fc, err := ec.fieldContext_BridgeWatcherTx_bridgeTx(ctx, field) if err != nil { @@ -3816,6 +3875,47 @@ func (ec *executionContext) fieldContext_BridgeWatcherTx_kappaStatus(ctx context return fc, nil } +func (ec *executionContext) _BridgeWatcherTx_bridgeModule(ctx context.Context, field graphql.CollectedField, obj *model.BridgeWatcherTx) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_BridgeWatcherTx_bridgeModule(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.BridgeModule, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*string) + fc.Result = res + return ec.marshalOString2áš–string(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_BridgeWatcherTx_bridgeModule(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "BridgeWatcherTx", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type String does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _DateResult_date(ctx context.Context, field graphql.CollectedField, obj *model.DateResult) (ret graphql.Marshaler) { fc, err := ec.fieldContext_DateResult_date(ctx, field) if err != nil { @@ -6846,6 +6946,8 @@ func (ec *executionContext) fieldContext_Query_bridgeTransactions(ctx context.Co return ec.fieldContext_BridgeTransaction_pending(ctx, field) case "swapSuccess": return ec.fieldContext_BridgeTransaction_swapSuccess(ctx, field) + case "bridgeModule": + return ec.fieldContext_BridgeTransaction_bridgeModule(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type BridgeTransaction", field.Name) }, @@ -7506,6 +7608,8 @@ func (ec *executionContext) fieldContext_Query_getOriginBridgeTx(ctx context.Con return ec.fieldContext_BridgeWatcherTx_kappa(ctx, field) case "kappaStatus": return ec.fieldContext_BridgeWatcherTx_kappaStatus(ctx, field) + case "bridgeModule": + return ec.fieldContext_BridgeWatcherTx_bridgeModule(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type BridgeWatcherTx", field.Name) }, @@ -7570,6 +7674,8 @@ func (ec *executionContext) fieldContext_Query_getDestinationBridgeTx(ctx contex return ec.fieldContext_BridgeWatcherTx_kappa(ctx, field) case "kappaStatus": return ec.fieldContext_BridgeWatcherTx_kappaStatus(ctx, field) + case "bridgeModule": + return ec.fieldContext_BridgeWatcherTx_bridgeModule(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type BridgeWatcherTx", field.Name) }, @@ -10324,6 +10430,8 @@ func (ec *executionContext) _BridgeTransaction(ctx context.Context, sel ast.Sele out.Values[i] = ec._BridgeTransaction_pending(ctx, field, obj) case "swapSuccess": out.Values[i] = ec._BridgeTransaction_swapSuccess(ctx, field, obj) + case "bridgeModule": + out.Values[i] = ec._BridgeTransaction_bridgeModule(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -10368,6 +10476,8 @@ func (ec *executionContext) _BridgeWatcherTx(ctx context.Context, sel ast.Select out.Values[i] = ec._BridgeWatcherTx_kappa(ctx, field, obj) case "kappaStatus": out.Values[i] = ec._BridgeWatcherTx_kappaStatus(ctx, field, obj) + case "bridgeModule": + out.Values[i] = ec._BridgeWatcherTx_bridgeModule(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/services/explorer/graphql/server/graph/schema/types.graphql b/services/explorer/graphql/server/graph/schema/types.graphql index 084c2da036..9759feb118 100644 --- a/services/explorer/graphql/server/graph/schema/types.graphql +++ b/services/explorer/graphql/server/graph/schema/types.graphql @@ -9,6 +9,7 @@ type BridgeTransaction { kappa: String pending: Boolean swapSuccess: Boolean + bridgeModule: String } """ PartialInfo is a transaction that occurred on one chain. @@ -43,6 +44,7 @@ type BridgeWatcherTx { type: BridgeTxType kappa: String kappaStatus: KappaStatus + bridgeModule: String } """ DateResult is a given statistic for a given date. diff --git a/services/explorer/static/tokenIDToCoinGeckoID.yaml b/services/explorer/static/tokenIDToCoinGeckoID.yaml index 574cc7edc8..a6cfbcc9eb 100644 --- a/services/explorer/static/tokenIDToCoinGeckoID.yaml +++ b/services/explorer/static/tokenIDToCoinGeckoID.yaml @@ -40,4 +40,4 @@ USDbC: 'usd-coin' crvUSD: 'usd-coin' USDB: 'usdb' SPEC: 'spectral' -WLD: 'worldcoin' +WLD: 'worldcoin-wld' diff --git a/services/explorer/static/tokenSymbolToCoinGeckoID.yaml b/services/explorer/static/tokenSymbolToCoinGeckoID.yaml index 6288259e8d..47b021fafb 100644 --- a/services/explorer/static/tokenSymbolToCoinGeckoID.yaml +++ b/services/explorer/static/tokenSymbolToCoinGeckoID.yaml @@ -40,4 +40,4 @@ usdbc: 'usd-coin' crvusd: 'usd-coin' usdb: 'usdb' spec: 'spectral' -wld: 'worldcoin' +wld: 'worldcoin-wld' diff --git a/services/explorer/types/fastbridge/eventtype.go b/services/explorer/types/fastbridge/eventtype.go index 47df7f8827..5bce6ba971 100644 --- a/services/explorer/types/fastbridge/eventtype.go +++ b/services/explorer/types/fastbridge/eventtype.go @@ -10,11 +10,17 @@ const ( BridgeRequestedEvent EventType = iota // BridgeRelayedEvent is emitted when a RFQ request is relayed to the destination chain. BridgeRelayedEvent + // BridgeRefundedEvent is emitted when a RFQ request is refunded. + BridgeRefundedEvent + // BridgeProvenEvent is emitted when a RFQ request is proven. + BridgeProvenEvent + // BridgeClaimedEvent is emitted when a RFQ request is claimed. + BridgeClaimedEvent ) // AllEventTypes is a list of the event types. func AllEventTypes() []EventType { - return []EventType{BridgeRequestedEvent, BridgeRelayedEvent} + return []EventType{BridgeRequestedEvent, BridgeRelayedEvent, BridgeRefundedEvent, BridgeProvenEvent, BridgeClaimedEvent} } // Int gets the int value of the event type. diff --git a/services/explorer/types/fastbridge/eventtype_string.go b/services/explorer/types/fastbridge/eventtype_string.go index 7946ff1fde..27abbb2926 100644 --- a/services/explorer/types/fastbridge/eventtype_string.go +++ b/services/explorer/types/fastbridge/eventtype_string.go @@ -10,11 +10,14 @@ func _() { var x [1]struct{} _ = x[BridgeRequestedEvent-0] _ = x[BridgeRelayedEvent-1] + _ = x[BridgeRefundedEvent-2] + _ = x[BridgeProvenEvent-3] + _ = x[BridgeClaimedEvent-4] } -const _EventType_name = "BridgeRequestedEventBridgeRelayedEvent" +const _EventType_name = "BridgeRequestedEventBridgeRelayedEventBridgeRefundedEventBridgeProvenEventBridgeClaimedEvent" -var _EventType_index = [...]uint8{0, 20, 38} +var _EventType_index = [...]uint8{0, 20, 38, 57, 74, 92} func (i EventType) String() string { if i >= EventType(len(_EventType_index)-1) {