From dadc913d51f70f600c686945be6555ba8a4e63f9 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Wed, 9 Oct 2024 15:33:05 -0500 Subject: [PATCH 01/23] use gql api --- contrib/opbot/botmd/commands.go | 147 +++++++++---------------------- contrib/opbot/config/config.go | 2 + contrib/opbot/internal/client.go | 74 ++++++++++++++++ contrib/opbot/internal/model.go | 53 +++++++++++ 4 files changed, 172 insertions(+), 104 deletions(-) create mode 100644 contrib/opbot/internal/client.go create mode 100644 contrib/opbot/internal/model.go diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index b72f4ff7c2..fa289dd5b1 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -11,7 +11,6 @@ import ( "regexp" "sort" "strings" - "sync" "time" "github.com/dustin/go-humanize" @@ -21,10 +20,10 @@ import ( "github.com/hako/durafmt" "github.com/slack-go/slack" "github.com/slack-io/slacker" + "github.com/synapsecns/sanguine/contrib/opbot/internal" "github.com/synapsecns/sanguine/contrib/opbot/signoz" "github.com/synapsecns/sanguine/core/retry" "github.com/synapsecns/sanguine/ethergo/chaindata" - "github.com/synapsecns/sanguine/ethergo/client" "github.com/synapsecns/sanguine/ethergo/submitter" rfqClient "github.com/synapsecns/sanguine/services/rfq/api/client" "github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge" @@ -164,57 +163,14 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { "rfq 0x30f96b45ba689c809f7e936c140609eb31c99b182bef54fccf49778716a7e1ca", }, Handler: func(ctx *slacker.CommandContext) { - type Status struct { - relayer string - *relapi.GetQuoteRequestResponse - } - - var statuses []Status - var sliceMux sync.Mutex - - if len(b.cfg.RelayerURLS) == 0 { - _, err := ctx.Response().Reply("no relayer urls configured") - if err != nil { - log.Println(err) - } - return - } - tx := stripLinks(ctx.Request().Param("tx")) - var wg sync.WaitGroup - // 2 routines per relayer, one for tx hashh one for tx id - wg.Add(len(b.cfg.RelayerURLS) * 2) - for _, relayer := range b.cfg.RelayerURLS { - client := relapi.NewRelayerClient(b.handler, relayer) - go func() { - defer wg.Done() - res, err := client.GetQuoteRequestByTxHash(ctx.Context(), tx) - if err != nil { - log.Printf("error fetching quote request status by tx hash: %v\n", err) - return - } - sliceMux.Lock() - defer sliceMux.Unlock() - statuses = append(statuses, Status{relayer: relayer, GetQuoteRequestResponse: res}) - }() - - go func() { - defer wg.Done() - res, err := client.GetQuoteRequestByTXID(ctx.Context(), tx) - if err != nil { - log.Printf("error fetching quote request status by tx id: %v\n", err) - return - } - sliceMux.Lock() - defer sliceMux.Unlock() - statuses = append(statuses, Status{relayer: relayer, GetQuoteRequestResponse: res}) - }() - } - wg.Wait() + rfqClient := internal.NewRFQClient(b.handler, b.cfg.RFQIndexerAPIURL) - if len(statuses) == 0 { - _, err := ctx.Response().Reply("no quote request found") + res, status, err := rfqClient.GetRFQByTxID(ctx.Context(), tx) + if err != nil { + b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) + _, err := ctx.Response().Reply("error fetching quote request") if err != nil { log.Println(err) } @@ -223,51 +179,44 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { var slackBlocks []slack.Block - for _, status := range statuses { - client, err := b.rpcClient.GetChainClient(ctx.Context(), int(status.OriginChainID)) - if err != nil { - log.Printf("error getting chain client: %v\n", err) - } - - objects := []*slack.TextBlockObject{ - { - Type: slack.MarkdownType, - Text: fmt.Sprintf("*Relayer*: %s", status.relayer), - }, - { - Type: slack.MarkdownType, - Text: fmt.Sprintf("*Status*: %s", status.Status), - }, - { - Type: slack.MarkdownType, - Text: fmt.Sprintf("*TxID*: %s", toExplorerSlackLink(status.TxID)), - }, - { - Type: slack.MarkdownType, - Text: fmt.Sprintf("*OriginTxHash*: %s", toTXSlackLink(status.OriginTxHash, status.OriginChainID)), - }, - { - Type: slack.MarkdownType, - Text: fmt.Sprintf("*Estimated Tx Age*: %s", getTxAge(ctx.Context(), client, status.GetQuoteRequestResponse)), - }, - } - - if status.DestTxHash == (common.Hash{}).String() { - objects = append(objects, &slack.TextBlockObject{ - Type: slack.MarkdownType, - Text: "*DestTxHash*: not available", - }) - } else { - objects = append(objects, &slack.TextBlockObject{ - Type: slack.MarkdownType, - Text: fmt.Sprintf("*DestTxHash*: %s", toTXSlackLink(status.DestTxHash, status.DestChainID)), - }) - } + objects := []*slack.TextBlockObject{ + { + Type: slack.MarkdownType, + Text: fmt.Sprintf("*Relayer*: %s", res.BridgeRelay.Relayer), + }, + { + Type: slack.MarkdownType, + Text: fmt.Sprintf("*Status*: %s", status), + }, + { + Type: slack.MarkdownType, + Text: fmt.Sprintf("*TxID*: %s", toExplorerSlackLink(res.Bridge.TransactionID)), + }, + { + Type: slack.MarkdownType, + Text: fmt.Sprintf("*OriginTxHash*: %s", toTXSlackLink(res.BridgeRequest.TransactionHash, uint32(res.Bridge.OriginChainID))), + }, + { + Type: slack.MarkdownType, + Text: fmt.Sprintf("*Estimated Tx Age*: %s", getTxAge(res.BridgeRelay.BlockTimestamp)), + }, + } - slackBlocks = append(slackBlocks, slack.NewSectionBlock(nil, objects, nil)) + if status == "Requested" { + objects = append(objects, &slack.TextBlockObject{ + Type: slack.MarkdownType, + Text: "*DestTxHash*: not available", + }) + } else { + objects = append(objects, &slack.TextBlockObject{ + Type: slack.MarkdownType, + Text: fmt.Sprintf("*DestTxHash*: %s", toTXSlackLink(res.BridgeRelay.TransactionHash, uint32(res.Bridge.DestChainID))), + }) } - _, err := ctx.Response().ReplyBlocks(slackBlocks, slacker.WithUnfurlLinks(false)) + slackBlocks = append(slackBlocks, slack.NewSectionBlock(nil, objects, nil)) + + _, err = ctx.Response().ReplyBlocks(slackBlocks, slacker.WithUnfurlLinks(false)) if err != nil { log.Println(err) } @@ -405,18 +354,8 @@ func (b *Bot) makeFastBridge(ctx context.Context, req *relapi.GetQuoteRequestRes return fastBridgeHandle, nil } -func getTxAge(ctx context.Context, client client.EVM, res *relapi.GetQuoteRequestResponse) string { - // TODO: add CreatedAt field to GetQuoteRequestStatusResponse so we don't need to make network calls? - receipt, err := client.TransactionReceipt(ctx, common.HexToHash(res.OriginTxHash)) - if err != nil { - return "unknown time ago" - } - txBlock, err := client.HeaderByHash(ctx, receipt.BlockHash) - if err != nil { - return "unknown time ago" - } - - return humanize.Time(time.Unix(int64(txBlock.Time), 0)) +func getTxAge(timestamp int64) string { + return fmt.Sprintf("The block was created %s.\n", humanize.Time(time.Unix(timestamp, 0))) } func toExplorerSlackLink(ogHash string) string { diff --git a/contrib/opbot/config/config.go b/contrib/opbot/config/config.go index e9dde19453..0e52bb3e3c 100644 --- a/contrib/opbot/config/config.go +++ b/contrib/opbot/config/config.go @@ -38,6 +38,8 @@ type Config struct { ScreenerURL string `yaml:"screener_url"` // Database is the database config. Database DatabaseConfig `yaml:"database"` + // RFQIndexerAPIURL is the URL of the RFQ indexer API. + RFQIndexerAPIURL string `yaml:"rfq_indexer_api_url"` } // DatabaseConfig represents the configuration for the database. diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go new file mode 100644 index 0000000000..a3a4686905 --- /dev/null +++ b/contrib/opbot/internal/client.go @@ -0,0 +1,74 @@ +package internal + +import ( + "context" + "fmt" + "net/http" + + "github.com/dubonzi/otelresty" + "github.com/go-http-utils/headers" + "github.com/go-resty/resty/v2" + "github.com/synapsecns/sanguine/core/metrics" + "github.com/valyala/fastjson" +) + +const ( + getRequestByTxHash = "/api/transaction-id/%s" +) + +// GetRFQByTxIDResponse represents the response of a quote request by transaction ID. +type RFQClient interface { + // GetRFQByTxID gets a quote request by transaction ID. + GetRFQByTxID(ctx context.Context, txID string) (resp *GetRFQByTxIDResponse, status string, err error) +} + +type rfqClientImpl struct { + client *resty.Client +} + +// NewRFQClient creates a new RFQClient. +func NewRFQClient(handler metrics.Handler, url string) RFQClient { + client := resty.New() + client.SetBaseURL(url) + client.SetHeader(headers.UserAgent, "rfq-client") + + otelresty.TraceClient(client, otelresty.WithTracerProvider(handler.GetTracerProvider())) + + return &rfqClientImpl{ + client: client, + } +} + +// GetRFQByTxID gets a quote request by transaction ID. +func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQByTxIDResponse, string, error) { + var res GetRFQByTxIDResponse + resp, err := r.client.R().SetContext(ctx). + SetQueryParam("hash", txID). + SetResult(&res). + Get(fmt.Sprintf(getRequestByTxHash, txID)) + if err != nil { + return nil, "", fmt.Errorf("failed to get quote request by tx hash: %w", err) + } + + if resp.StatusCode() != http.StatusOK { + return nil, "", fmt.Errorf("unexpected status code: %d", resp.StatusCode()) + } + + var status string + if fastjson.GetString(resp.Body(), "BridgeClaim") != "" { + status = "Claimed" + } else if fastjson.GetString(resp.Body(), "BridgeProof") != "" { + status = "Proven" + } else if fastjson.GetString(resp.Body(), "BridgeRelay") != "" { + status = "Relayed" + } else if fastjson.GetString(resp.Body(), "BridgeRequest") != "" { + status = "Requested" + } else { + status = "Unknown" + } + + return &res, status, nil + +} + +var _ RFQClient = &rfqClientImpl{} diff --git a/contrib/opbot/internal/model.go b/contrib/opbot/internal/model.go new file mode 100644 index 0000000000..819129b57f --- /dev/null +++ b/contrib/opbot/internal/model.go @@ -0,0 +1,53 @@ +package internal + +type GetRFQByTxIDResponse struct { + Bridge Bridge `json:"Bridge"` + BridgeRequest BridgeRequest `json:"BridgeRequest"` + BridgeRelay BridgeRelay `json:"BridgeRelay"` + BridgeProof BridgeProof `json:"BridgeProof"` + BridgeClaim BridgeClaim `json:"BridgeClaim"` +} + +type Bridge struct { + TransactionID string `json:"transactionId"` + OriginChain string `json:"originChain"` + DestChain string `json:"destChain"` + OriginChainID int `json:"originChainId"` + DestChainID int `json:"destChainId"` + OriginToken string `json:"originToken"` + DestToken string `json:"destToken"` + OriginAmountFormatted string `json:"originAmountFormatted"` + DestAmountFormatted string `json:"destAmountFormatted"` + Sender string `json:"sender"` + SendChainGas int `json:"sendChainGas"` +} + +type BridgeRequest struct { + BlockNumber string `json:"blockNumber"` + BlockTimestamp int64 `json:"blockTimestamp"` + TransactionHash string `json:"transactionHash"` +} + +type BridgeRelay struct { + BlockNumber string `json:"blockNumber"` + BlockTimestamp int64 `json:"blockTimestamp"` + TransactionHash string `json:"transactionHash"` + Relayer string `json:"relayer"` + To string `json:"to"` +} + +type BridgeProof struct { + BlockNumber string `json:"blockNumber"` + BlockTimestamp int64 `json:"blockTimestamp"` + TransactionHash string `json:"transactionHash"` + Relayer string `json:"relayer"` +} + +type BridgeClaim struct { + BlockNumber string `json:"blockNumber"` + BlockTimestamp int64 `json:"blockTimestamp"` + TransactionHash string `json:"transactionHash"` + To string `json:"to"` + Relayer string `json:"relayer"` + AmountFormatted string `json:"amountFormatted"` +} From dccd63869d964481df7e55194567ba6077515d9e Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Wed, 9 Oct 2024 15:40:47 -0500 Subject: [PATCH 02/23] remove old test --- contrib/opbot/botmd/commands_test.go | 25 ------------------------- contrib/opbot/botmd/export_test.go | 11 ----------- contrib/opbot/go.mod | 2 +- 3 files changed, 1 insertion(+), 37 deletions(-) diff --git a/contrib/opbot/botmd/commands_test.go b/contrib/opbot/botmd/commands_test.go index b9ab0a39ee..6b5456094e 100644 --- a/contrib/opbot/botmd/commands_test.go +++ b/contrib/opbot/botmd/commands_test.go @@ -1,13 +1,9 @@ package botmd_test import ( - "context" "testing" "github.com/synapsecns/sanguine/contrib/opbot/botmd" - "github.com/synapsecns/sanguine/core/metrics" - omnirpcClient "github.com/synapsecns/sanguine/services/omnirpc/client" - "github.com/synapsecns/sanguine/services/rfq/relayer/relapi" ) func TestStripLinks(t *testing.T) { @@ -18,24 +14,3 @@ func TestStripLinks(t *testing.T) { t.Errorf("StripLinks(%s) = %s; want %s", testLink, got, expected) } } - -func TestTxAge(t *testing.T) { - notExpected := "unknown time ago" // should be a definite time - - status := &relapi.GetQuoteRequestResponse{ - OriginTxHash: "0x954264d120f5f3cf50edc39ebaf88ea9dc647d9d6843b7a120ed3677e23d7890", - OriginChainID: 421611, - } - - ctx := context.Background() - - client := omnirpcClient.NewOmnirpcClient("https://arb1.arbitrum.io/rpc", metrics.Get()) - cc, err := client.GetChainClient(ctx, int(status.OriginChainID)) - if err != nil { - t.Fatalf("GetChainClient() failed: %v", err) - } - - if got := botmd.GetTxAge(context.Background(), cc, status); got == notExpected { - t.Errorf("TxAge(%s) = %s; want not %s", status.OriginTxHash, got, notExpected) - } -} diff --git a/contrib/opbot/botmd/export_test.go b/contrib/opbot/botmd/export_test.go index 79b1e7a0f2..36a3ba400c 100644 --- a/contrib/opbot/botmd/export_test.go +++ b/contrib/opbot/botmd/export_test.go @@ -1,16 +1,5 @@ package botmd -import ( - "context" - - "github.com/synapsecns/sanguine/ethergo/client" - "github.com/synapsecns/sanguine/services/rfq/relayer/relapi" -) - func StripLinks(input string) string { return stripLinks(input) } - -func GetTxAge(ctx context.Context, client client.EVM, res *relapi.GetQuoteRequestResponse) string { - return getTxAge(ctx, client, res) -} diff --git a/contrib/opbot/go.mod b/contrib/opbot/go.mod index 70e9afa62e..9a098334b5 100644 --- a/contrib/opbot/go.mod +++ b/contrib/opbot/go.mod @@ -30,6 +30,7 @@ require ( github.com/synapsecns/sanguine/services/rfq v0.0.0-00010101000000-000000000000 github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.1 github.com/urfave/cli/v2 v2.27.2 + github.com/valyala/fastjson v1.6.4 golang.org/x/sync v0.8.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -242,7 +243,6 @@ require ( github.com/uptrace/opentelemetry-go-extra/otelgorm v0.3.1 // indirect github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.1 // indirect github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.1 // indirect - github.com/valyala/fastjson v1.6.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect From c1d21e47acadf2d77e28d1c6eddaf4344124d826 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 07:45:19 -0500 Subject: [PATCH 03/23] [goreleaser] --- contrib/opbot/botmd/botmd.go | 11 +++++--- contrib/opbot/botmd/commands.go | 43 ++++++++------------------------ contrib/opbot/go.mod | 2 +- contrib/opbot/internal/client.go | 42 +++++++++++++++++++++++-------- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/contrib/opbot/botmd/botmd.go b/contrib/opbot/botmd/botmd.go index 32ce34bfae..0d8c22f930 100644 --- a/contrib/opbot/botmd/botmd.go +++ b/contrib/opbot/botmd/botmd.go @@ -6,6 +6,7 @@ import ( "github.com/slack-io/slacker" "github.com/synapsecns/sanguine/contrib/opbot/config" + "github.com/synapsecns/sanguine/contrib/opbot/internal" "github.com/synapsecns/sanguine/contrib/opbot/signoz" screenerClient "github.com/synapsecns/sanguine/contrib/screener-api/client" "github.com/synapsecns/sanguine/core/dbcommon" @@ -29,6 +30,7 @@ type Bot struct { signozClient *signoz.Client signozEnabled bool rpcClient omnirpcClient.RPCClient + rfqClient internal.RFQClient signer signer.Signer submitter submitter.TransactionSubmitter screener screenerClient.ScreenerClient @@ -42,10 +44,11 @@ func NewBot(handler metrics.Handler, cfg config.Config) *Bot { sugaredLogger := otelzap.New(experimentalLogger.MakeZapLogger()).Sugar() bot := Bot{ - handler: handler, - cfg: cfg, - server: server, - logger: experimentalLogger.MakeWrappedSugaredLogger(sugaredLogger), + handler: handler, + cfg: cfg, + server: server, + logger: experimentalLogger.MakeWrappedSugaredLogger(sugaredLogger), + rfqClient: internal.NewRFQClient(handler, cfg.RFQIndexerAPIURL, cfg.RelayerURLS), } // you should be able to run opbot even without signoz. diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index fa289dd5b1..8aefb063cf 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -20,7 +20,6 @@ import ( "github.com/hako/durafmt" "github.com/slack-go/slack" "github.com/slack-io/slacker" - "github.com/synapsecns/sanguine/contrib/opbot/internal" "github.com/synapsecns/sanguine/contrib/opbot/signoz" "github.com/synapsecns/sanguine/core/retry" "github.com/synapsecns/sanguine/ethergo/chaindata" @@ -165,12 +164,10 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { Handler: func(ctx *slacker.CommandContext) { tx := stripLinks(ctx.Request().Param("tx")) - rfqClient := internal.NewRFQClient(b.handler, b.cfg.RFQIndexerAPIURL) - - res, status, err := rfqClient.GetRFQByTxID(ctx.Context(), tx) + res, status, err := b.rfqClient.GetRFQByTxID(ctx.Context(), tx) if err != nil { b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) - _, err := ctx.Response().Reply("error fetching quote request") + _, err := ctx.Response().Reply(fmt.Sprintf("error fetching quote request %s", err.Error())) if err != nil { log.Println(err) } @@ -241,16 +238,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { return } - var rawRequest *relapi.GetQuoteRequestResponse - var err error - var relClient relapi.RelayerClient - for _, relayer := range b.cfg.RelayerURLS { - relClient = relapi.NewRelayerClient(b.handler, relayer) - rawRequest, err = getQuoteRequest(ctx.Context(), relClient, tx) - if err == nil { - break - } - } + rawRequest, err := b.rfqClient.GetRFQByTxHash(ctx.Context(), tx) if err != nil { b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) _, err := ctx.Response().Reply("error fetching quote request") @@ -313,12 +301,14 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { ) if err != nil { b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) - _, err := ctx.Response().Reply(fmt.Sprintf("error fetching explorer link to refund, but nonce is %d", nonce)) - log.Printf("error fetching quote request: %v\n", err) + _, err := ctx.Response().Reply(fmt.Sprintf("refund submitted with nonce %d", nonce)) + if err != nil { + log.Println(err) + } return } - _, err = ctx.Response().Reply(fmt.Sprintf("refund submitted: %s", toExplorerSlackLink(status.TxHash().String()))) + _, err = ctx.Response().Reply(fmt.Sprintf("refund submitted: %s", toTXSlackLink(status.TxHash().String(), rawRequest.OriginChainID))) if err != nil { log.Println(err) } @@ -355,13 +345,13 @@ func (b *Bot) makeFastBridge(ctx context.Context, req *relapi.GetQuoteRequestRes } func getTxAge(timestamp int64) string { - return fmt.Sprintf("The block was created %s.\n", humanize.Time(time.Unix(timestamp, 0))) + return humanize.Time(time.Unix(timestamp, 0)) } func toExplorerSlackLink(ogHash string) string { rfqHash := strings.ToUpper(ogHash) // cut off 0x - if strings.HasPrefix(rfqHash, "0x") { + if strings.HasPrefix(rfqHash, "0X") { rfqHash = strings.ToLower(rfqHash[2:]) } @@ -383,16 +373,3 @@ func stripLinks(input string) string { linkRegex := regexp.MustCompile(`]+\|([^>]+)>`) return linkRegex.ReplaceAllString(input, "$1") } - -func getQuoteRequest(ctx context.Context, client relapi.RelayerClient, tx string) (qr *relapi.GetQuoteRequestResponse, err error) { - if qr, err = client.GetQuoteRequestByTxHash(ctx, tx); err == nil { - return qr, nil - } - - // look up quote request - if qr, err = client.GetQuoteRequestByTXID(ctx, tx); err == nil { - return qr, nil - } - - return nil, fmt.Errorf("error fetching quote request: %w", err) -} diff --git a/contrib/opbot/go.mod b/contrib/opbot/go.mod index 9a098334b5..70e9afa62e 100644 --- a/contrib/opbot/go.mod +++ b/contrib/opbot/go.mod @@ -30,7 +30,6 @@ require ( github.com/synapsecns/sanguine/services/rfq v0.0.0-00010101000000-000000000000 github.com/uptrace/opentelemetry-go-extra/otelzap v0.3.1 github.com/urfave/cli/v2 v2.27.2 - github.com/valyala/fastjson v1.6.4 golang.org/x/sync v0.8.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 @@ -243,6 +242,7 @@ require ( github.com/uptrace/opentelemetry-go-extra/otelgorm v0.3.1 // indirect github.com/uptrace/opentelemetry-go-extra/otelsql v0.3.1 // indirect github.com/uptrace/opentelemetry-go-extra/otelutil v0.3.1 // indirect + github.com/valyala/fastjson v1.6.4 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xrash/smetrics v0.0.0-20240312152122-5f08fbb34913 // indirect diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index a3a4686905..f3a886f3a5 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -9,7 +9,7 @@ import ( "github.com/go-http-utils/headers" "github.com/go-resty/resty/v2" "github.com/synapsecns/sanguine/core/metrics" - "github.com/valyala/fastjson" + "github.com/synapsecns/sanguine/services/rfq/relayer/relapi" ) const ( @@ -20,22 +20,31 @@ const ( type RFQClient interface { // GetRFQByTxID gets a quote request by transaction ID. GetRFQByTxID(ctx context.Context, txID string) (resp *GetRFQByTxIDResponse, status string, err error) + // GetRFQByTxHash gets a quote request by transaction hash. + GetRFQByTxHash(ctx context.Context, txHash string) (resp *relapi.GetQuoteRequestResponse, err error) } type rfqClientImpl struct { - client *resty.Client + client *resty.Client + relayerClients []relapi.RelayerClient } // NewRFQClient creates a new RFQClient. -func NewRFQClient(handler metrics.Handler, url string) RFQClient { +func NewRFQClient(handler metrics.Handler, indexerURL string, relayerURLs []string) RFQClient { client := resty.New() - client.SetBaseURL(url) + client.SetBaseURL(indexerURL) client.SetHeader(headers.UserAgent, "rfq-client") otelresty.TraceClient(client, otelresty.WithTracerProvider(handler.GetTracerProvider())) + var relayerClients []relapi.RelayerClient + for _, url := range relayerURLs { + relayerClients = append(relayerClients, relapi.NewRelayerClient(handler, url)) + } + return &rfqClientImpl{ - client: client, + client: client, + relayerClients: relayerClients, } } @@ -43,7 +52,6 @@ func NewRFQClient(handler metrics.Handler, url string) RFQClient { func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQByTxIDResponse, string, error) { var res GetRFQByTxIDResponse resp, err := r.client.R().SetContext(ctx). - SetQueryParam("hash", txID). SetResult(&res). Get(fmt.Sprintf(getRequestByTxHash, txID)) if err != nil { @@ -55,13 +63,13 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB } var status string - if fastjson.GetString(resp.Body(), "BridgeClaim") != "" { + if res.BridgeClaim != (BridgeClaim{}) { status = "Claimed" - } else if fastjson.GetString(resp.Body(), "BridgeProof") != "" { + } else if res.BridgeProof != (BridgeProof{}) { status = "Proven" - } else if fastjson.GetString(resp.Body(), "BridgeRelay") != "" { + } else if res.BridgeRelay != (BridgeRelay{}) { status = "Relayed" - } else if fastjson.GetString(resp.Body(), "BridgeRequest") != "" { + } else if res.BridgeRequest != (BridgeRequest{}) { status = "Requested" } else { status = "Unknown" @@ -71,4 +79,18 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB } +// GetRFQByTxHash gets a quote request by transaction hash. +func (r *rfqClientImpl) GetRFQByTxHash(ctx context.Context, txHash string) (*relapi.GetQuoteRequestResponse, error) { + var resp *relapi.GetQuoteRequestResponse + var err error + for _, relayerClient := range r.relayerClients { + resp, err = relayerClient.GetQuoteRequestByTxHash(ctx, txHash) + if err != nil { + return nil, fmt.Errorf("failed to get quote request by tx hash: %w", err) + } + } + + return resp, nil +} + var _ RFQClient = &rfqClientImpl{} From cd2187a2f170696f96c80cef86007c8351daa72e Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 07:47:00 -0500 Subject: [PATCH 04/23] fix lint[goreleaser] --- contrib/opbot/internal/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index f3a886f3a5..aa08899b08 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -16,7 +16,7 @@ const ( getRequestByTxHash = "/api/transaction-id/%s" ) -// GetRFQByTxIDResponse represents the response of a quote request by transaction ID. +// RFQClient is the interface for the RFQ client. type RFQClient interface { // GetRFQByTxID gets a quote request by transaction ID. GetRFQByTxID(ctx context.Context, txID string) (resp *GetRFQByTxIDResponse, status string, err error) From 8885dd53e6d610b707a3f96ba58ac9700de43979 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 08:22:00 -0500 Subject: [PATCH 05/23] [goreleaser] From 9dc780dcef7d0b62f972dc61560482cc832da558 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 08:35:26 -0500 Subject: [PATCH 06/23] fix lint [goreleaser] --- contrib/opbot/botmd/commands.go | 2 ++ contrib/opbot/internal/client.go | 13 +++++++------ contrib/opbot/internal/model.go | 6 ++++++ 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index 8aefb063cf..7c0785b856 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -191,6 +191,7 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { }, { Type: slack.MarkdownType, + //nolint: gosec Text: fmt.Sprintf("*OriginTxHash*: %s", toTXSlackLink(res.BridgeRequest.TransactionHash, uint32(res.Bridge.OriginChainID))), }, { @@ -205,6 +206,7 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { Text: "*DestTxHash*: not available", }) } else { + //nolint: gosec objects = append(objects, &slack.TextBlockObject{ Type: slack.MarkdownType, Text: fmt.Sprintf("*DestTxHash*: %s", toTXSlackLink(res.BridgeRelay.TransactionHash, uint32(res.Bridge.DestChainID))), diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index aa08899b08..c1072f6e9c 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -1,3 +1,4 @@ +// Package internal provides the RFQ client implementation. package internal import ( @@ -63,20 +64,20 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB } var status string - if res.BridgeClaim != (BridgeClaim{}) { + switch { + case res.BridgeClaim != (BridgeClaim{}): status = "Claimed" - } else if res.BridgeProof != (BridgeProof{}) { + case res.BridgeProof != (BridgeProof{}): status = "Proven" - } else if res.BridgeRelay != (BridgeRelay{}) { + case res.BridgeRelay != (BridgeRelay{}): status = "Relayed" - } else if res.BridgeRequest != (BridgeRequest{}) { + case res.BridgeRequest != (BridgeRequest{}): status = "Requested" - } else { + default: status = "Unknown" } return &res, status, nil - } // GetRFQByTxHash gets a quote request by transaction hash. diff --git a/contrib/opbot/internal/model.go b/contrib/opbot/internal/model.go index 819129b57f..9a1f944886 100644 --- a/contrib/opbot/internal/model.go +++ b/contrib/opbot/internal/model.go @@ -1,5 +1,6 @@ package internal +// GetRFQByTxIDResponse is the response for GetRFQByTxID. type GetRFQByTxIDResponse struct { Bridge Bridge `json:"Bridge"` BridgeRequest BridgeRequest `json:"BridgeRequest"` @@ -8,6 +9,7 @@ type GetRFQByTxIDResponse struct { BridgeClaim BridgeClaim `json:"BridgeClaim"` } +// Bridge contains the bridge information. type Bridge struct { TransactionID string `json:"transactionId"` OriginChain string `json:"originChain"` @@ -22,12 +24,14 @@ type Bridge struct { SendChainGas int `json:"sendChainGas"` } +// BridgeRequest contains the bridge request information. type BridgeRequest struct { BlockNumber string `json:"blockNumber"` BlockTimestamp int64 `json:"blockTimestamp"` TransactionHash string `json:"transactionHash"` } +// BridgeRelay contains the bridge relay information. type BridgeRelay struct { BlockNumber string `json:"blockNumber"` BlockTimestamp int64 `json:"blockTimestamp"` @@ -36,6 +40,7 @@ type BridgeRelay struct { To string `json:"to"` } +// BridgeProof contains the bridge proof information. type BridgeProof struct { BlockNumber string `json:"blockNumber"` BlockTimestamp int64 `json:"blockTimestamp"` @@ -43,6 +48,7 @@ type BridgeProof struct { Relayer string `json:"relayer"` } +// BridgeClaim contains the bridge claim information. type BridgeClaim struct { BlockNumber string `json:"blockNumber"` BlockTimestamp int64 `json:"blockTimestamp"` From 2ef3bbf3353dd70458d17191e58952612e0129b3 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 15:00:36 +0100 Subject: [PATCH 07/23] explorer UI updated --- packages/explorer-ui/components/ChainChart/index.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/explorer-ui/components/ChainChart/index.tsx b/packages/explorer-ui/components/ChainChart/index.tsx index a99f02dbb7..35ae42acb6 100644 --- a/packages/explorer-ui/components/ChainChart/index.tsx +++ b/packages/explorer-ui/components/ChainChart/index.tsx @@ -320,6 +320,12 @@ export const OverviewChart: React.FC = ({ stackId="a" fill={loading ? 'rgba(255, 255, 255, 0.1)' : '#000000'} /> + )} From 6cf146a9ca80e10d89bb98272c16d7c1e20d9926 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 15:03:08 +0100 Subject: [PATCH 08/23] rfq-indexer update --- .../api/src/constants/networkConfig.ts | 12 +++++++++ .../conflictingProofsController.ts | 2 +- .../api/src/controllers/disputesController.ts | 2 +- .../pendingTransactionsController.ts | 2 +- .../controllers/transactionIdController.ts | 4 +-- packages/rfq-indexer/indexer/.env.example | 2 +- packages/rfq-indexer/indexer/ponder.config.ts | 25 +++++++++++++++++++ .../rfq-indexer/indexer/src/utils/chains.ts | 1 + 8 files changed, 44 insertions(+), 6 deletions(-) diff --git a/packages/rfq-indexer/api/src/constants/networkConfig.ts b/packages/rfq-indexer/api/src/constants/networkConfig.ts index 8d2dc78e3f..579f8f7273 100644 --- a/packages/rfq-indexer/api/src/constants/networkConfig.ts +++ b/packages/rfq-indexer/api/src/constants/networkConfig.ts @@ -8,6 +8,7 @@ import { linea, bsc, blast, + worldchain, } from 'viem/chains' import { FastBridgeV2Abi } from './abis/FastBridgeV2' @@ -114,4 +115,15 @@ export const networkConfig: NetworkConfig = { transport: http(), }), }, + 480: { + name: 'Worldchain', + FastBridgeV2: { + address: '0x5523D3c98809DdDB82C686E152F5C58B1B0fB59E', + abi: FastBridgeV2Abi, + }, + client: createPublicClient({ + chain: worldchain, + transport: http(), + }), + }, } as const diff --git a/packages/rfq-indexer/api/src/controllers/conflictingProofsController.ts b/packages/rfq-indexer/api/src/controllers/conflictingProofsController.ts index 7f1de3137a..879473b32e 100644 --- a/packages/rfq-indexer/api/src/controllers/conflictingProofsController.ts +++ b/packages/rfq-indexer/api/src/controllers/conflictingProofsController.ts @@ -13,7 +13,7 @@ export const conflictingProofsController = async ( const query = db .with('deposits', () => qDeposits()) .with('relays', () => qRelays()) - .with('proofs', () => qProofs({activeOnly: true})) + .with('proofs', () => qProofs({ activeOnly: true })) .with('combined', (qb) => qb .selectFrom('deposits') diff --git a/packages/rfq-indexer/api/src/controllers/disputesController.ts b/packages/rfq-indexer/api/src/controllers/disputesController.ts index 2e65632c77..840d133db8 100644 --- a/packages/rfq-indexer/api/src/controllers/disputesController.ts +++ b/packages/rfq-indexer/api/src/controllers/disputesController.ts @@ -7,7 +7,7 @@ import { nest_results } from '../utils/nestResults' export const disputesController = async (req: Request, res: Response) => { try { const query = db - .with('disputes', () => qDisputes({activeOnly: true})) + .with('disputes', () => qDisputes({ activeOnly: true })) .selectFrom('disputes') .selectAll() .orderBy('blockTimestamp_dispute', 'desc') diff --git a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts index a2012c53c4..cf2d195f84 100644 --- a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts +++ b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts @@ -62,7 +62,7 @@ export const pendingTransactionsMissingProofController = async ( const query = db .with('deposits', () => qDeposits()) .with('relays', () => qRelays()) - .with('proofs', () => qProofs({activeOnly: true})) + .with('proofs', () => qProofs({ activeOnly: true })) .with('combined', (qb) => qb .selectFrom('deposits') diff --git a/packages/rfq-indexer/api/src/controllers/transactionIdController.ts b/packages/rfq-indexer/api/src/controllers/transactionIdController.ts index 586590220a..f389d06025 100644 --- a/packages/rfq-indexer/api/src/controllers/transactionIdController.ts +++ b/packages/rfq-indexer/api/src/controllers/transactionIdController.ts @@ -13,8 +13,8 @@ export const getTransactionById = async (req: Request, res: Response) => { qDeposits().where('transactionId', '=', transactionId as string) ) .with('relays', () => qRelays()) - .with('proofs', () => qProofs({activeOnly: false})) // display proofs even if they have been invalidated/replaced by a dispute - .with('disputes', () => qDisputes({activeOnly: true})) // do not show disputes that have been invalidated/replaced by a proof + .with('proofs', () => qProofs({ activeOnly: false })) // display proofs even if they have been invalidated/replaced by a dispute + .with('disputes', () => qDisputes({ activeOnly: true })) // do not show disputes that have been invalidated/replaced by a proof .with('claims', () => qClaims()) .with('refunds', () => qRefunds()) .with('combined', (qb) => diff --git a/packages/rfq-indexer/indexer/.env.example b/packages/rfq-indexer/indexer/.env.example index 33ca569c2c..b1361bc84e 100644 --- a/packages/rfq-indexer/indexer/.env.example +++ b/packages/rfq-indexer/indexer/.env.example @@ -8,7 +8,7 @@ BLAST_MAINNET_RPC= SCROLL_MAINNET_RPC= LINEA_MAINNET_RPC= BNB_MAINNET_RPC= +WORLDCHAIN_MAINNET_RPC= # (Optional) Postgres database URL. If not provided, SQLite will be used. DATABASE_URL= - \ No newline at end of file diff --git a/packages/rfq-indexer/indexer/ponder.config.ts b/packages/rfq-indexer/indexer/ponder.config.ts index df73b39d5e..edfea0e144 100644 --- a/packages/rfq-indexer/indexer/ponder.config.ts +++ b/packages/rfq-indexer/indexer/ponder.config.ts @@ -13,6 +13,7 @@ const blastChainId = 81457 const scrollChainId = 534352 const lineaChainId = 59144 const bnbChainId = 56 +const worldchainChainId = 480 const configByChainId = { [1]: { @@ -69,6 +70,12 @@ const configByChainId = { FastBridgeV2Address: '0x5523D3c98809DdDB82C686E152F5C58B1B0fB59E', FastBridgeV2StartBlock: 40497843, // first block and new block }, + [480]: { + transport: http(process.env.WORLDCHAIN_MAINNET_RPC), + chainName: 'worldchain', + FastBridgeV2Address: '0x5523D3c98809DdDB82C686E152F5C58B1B0fB59E', + FastBridgeV2StartBlock: 4616214, // first block and new block + }, disableCache: true, } @@ -137,6 +144,14 @@ export const networkDetails = { startBlock: configByChainId[bnbChainId].FastBridgeV2StartBlock, }, }, + [worldchainChainId]: { + name: configByChainId[worldchainChainId].chainName, + FastBridgeV2: { + address: configByChainId[worldchainChainId].FastBridgeV2Address, + abi: FastBridgeV2Abi, + startBlock: configByChainId[worldchainChainId].FastBridgeV2StartBlock, + }, + }, } as Record const config = createConfig({ @@ -181,6 +196,11 @@ const config = createConfig({ transport: configByChainId[bnbChainId].transport, // disableCache: configByChainId.disableCache, }, + [configByChainId[worldchainChainId].chainName]: { + chainId: worldchainChainId, + transport: configByChainId[worldchainChainId].transport, + // disableCache: configByChainId.disableCache, + }, }, contracts: { FastBridgeV2: { @@ -217,6 +237,11 @@ const config = createConfig({ address: networkDetails[bnbChainId]?.FastBridgeV2.address, startBlock: networkDetails[bnbChainId]?.FastBridgeV2.startBlock, }, + [configByChainId[worldchainChainId].chainName]: { + address: networkDetails[worldchainChainId]?.FastBridgeV2.address, + startBlock: + networkDetails[worldchainChainId]?.FastBridgeV2.startBlock, + }, }, abi: FastBridgeV2Abi, }, diff --git a/packages/rfq-indexer/indexer/src/utils/chains.ts b/packages/rfq-indexer/indexer/src/utils/chains.ts index e521f65def..121f48c546 100644 --- a/packages/rfq-indexer/indexer/src/utils/chains.ts +++ b/packages/rfq-indexer/indexer/src/utils/chains.ts @@ -7,6 +7,7 @@ export const chainIdToName: { [key: number]: string } = { 534352: 'scroll', 59144: 'linea', 56: 'bnb', + 480: 'worldchain', } export const getChainName = (chainId: number): string => { From 451a2d7df892e12085851d3503f7bd6d36da11d0 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 15:03:33 +0100 Subject: [PATCH 09/23] explorer backend update --- services/explorer/api/server_test.go | 49 ++++----- .../consumer/parser/tokendata/cache.go | 5 + services/explorer/graphql/client/client.go | 50 ++++----- .../graphql/client/queries/queries.graphql | 1 + .../graphql/server/graph/model/models_gen.go | 49 ++++----- .../explorer/graphql/server/graph/partials.go | 6 ++ .../graphql/server/graph/resolver/server.go | 102 +++++++++++++----- .../graphql/server/graph/schema/types.graphql | 1 + services/explorer/static/chainIDs.yaml | 1 + .../explorer/static/tokenIDToCoinGeckoID.yaml | 1 + .../static/tokenSymbolToCoinGeckoID.yaml | 1 + .../explorer/static/tokenSymbolToTokenID.yaml | 1 + 12 files changed, 171 insertions(+), 96 deletions(-) diff --git a/services/explorer/api/server_test.go b/services/explorer/api/server_test.go index 6a5a0b27df..1125854ecb 100644 --- a/services/explorer/api/server_test.go +++ b/services/explorer/api/server_test.go @@ -35,30 +35,31 @@ func TestHandleJSONDailyStat(t *testing.T) { // nolint valueStruct := gqlClient.GetDailyStatisticsByChain{ Response: []*struct { - Date *string "json:\"date\" graphql:\"date\"" - Ethereum *float64 "json:\"ethereum\" graphql:\"ethereum\"" - Optimism *float64 "json:\"optimism\" graphql:\"optimism\"" - Cronos *float64 "json:\"cronos\" graphql:\"cronos\"" - Bsc *float64 "json:\"bsc\" graphql:\"bsc\"" - Polygon *float64 "json:\"polygon\" graphql:\"polygon\"" - Fantom *float64 "json:\"fantom\" graphql:\"fantom\"" - Boba *float64 "json:\"boba\" graphql:\"boba\"" - Metis *float64 "json:\"metis\" graphql:\"metis\"" - Moonbeam *float64 "json:\"moonbeam\" graphql:\"moonbeam\"" - Moonriver *float64 "json:\"moonriver\" graphql:\"moonriver\"" - Klaytn *float64 "json:\"klaytn\" graphql:\"klaytn\"" - Arbitrum *float64 "json:\"arbitrum\" graphql:\"arbitrum\"" - Avalanche *float64 "json:\"avalanche\" graphql:\"avalanche\"" - Dfk *float64 "json:\"dfk\" graphql:\"dfk\"" - Aurora *float64 "json:\"aurora\" graphql:\"aurora\"" - Harmony *float64 "json:\"harmony\" graphql:\"harmony\"" - Canto *float64 "json:\"canto\" graphql:\"canto\"" - Dogechain *float64 "json:\"dogechain\" graphql:\"dogechain\"" - Base *float64 "json:\"base\" graphql:\"base\"" - Blast *float64 "json:\"blast\" graphql:\"blast\"" - Scroll *float64 "json:\"scroll\" graphql:\"scroll\"" - Linea *float64 "json:\"linea\" graphql:\"linea\"" - Total *float64 "json:\"total\" graphql:\"total\"" + Date *string "json:\"date\" graphql:\"date\"" + Ethereum *float64 "json:\"ethereum\" graphql:\"ethereum\"" + Optimism *float64 "json:\"optimism\" graphql:\"optimism\"" + Cronos *float64 "json:\"cronos\" graphql:\"cronos\"" + Bsc *float64 "json:\"bsc\" graphql:\"bsc\"" + Polygon *float64 "json:\"polygon\" graphql:\"polygon\"" + Fantom *float64 "json:\"fantom\" graphql:\"fantom\"" + Boba *float64 "json:\"boba\" graphql:\"boba\"" + Metis *float64 "json:\"metis\" graphql:\"metis\"" + Moonbeam *float64 "json:\"moonbeam\" graphql:\"moonbeam\"" + Moonriver *float64 "json:\"moonriver\" graphql:\"moonriver\"" + Klaytn *float64 "json:\"klaytn\" graphql:\"klaytn\"" + Arbitrum *float64 "json:\"arbitrum\" graphql:\"arbitrum\"" + Avalanche *float64 "json:\"avalanche\" graphql:\"avalanche\"" + Dfk *float64 "json:\"dfk\" graphql:\"dfk\"" + Aurora *float64 "json:\"aurora\" graphql:\"aurora\"" + Harmony *float64 "json:\"harmony\" graphql:\"harmony\"" + Canto *float64 "json:\"canto\" graphql:\"canto\"" + Dogechain *float64 "json:\"dogechain\" graphql:\"dogechain\"" + Base *float64 "json:\"base\" graphql:\"base\"" + Blast *float64 "json:\"blast\" graphql:\"blast\"" + Scroll *float64 "json:\"scroll\" graphql:\"scroll\"" + Linea *float64 "json:\"linea\" graphql:\"linea\"" + Worldchain *float64 "json:\"worldchain\" graphql:\"worldchain\"" + Total *float64 "json:\"total\" graphql:\"total\"" }{ { Total: &valueFloat, diff --git a/services/explorer/consumer/parser/tokendata/cache.go b/services/explorer/consumer/parser/tokendata/cache.go index ab52591c94..b9eb33e54b 100644 --- a/services/explorer/consumer/parser/tokendata/cache.go +++ b/services/explorer/consumer/parser/tokendata/cache.go @@ -287,5 +287,10 @@ var tokenDataMap = map[string]TokenData{ "8453_0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb": {"DAI", 18, "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb"}, "1_0xAdF7C35560035944e805D98fF17d58CDe2449389": {"SPEC", 18, "0xAdF7C35560035944e805D98fF17d58CDe2449389"}, "8453_0x96419929d7949D6A801A6909c145C8EEf6A40431": {"SPEC", 18, "0x96419929d7949D6A801A6909c145C8EEf6A40431"}, + "480_0x2cFc85d8E48F8EAB294be644d9E25C3030863003": {"WLD", 18, "0x2cFc85d8E48F8EAB294be644d9E25C3030863003"}, + "10_0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1": {"WLD", 18, "0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1"}, + "480_0x79A02482A880bCE3F13e09Da970dC34db4CD24d1": {"USDC.e", 6, "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1"}, + "480_0x4200000000000000000000000000000000000006": {"WETH", 18, "0x4200000000000000000000000000000000000006"}, + "1_0x163f8c2467924be0ae7b5347228cabf260318753": {"WLD", 18, "0x163f8c2467924be0ae7b5347228cabf260318753"}, // Add additional tokens that are not part of the cache yet (and not by nature in bridge config) here } diff --git a/services/explorer/graphql/client/client.go b/services/explorer/graphql/client/client.go index 04f5498f6d..704c82de6b 100644 --- a/services/explorer/graphql/client/client.go +++ b/services/explorer/graphql/client/client.go @@ -106,30 +106,31 @@ type GetAmountStatistic struct { } type GetDailyStatisticsByChain struct { Response []*struct { - Date *string "json:\"date\" graphql:\"date\"" - Ethereum *float64 "json:\"ethereum\" graphql:\"ethereum\"" - Optimism *float64 "json:\"optimism\" graphql:\"optimism\"" - Cronos *float64 "json:\"cronos\" graphql:\"cronos\"" - Bsc *float64 "json:\"bsc\" graphql:\"bsc\"" - Polygon *float64 "json:\"polygon\" graphql:\"polygon\"" - Fantom *float64 "json:\"fantom\" graphql:\"fantom\"" - Boba *float64 "json:\"boba\" graphql:\"boba\"" - Metis *float64 "json:\"metis\" graphql:\"metis\"" - Moonbeam *float64 "json:\"moonbeam\" graphql:\"moonbeam\"" - Moonriver *float64 "json:\"moonriver\" graphql:\"moonriver\"" - Klaytn *float64 "json:\"klaytn\" graphql:\"klaytn\"" - Arbitrum *float64 "json:\"arbitrum\" graphql:\"arbitrum\"" - Avalanche *float64 "json:\"avalanche\" graphql:\"avalanche\"" - Dfk *float64 "json:\"dfk\" graphql:\"dfk\"" - Aurora *float64 "json:\"aurora\" graphql:\"aurora\"" - Harmony *float64 "json:\"harmony\" graphql:\"harmony\"" - Canto *float64 "json:\"canto\" graphql:\"canto\"" - Dogechain *float64 "json:\"dogechain\" graphql:\"dogechain\"" - Base *float64 "json:\"base\" graphql:\"base\"" - Blast *float64 "json:\"blast\" graphql:\"blast\"" - Scroll *float64 "json:\"scroll\" graphql:\"scroll\"" - Linea *float64 "json:\"linea\" graphql:\"linea\"" - Total *float64 "json:\"total\" graphql:\"total\"" + Date *string "json:\"date\" graphql:\"date\"" + Ethereum *float64 "json:\"ethereum\" graphql:\"ethereum\"" + Optimism *float64 "json:\"optimism\" graphql:\"optimism\"" + Cronos *float64 "json:\"cronos\" graphql:\"cronos\"" + Bsc *float64 "json:\"bsc\" graphql:\"bsc\"" + Polygon *float64 "json:\"polygon\" graphql:\"polygon\"" + Fantom *float64 "json:\"fantom\" graphql:\"fantom\"" + Boba *float64 "json:\"boba\" graphql:\"boba\"" + Metis *float64 "json:\"metis\" graphql:\"metis\"" + Moonbeam *float64 "json:\"moonbeam\" graphql:\"moonbeam\"" + Moonriver *float64 "json:\"moonriver\" graphql:\"moonriver\"" + Klaytn *float64 "json:\"klaytn\" graphql:\"klaytn\"" + Arbitrum *float64 "json:\"arbitrum\" graphql:\"arbitrum\"" + Avalanche *float64 "json:\"avalanche\" graphql:\"avalanche\"" + Dfk *float64 "json:\"dfk\" graphql:\"dfk\"" + Aurora *float64 "json:\"aurora\" graphql:\"aurora\"" + Harmony *float64 "json:\"harmony\" graphql:\"harmony\"" + Canto *float64 "json:\"canto\" graphql:\"canto\"" + Dogechain *float64 "json:\"dogechain\" graphql:\"dogechain\"" + Base *float64 "json:\"base\" graphql:\"base\"" + Blast *float64 "json:\"blast\" graphql:\"blast\"" + Scroll *float64 "json:\"scroll\" graphql:\"scroll\"" + Linea *float64 "json:\"linea\" graphql:\"linea\"" + Worldchain *float64 "json:\"worldchain\" graphql:\"worldchain\"" + Total *float64 "json:\"total\" graphql:\"total\"" } "json:\"response\" graphql:\"response\"" } type GetMessageBusTransactions struct { @@ -502,6 +503,7 @@ const GetDailyStatisticsByChainDocument = `query GetDailyStatisticsByChain ($cha blast scroll linea + worldchain total } } diff --git a/services/explorer/graphql/client/queries/queries.graphql b/services/explorer/graphql/client/queries/queries.graphql index 60eb3d63eb..3d351f3cc1 100644 --- a/services/explorer/graphql/client/queries/queries.graphql +++ b/services/explorer/graphql/client/queries/queries.graphql @@ -155,6 +155,7 @@ query GetDailyStatisticsByChain($chainID: Int, $type: DailyStatisticType, $durat blast scroll linea + worldchain total } } diff --git a/services/explorer/graphql/server/graph/model/models_gen.go b/services/explorer/graphql/server/graph/model/models_gen.go index d3eeb60af4..c090c167e4 100644 --- a/services/explorer/graphql/server/graph/model/models_gen.go +++ b/services/explorer/graphql/server/graph/model/models_gen.go @@ -81,30 +81,31 @@ type DateResult struct { // DateResult is a given statistic for a given date. type DateResultByChain struct { - Date *string `json:"date,omitempty"` - Ethereum *float64 `json:"ethereum,omitempty"` - Optimism *float64 `json:"optimism,omitempty"` - Cronos *float64 `json:"cronos,omitempty"` - Bsc *float64 `json:"bsc,omitempty"` - Polygon *float64 `json:"polygon,omitempty"` - Fantom *float64 `json:"fantom,omitempty"` - Boba *float64 `json:"boba,omitempty"` - Metis *float64 `json:"metis,omitempty"` - Moonbeam *float64 `json:"moonbeam,omitempty"` - Moonriver *float64 `json:"moonriver,omitempty"` - Klaytn *float64 `json:"klaytn,omitempty"` - Arbitrum *float64 `json:"arbitrum,omitempty"` - Avalanche *float64 `json:"avalanche,omitempty"` - Dfk *float64 `json:"dfk,omitempty"` - Aurora *float64 `json:"aurora,omitempty"` - Harmony *float64 `json:"harmony,omitempty"` - Canto *float64 `json:"canto,omitempty"` - Dogechain *float64 `json:"dogechain,omitempty"` - Base *float64 `json:"base,omitempty"` - Blast *float64 `json:"blast,omitempty"` - Scroll *float64 `json:"scroll,omitempty"` - Linea *float64 `json:"linea,omitempty"` - Total *float64 `json:"total,omitempty"` + Date *string `json:"date,omitempty"` + Ethereum *float64 `json:"ethereum,omitempty"` + Optimism *float64 `json:"optimism,omitempty"` + Cronos *float64 `json:"cronos,omitempty"` + Bsc *float64 `json:"bsc,omitempty"` + Polygon *float64 `json:"polygon,omitempty"` + Fantom *float64 `json:"fantom,omitempty"` + Boba *float64 `json:"boba,omitempty"` + Metis *float64 `json:"metis,omitempty"` + Moonbeam *float64 `json:"moonbeam,omitempty"` + Moonriver *float64 `json:"moonriver,omitempty"` + Klaytn *float64 `json:"klaytn,omitempty"` + Arbitrum *float64 `json:"arbitrum,omitempty"` + Avalanche *float64 `json:"avalanche,omitempty"` + Dfk *float64 `json:"dfk,omitempty"` + Aurora *float64 `json:"aurora,omitempty"` + Harmony *float64 `json:"harmony,omitempty"` + Canto *float64 `json:"canto,omitempty"` + Dogechain *float64 `json:"dogechain,omitempty"` + Base *float64 `json:"base,omitempty"` + Blast *float64 `json:"blast,omitempty"` + Scroll *float64 `json:"scroll,omitempty"` + Linea *float64 `json:"linea,omitempty"` + Worldchain *float64 `json:"worldchain,omitempty"` + Total *float64 `json:"total,omitempty"` } type HeroType struct { diff --git a/services/explorer/graphql/server/graph/partials.go b/services/explorer/graphql/server/graph/partials.go index 85519e442b..da436a4096 100644 --- a/services/explorer/graphql/server/graph/partials.go +++ b/services/explorer/graphql/server/graph/partials.go @@ -401,6 +401,7 @@ const dailyVolumeBridgeMvPt1 = ` results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM (SELECT date, maxMap(map(chain_id, total)) AS results FROM (SELECT coalesce(toString(b.date), toString(s.date)) AS date, @@ -445,6 +446,7 @@ const dailyVolumeBridge = ` results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM (SELECT date, maxMap(map(chain_id, total)) AS results FROM (SELECT coalesce(toString(b.date), toString(s.date)) AS date, @@ -541,6 +543,7 @@ SELECT date, results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM (SELECT date, maxMap(map(chain_id, total)) AS results FROM (SELECT coalesce(toString(b.date), toString(s.date), toString(m.date)) AS date, @@ -643,6 +646,7 @@ SELECT date, results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM ( SELECT date, @@ -674,6 +678,7 @@ SELECT date, results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM ( SELECT date, @@ -706,6 +711,7 @@ SELECT date, results[81457] AS blast, results[534352] AS scroll, results[59144] AS linea, + results[480] AS worldchain, arraySum(mapValues(results)) AS total FROM ( SELECT date, diff --git a/services/explorer/graphql/server/graph/resolver/server.go b/services/explorer/graphql/server/graph/resolver/server.go index 8abe58001c..29689da5c4 100644 --- a/services/explorer/graphql/server/graph/resolver/server.go +++ b/services/explorer/graphql/server/graph/resolver/server.go @@ -100,30 +100,31 @@ type ComplexityRoot struct { } DateResultByChain struct { - Arbitrum func(childComplexity int) int - Aurora func(childComplexity int) int - Avalanche func(childComplexity int) int - Base func(childComplexity int) int - Blast func(childComplexity int) int - Boba func(childComplexity int) int - Bsc func(childComplexity int) int - Canto func(childComplexity int) int - Cronos func(childComplexity int) int - Date func(childComplexity int) int - Dfk func(childComplexity int) int - Dogechain func(childComplexity int) int - Ethereum func(childComplexity int) int - Fantom func(childComplexity int) int - Harmony func(childComplexity int) int - Klaytn func(childComplexity int) int - Linea func(childComplexity int) int - Metis func(childComplexity int) int - Moonbeam func(childComplexity int) int - Moonriver func(childComplexity int) int - Optimism func(childComplexity int) int - Polygon func(childComplexity int) int - Scroll func(childComplexity int) int - Total func(childComplexity int) int + Arbitrum func(childComplexity int) int + Aurora func(childComplexity int) int + Avalanche func(childComplexity int) int + Base func(childComplexity int) int + Blast func(childComplexity int) int + Boba func(childComplexity int) int + Bsc func(childComplexity int) int + Canto func(childComplexity int) int + Cronos func(childComplexity int) int + Date func(childComplexity int) int + Dfk func(childComplexity int) int + Dogechain func(childComplexity int) int + Ethereum func(childComplexity int) int + Fantom func(childComplexity int) int + Harmony func(childComplexity int) int + Klaytn func(childComplexity int) int + Linea func(childComplexity int) int + Metis func(childComplexity int) int + Moonbeam func(childComplexity int) int + Moonriver func(childComplexity int) int + Optimism func(childComplexity int) int + Polygon func(childComplexity int) int + Scroll func(childComplexity int) int + Total func(childComplexity int) int + Worldchain func(childComplexity int) int } HeroType struct { @@ -660,6 +661,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.DateResultByChain.Total(childComplexity), true + case "DateResultByChain.worldchain": + if e.complexity.DateResultByChain.Worldchain == nil { + break + } + + return e.complexity.DateResultByChain.Worldchain(childComplexity), true + case "HeroType.heroID": if e.complexity.HeroType.HeroID == nil { break @@ -1664,6 +1672,7 @@ type DateResultByChain { blast: Float scroll: Float linea: Float + worldchain: Float total: Float } @@ -4832,6 +4841,47 @@ func (ec *executionContext) fieldContext_DateResultByChain_linea(ctx context.Con return fc, nil } +func (ec *executionContext) _DateResultByChain_worldchain(ctx context.Context, field graphql.CollectedField, obj *model.DateResultByChain) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_DateResultByChain_worldchain(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.Worldchain, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*float64) + fc.Result = res + return ec.marshalOFloat2ᚖfloat64(ctx, field.Selections, res) +} + +func (ec *executionContext) fieldContext_DateResultByChain_worldchain(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DateResultByChain", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Float does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _DateResultByChain_total(ctx context.Context, field graphql.CollectedField, obj *model.DateResultByChain) (ret graphql.Marshaler) { fc, err := ec.fieldContext_DateResultByChain_total(ctx, field) if err != nil { @@ -7190,6 +7240,8 @@ func (ec *executionContext) fieldContext_Query_dailyStatisticsByChain(ctx contex return ec.fieldContext_DateResultByChain_scroll(ctx, field) case "linea": return ec.fieldContext_DateResultByChain_linea(ctx, field) + case "worldchain": + return ec.fieldContext_DateResultByChain_worldchain(ctx, field) case "total": return ec.fieldContext_DateResultByChain_total(ctx, field) } @@ -10434,6 +10486,8 @@ func (ec *executionContext) _DateResultByChain(ctx context.Context, sel ast.Sele out.Values[i] = ec._DateResultByChain_scroll(ctx, field, obj) case "linea": out.Values[i] = ec._DateResultByChain_linea(ctx, field, obj) + case "worldchain": + out.Values[i] = ec._DateResultByChain_worldchain(ctx, field, obj) case "total": out.Values[i] = ec._DateResultByChain_total(ctx, field, obj) default: diff --git a/services/explorer/graphql/server/graph/schema/types.graphql b/services/explorer/graphql/server/graph/schema/types.graphql index 9b8bebdbd0..084c2da036 100644 --- a/services/explorer/graphql/server/graph/schema/types.graphql +++ b/services/explorer/graphql/server/graph/schema/types.graphql @@ -180,6 +180,7 @@ type DateResultByChain { blast: Float scroll: Float linea: Float + worldchain: Float total: Float } diff --git a/services/explorer/static/chainIDs.yaml b/services/explorer/static/chainIDs.yaml index 84add22b21..250c5db0a6 100644 --- a/services/explorer/static/chainIDs.yaml +++ b/services/explorer/static/chainIDs.yaml @@ -19,3 +19,4 @@ 81457: 'Blast' 534352: 'Scroll' 59144: 'Linea' +480: 'Worldchain' diff --git a/services/explorer/static/tokenIDToCoinGeckoID.yaml b/services/explorer/static/tokenIDToCoinGeckoID.yaml index 6c618da717..574cc7edc8 100644 --- a/services/explorer/static/tokenIDToCoinGeckoID.yaml +++ b/services/explorer/static/tokenIDToCoinGeckoID.yaml @@ -40,3 +40,4 @@ USDbC: 'usd-coin' crvUSD: 'usd-coin' USDB: 'usdb' SPEC: 'spectral' +WLD: 'worldcoin' diff --git a/services/explorer/static/tokenSymbolToCoinGeckoID.yaml b/services/explorer/static/tokenSymbolToCoinGeckoID.yaml index 231aa8ef74..6288259e8d 100644 --- a/services/explorer/static/tokenSymbolToCoinGeckoID.yaml +++ b/services/explorer/static/tokenSymbolToCoinGeckoID.yaml @@ -40,3 +40,4 @@ usdbc: 'usd-coin' crvusd: 'usd-coin' usdb: 'usdb' spec: 'spectral' +wld: 'worldcoin' diff --git a/services/explorer/static/tokenSymbolToTokenID.yaml b/services/explorer/static/tokenSymbolToTokenID.yaml index 83bac16402..eaf7f01c7d 100644 --- a/services/explorer/static/tokenSymbolToTokenID.yaml +++ b/services/explorer/static/tokenSymbolToTokenID.yaml @@ -42,3 +42,4 @@ usdbc: 'usd-coin' crvusd: 'usd-coin' usdb: 'usdb' spec: 'spectral' +wld: 'worldcoin' From 6c0251712ed39e30ac93e1344a9aa051cba0fa29 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 15:09:35 +0100 Subject: [PATCH 10/23] [goreleaser] trigger explorer version bump --- services/explorer/consumer/parser/tokendata/cache.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/explorer/consumer/parser/tokendata/cache.go b/services/explorer/consumer/parser/tokendata/cache.go index b9eb33e54b..aaf76877e2 100644 --- a/services/explorer/consumer/parser/tokendata/cache.go +++ b/services/explorer/consumer/parser/tokendata/cache.go @@ -292,5 +292,5 @@ var tokenDataMap = map[string]TokenData{ "480_0x79A02482A880bCE3F13e09Da970dC34db4CD24d1": {"USDC.e", 6, "0x79A02482A880bCE3F13e09Da970dC34db4CD24d1"}, "480_0x4200000000000000000000000000000000000006": {"WETH", 18, "0x4200000000000000000000000000000000000006"}, "1_0x163f8c2467924be0ae7b5347228cabf260318753": {"WLD", 18, "0x163f8c2467924be0ae7b5347228cabf260318753"}, - // Add additional tokens that are not part of the cache yet (and not by nature in bridge config) here + // Add additional tokens that are not part of the cache yet (and is not by nature in bridge config) here } From a932e29b1ace9611d091edb8ab6b922fd4ff337e Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 16:55:21 +0100 Subject: [PATCH 11/23] rfq indexer with the right contracts --- .../controllers/pendingTransactionsController.ts | 11 ++--------- .../src/controllers/transactionIdController.ts | 15 +++++++++++++-- packages/rfq-indexer/indexer/ponder.config.ts | 4 ++-- 3 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts index cf2d195f84..0cbb2defa8 100644 --- a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts +++ b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts @@ -1,14 +1,7 @@ import { Request, Response } from 'express' import { db } from '../db' -import { - qDeposits, - qRelays, - qProofs, - qClaims, - qRefunds, - qDisputes, -} from '../queries' +import { qDeposits, qRelays, qProofs, qClaims, qRefunds } from '../queries' import { nest_results } from '../utils/nestResults' const sevenDaysAgo = Math.floor(Date.now() / 1000) - 7 * 24 * 60 * 60 @@ -21,7 +14,7 @@ export const pendingTransactionsMissingClaimController = async ( const query = db .with('deposits', () => qDeposits()) .with('relays', () => qRelays()) - .with('proofs', () => qProofs({activeOnly: true})) + .with('proofs', () => qProofs({ activeOnly: true })) .with('claims', () => qClaims()) .with('combined', (qb) => qb diff --git a/packages/rfq-indexer/api/src/controllers/transactionIdController.ts b/packages/rfq-indexer/api/src/controllers/transactionIdController.ts index f389d06025..578020ef1a 100644 --- a/packages/rfq-indexer/api/src/controllers/transactionIdController.ts +++ b/packages/rfq-indexer/api/src/controllers/transactionIdController.ts @@ -1,7 +1,14 @@ import { Request, Response } from 'express' import { db } from '../db' -import { qDeposits, qRelays, qProofs, qClaims, qRefunds, qDisputes } from '../queries' +import { + qDeposits, + qRelays, + qProofs, + qClaims, + qRefunds, + qDisputes, +} from '../queries' import { nest_results } from '../utils/nestResults' export const getTransactionById = async (req: Request, res: Response) => { @@ -22,7 +29,11 @@ export const getTransactionById = async (req: Request, res: Response) => { .selectFrom('deposits') .leftJoin('relays', 'transactionId_deposit', 'transactionId_relay') .leftJoin('proofs', 'transactionId_deposit', 'transactionId_proof') - .leftJoin('disputes', 'transactionId_deposit', 'transactionId_dispute') + .leftJoin( + 'disputes', + 'transactionId_deposit', + 'transactionId_dispute' + ) .leftJoin('claims', 'transactionId_deposit', 'transactionId_claim') .leftJoin('refunds', 'transactionId_deposit', 'transactionId_refund') .selectAll('deposits') diff --git a/packages/rfq-indexer/indexer/ponder.config.ts b/packages/rfq-indexer/indexer/ponder.config.ts index edfea0e144..2329d0e89f 100644 --- a/packages/rfq-indexer/indexer/ponder.config.ts +++ b/packages/rfq-indexer/indexer/ponder.config.ts @@ -73,8 +73,8 @@ const configByChainId = { [480]: { transport: http(process.env.WORLDCHAIN_MAINNET_RPC), chainName: 'worldchain', - FastBridgeV2Address: '0x5523D3c98809DdDB82C686E152F5C58B1B0fB59E', - FastBridgeV2StartBlock: 4616214, // first block and new block + FastBridgeV2Address: '0x05C62156C7C47E76223A560210EA648De5e6B53B', + FastBridgeV2StartBlock: 4598830, // first block and new block }, disableCache: true, } From 543fa155e9c3d7258a3e602922ab2c317c5dec57 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 10:58:27 -0500 Subject: [PATCH 12/23] fix logic --- contrib/opbot/internal/client.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index c1072f6e9c..350ab5bb18 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -82,16 +82,16 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB // GetRFQByTxHash gets a quote request by transaction hash. func (r *rfqClientImpl) GetRFQByTxHash(ctx context.Context, txHash string) (*relapi.GetQuoteRequestResponse, error) { - var resp *relapi.GetQuoteRequestResponse - var err error + var errs []error for _, relayerClient := range r.relayerClients { - resp, err = relayerClient.GetQuoteRequestByTxHash(ctx, txHash) - if err != nil { - return nil, fmt.Errorf("failed to get quote request by tx hash: %w", err) + resp, err := relayerClient.GetQuoteRequestByTxHash(ctx, txHash) + if err == nil { + return resp, nil } + errs = append(errs, fmt.Errorf("could not get quote request by tx hash: %w", err)) } - return resp, nil + return nil, fmt.Errorf("could not get quote request by tx hash: %v", errs) } var _ RFQClient = &rfqClientImpl{} From 50c4ecc08b4ee0377b3e92f45db1f31cfed1316c Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 10:58:39 -0500 Subject: [PATCH 13/23] [goreleaser] From a4cd9aa73be6e29a4fa27399e752b47108eb3e3e Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 10 Oct 2024 11:00:25 -0500 Subject: [PATCH 14/23] fix error msg --- contrib/opbot/internal/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index 350ab5bb18..26bf3732a6 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -56,7 +56,7 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB SetResult(&res). Get(fmt.Sprintf(getRequestByTxHash, txID)) if err != nil { - return nil, "", fmt.Errorf("failed to get quote request by tx hash: %w", err) + return nil, "", fmt.Errorf("failed to get quote request by tx ID: %w", err) } if resp.StatusCode() != http.StatusOK { From 3e9071592ba2a646b841b16adc0b08e0d54db142 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Thu, 10 Oct 2024 17:32:05 +0100 Subject: [PATCH 15/23] [goreleaser] adding catch --- services/explorer/consumer/parser/rfqparser.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/services/explorer/consumer/parser/rfqparser.go b/services/explorer/consumer/parser/rfqparser.go index 65da0f5bd7..8342b7efb1 100644 --- a/services/explorer/consumer/parser/rfqparser.go +++ b/services/explorer/consumer/parser/rfqparser.go @@ -120,6 +120,11 @@ func (p *RFQParser) MatureLogs(ctx context.Context, rfqEvent *model.RFQEvent, iF rfqEvent.TokenDecimal = new(uint8) *rfqEvent.TokenDecimal = 18 curCoinGeckoID = ethCoinGeckoID + } else if 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 rfqEvent.TokenSymbol = "USDC" From 7c12249c67176dcae11d95f00e6c7a8cd2d3c256 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Fri, 11 Oct 2024 16:28:09 -0500 Subject: [PATCH 16/23] remove function --- contrib/opbot/botmd/commands.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index 7c0785b856..22ce4f0293 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -196,7 +196,7 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { }, { Type: slack.MarkdownType, - Text: fmt.Sprintf("*Estimated Tx Age*: %s", getTxAge(res.BridgeRelay.BlockTimestamp)), + Text: fmt.Sprintf("*Estimated Tx Age*: %s", humanize.Time(time.Unix(res.BridgeRelay.BlockTimestamp, 0))), }, } @@ -346,10 +346,6 @@ func (b *Bot) makeFastBridge(ctx context.Context, req *relapi.GetQuoteRequestRes return fastBridgeHandle, nil } -func getTxAge(timestamp int64) string { - return humanize.Time(time.Unix(timestamp, 0)) -} - func toExplorerSlackLink(ogHash string) string { rfqHash := strings.ToUpper(ogHash) // cut off 0x From 9bd00381293fb425b0e9aff8edf9ecc7d24254d3 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Mon, 14 Oct 2024 09:02:42 -0500 Subject: [PATCH 17/23] response error fixes and wld decimals --- .../src/controllers/pendingTransactionsController.ts | 8 ++++---- .../api/src/routes/conflictingProofsRoute.ts | 2 +- packages/rfq-indexer/api/src/routes/disputesRoute.ts | 2 +- .../rfq-indexer/api/src/routes/invalidRelaysRoute.ts | 2 +- .../api/src/routes/pendingTransactionsRoute.ts | 8 ++++---- .../api/src/routes/refundedAndRelayedRoute.ts | 2 +- .../rfq-indexer/api/src/routes/transactionIdRoute.ts | 2 +- packages/rfq-indexer/indexer/src/utils/formatAmount.ts | 10 +++++++--- 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts index 0cbb2defa8..5d235e92cc 100644 --- a/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts +++ b/packages/rfq-indexer/api/src/controllers/pendingTransactionsController.ts @@ -38,7 +38,7 @@ export const pendingTransactionsMissingClaimController = async ( res.json(nestedResults) } else { res - .status(404) + .status(200) .json({ message: 'No pending transactions missing claim found' }) } } catch (error) { @@ -76,7 +76,7 @@ export const pendingTransactionsMissingProofController = async ( res.json(nestedResults) } else { res - .status(404) + .status(200) .json({ message: 'No pending transactions missing proof found' }) } } catch (error) { @@ -121,7 +121,7 @@ export const pendingTransactionsMissingRelayController = async ( res.json(nestedResults) } else { res - .status(404) + .status(200) .json({ message: 'No pending transactions missing relay found' }) } } catch (error) { @@ -166,7 +166,7 @@ export const pendingTransactionsMissingRelayExceedDeadlineController = async ( res.json(nestedResults) } else { res - .status(404) + .status(200) .json({ message: 'No pending transactions missing relay found' }) } } catch (error) { diff --git a/packages/rfq-indexer/api/src/routes/conflictingProofsRoute.ts b/packages/rfq-indexer/api/src/routes/conflictingProofsRoute.ts index aa48c89e07..0a03dc5a1f 100644 --- a/packages/rfq-indexer/api/src/routes/conflictingProofsRoute.ts +++ b/packages/rfq-indexer/api/src/routes/conflictingProofsRoute.ts @@ -41,7 +41,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: No conflicting proofs found * content: * application/json: diff --git a/packages/rfq-indexer/api/src/routes/disputesRoute.ts b/packages/rfq-indexer/api/src/routes/disputesRoute.ts index de964220b0..ee1b2f9bf4 100644 --- a/packages/rfq-indexer/api/src/routes/disputesRoute.ts +++ b/packages/rfq-indexer/api/src/routes/disputesRoute.ts @@ -41,7 +41,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: No disputes found * content: * application/json: diff --git a/packages/rfq-indexer/api/src/routes/invalidRelaysRoute.ts b/packages/rfq-indexer/api/src/routes/invalidRelaysRoute.ts index 31356156f2..df20c8f60e 100644 --- a/packages/rfq-indexer/api/src/routes/invalidRelaysRoute.ts +++ b/packages/rfq-indexer/api/src/routes/invalidRelaysRoute.ts @@ -41,7 +41,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: No recent invalid relays found * content: * application/json: diff --git a/packages/rfq-indexer/api/src/routes/pendingTransactionsRoute.ts b/packages/rfq-indexer/api/src/routes/pendingTransactionsRoute.ts index e80dbd7fac..5bd3f0ba1a 100644 --- a/packages/rfq-indexer/api/src/routes/pendingTransactionsRoute.ts +++ b/packages/rfq-indexer/api/src/routes/pendingTransactionsRoute.ts @@ -46,7 +46,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: No pending transactions missing claim found * content: * application/json: @@ -87,7 +87,7 @@ router.get('/missing-claim', pendingTransactionsMissingClaimController) * type: object * relay: * type: object - * 404: + * 200: * description: No pending transactions missing proof found * content: * application/json: @@ -126,7 +126,7 @@ router.get('/missing-proof', pendingTransactionsMissingProofController) * properties: * deposit: * type: object - * 404: + * 200: * description: No pending transactions missing relay found * content: * application/json: @@ -165,7 +165,7 @@ router.get('/missing-relay', pendingTransactionsMissingRelayController) * properties: * deposit: * type: object - * 404: + * 200: * description: No pending transactionst that exceed the deadline found * content: * application/json: diff --git a/packages/rfq-indexer/api/src/routes/refundedAndRelayedRoute.ts b/packages/rfq-indexer/api/src/routes/refundedAndRelayedRoute.ts index cd38b3b33e..ab54203ed7 100644 --- a/packages/rfq-indexer/api/src/routes/refundedAndRelayedRoute.ts +++ b/packages/rfq-indexer/api/src/routes/refundedAndRelayedRoute.ts @@ -41,7 +41,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: No refunded and relayed transactions found * content: * application/json: diff --git a/packages/rfq-indexer/api/src/routes/transactionIdRoute.ts b/packages/rfq-indexer/api/src/routes/transactionIdRoute.ts index 253060dcdf..0a654e8d30 100644 --- a/packages/rfq-indexer/api/src/routes/transactionIdRoute.ts +++ b/packages/rfq-indexer/api/src/routes/transactionIdRoute.ts @@ -46,7 +46,7 @@ const router = express.Router() * BridgeDispute: * type: object * description: Dispute information (if available) - * 404: + * 200: * description: Transaction not found * content: * application/json: diff --git a/packages/rfq-indexer/indexer/src/utils/formatAmount.ts b/packages/rfq-indexer/indexer/src/utils/formatAmount.ts index 9cbc1b2768..54787d3a91 100644 --- a/packages/rfq-indexer/indexer/src/utils/formatAmount.ts +++ b/packages/rfq-indexer/indexer/src/utils/formatAmount.ts @@ -1,8 +1,12 @@ import { formatUnits } from 'viem' -const ETH_ADDRESS = '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE' +const ADDRESSES_WITH_18_DECIMALS = [ + '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH + '0x2cFc85d8E48F8EAB294be644d9E25C3030863003', // WLD + '0x163f8c2467924be0ae7b5347228cabf260318753', // WLD +].map(address => address.toLowerCase()) export function formatAmount(amount: bigint, tokenAddress: string): string { - const decimals = tokenAddress.toLowerCase() === ETH_ADDRESS.toLowerCase() ? 18 : 6 + const decimals = ADDRESSES_WITH_18_DECIMALS.includes(tokenAddress.toLowerCase()) ? 18 : 6 return formatUnits(amount, decimals) -} \ No newline at end of file +} From 4f1f04c21ca4cf6ad7ca71aad4cc8362644f2f3f Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Mon, 14 Oct 2024 12:57:37 -0500 Subject: [PATCH 18/23] origin tx hash --- contrib/opbot/botmd/commands.go | 20 ++++++++++---------- contrib/opbot/internal/client.go | 30 ++++++------------------------ 2 files changed, 16 insertions(+), 34 deletions(-) diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index 22ce4f0293..000bca8700 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -20,13 +20,13 @@ import ( "github.com/hako/durafmt" "github.com/slack-go/slack" "github.com/slack-io/slacker" + "github.com/synapsecns/sanguine/contrib/opbot/internal" "github.com/synapsecns/sanguine/contrib/opbot/signoz" "github.com/synapsecns/sanguine/core/retry" "github.com/synapsecns/sanguine/ethergo/chaindata" "github.com/synapsecns/sanguine/ethergo/submitter" rfqClient "github.com/synapsecns/sanguine/services/rfq/api/client" "github.com/synapsecns/sanguine/services/rfq/contracts/fastbridge" - "github.com/synapsecns/sanguine/services/rfq/relayer/relapi" ) func (b *Bot) requiresSignoz(definition *slacker.CommandDefinition) *slacker.CommandDefinition { @@ -164,7 +164,7 @@ func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { Handler: func(ctx *slacker.CommandContext) { tx := stripLinks(ctx.Request().Param("tx")) - res, status, err := b.rfqClient.GetRFQByTxID(ctx.Context(), tx) + res, status, err := b.rfqClient.GetRFQ(ctx.Context(), tx) if err != nil { b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) _, err := ctx.Response().Reply(fmt.Sprintf("error fetching quote request %s", err.Error())) @@ -240,7 +240,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { return } - rawRequest, err := b.rfqClient.GetRFQByTxHash(ctx.Context(), tx) + rawRequest, _, err := b.rfqClient.GetRFQ(ctx.Context(), tx) if err != nil { b.logger.Errorf(ctx.Context(), "error fetching quote request: %v", err) _, err := ctx.Response().Reply("error fetching quote request") @@ -259,7 +259,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { return } - isScreened, err := b.screener.ScreenAddress(ctx.Context(), rawRequest.Sender) + isScreened, err := b.screener.ScreenAddress(ctx.Context(), rawRequest.Bridge.Sender) if err != nil { _, err := ctx.Response().Reply("error screening address") if err != nil { @@ -275,7 +275,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { return } - nonce, err := b.submitter.SubmitTransaction(ctx.Context(), big.NewInt(int64(rawRequest.OriginChainID)), func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) { + nonce, err := b.submitter.SubmitTransaction(ctx.Context(), big.NewInt(int64(rawRequest.Bridge.OriginChainID)), func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) { tx, err = fastBridgeContract.Refund(transactor, common.Hex2Bytes(rawRequest.QuoteRequestRaw)) if err != nil { return nil, fmt.Errorf("error submitting refund: %w", err) @@ -291,7 +291,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { err = retry.WithBackoff( ctx.Context(), func(ctx context.Context) error { - status, err = b.submitter.GetSubmissionStatus(ctx, big.NewInt(int64(rawRequest.OriginChainID)), nonce) + status, err = b.submitter.GetSubmissionStatus(ctx, big.NewInt(int64(rawRequest.Bridge.OriginChainID)), nonce) if err != nil || !status.HasTx() { b.logger.Errorf(ctx, "error fetching quote request: %v", err) return fmt.Errorf("error fetching quote request: %w", err) @@ -310,7 +310,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { return } - _, err = ctx.Response().Reply(fmt.Sprintf("refund submitted: %s", toTXSlackLink(status.TxHash().String(), rawRequest.OriginChainID))) + _, err = ctx.Response().Reply(fmt.Sprintf("refund submitted: %s", toTXSlackLink(status.TxHash().String(), uint32(rawRequest.Bridge.OriginChainID)))) if err != nil { log.Println(err) } @@ -318,7 +318,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { } } -func (b *Bot) makeFastBridge(ctx context.Context, req *relapi.GetQuoteRequestResponse) (*fastbridge.FastBridge, error) { +func (b *Bot) makeFastBridge(ctx context.Context, req *internal.GetRFQByTxIDResponse) (*fastbridge.FastBridge, error) { client, err := rfqClient.NewUnauthenticatedClient(b.handler, b.cfg.RFQApiURL) if err != nil { return nil, fmt.Errorf("error creating rfq client: %w", err) @@ -329,12 +329,12 @@ func (b *Bot) makeFastBridge(ctx context.Context, req *relapi.GetQuoteRequestRes return nil, fmt.Errorf("error fetching rfq contracts: %w", err) } - chainClient, err := b.rpcClient.GetChainClient(ctx, int(req.OriginChainID)) + chainClient, err := b.rpcClient.GetChainClient(ctx, int(req.Bridge.OriginChainID)) if err != nil { return nil, fmt.Errorf("error getting chain client: %w", err) } - contractAddress, ok := contracts.Contracts[req.OriginChainID] + contractAddress, ok := contracts.Contracts[uint32(req.Bridge.OriginChainID)] if !ok { return nil, errors.New("contract address not found") } diff --git a/contrib/opbot/internal/client.go b/contrib/opbot/internal/client.go index 26bf3732a6..525d0e4b2f 100644 --- a/contrib/opbot/internal/client.go +++ b/contrib/opbot/internal/client.go @@ -14,15 +14,13 @@ import ( ) const ( - getRequestByTxHash = "/api/transaction-id/%s" + getRFQRoute = "/api/transaction-id/%s" ) // RFQClient is the interface for the RFQ client. type RFQClient interface { - // GetRFQByTxID gets a quote request by transaction ID. - GetRFQByTxID(ctx context.Context, txID string) (resp *GetRFQByTxIDResponse, status string, err error) - // GetRFQByTxHash gets a quote request by transaction hash. - GetRFQByTxHash(ctx context.Context, txHash string) (resp *relapi.GetQuoteRequestResponse, err error) + // GetRFQ gets a quote request by transaction ID. + GetRFQ(ctx context.Context, txIdentifier string) (resp *GetRFQByTxIDResponse, status string, err error) } type rfqClientImpl struct { @@ -49,12 +47,12 @@ func NewRFQClient(handler metrics.Handler, indexerURL string, relayerURLs []stri } } -// GetRFQByTxID gets a quote request by transaction ID. -func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQByTxIDResponse, string, error) { +// GetRFQByTxID gets a quote request by transaction ID or transaction hash. +func (r *rfqClientImpl) GetRFQ(ctx context.Context, txIdentifier string) (*GetRFQByTxIDResponse, string, error) { var res GetRFQByTxIDResponse resp, err := r.client.R().SetContext(ctx). SetResult(&res). - Get(fmt.Sprintf(getRequestByTxHash, txID)) + Get(fmt.Sprintf(getRFQRoute, txIdentifier)) if err != nil { return nil, "", fmt.Errorf("failed to get quote request by tx ID: %w", err) } @@ -79,19 +77,3 @@ func (r *rfqClientImpl) GetRFQByTxID(ctx context.Context, txID string) (*GetRFQB return &res, status, nil } - -// GetRFQByTxHash gets a quote request by transaction hash. -func (r *rfqClientImpl) GetRFQByTxHash(ctx context.Context, txHash string) (*relapi.GetQuoteRequestResponse, error) { - var errs []error - for _, relayerClient := range r.relayerClients { - resp, err := relayerClient.GetQuoteRequestByTxHash(ctx, txHash) - if err == nil { - return resp, nil - } - errs = append(errs, fmt.Errorf("could not get quote request by tx hash: %w", err)) - } - - return nil, fmt.Errorf("could not get quote request by tx hash: %v", errs) -} - -var _ RFQClient = &rfqClientImpl{} From 1dbcd96868ad10ca7ed4033a83737168d2ae5489 Mon Sep 17 00:00:00 2001 From: defi-moses Date: Tue, 15 Oct 2024 10:56:37 -0400 Subject: [PATCH 19/23] adding address --- packages/rfq-indexer/indexer/src/utils/formatAmount.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/rfq-indexer/indexer/src/utils/formatAmount.ts b/packages/rfq-indexer/indexer/src/utils/formatAmount.ts index 54787d3a91..2ea80247e9 100644 --- a/packages/rfq-indexer/indexer/src/utils/formatAmount.ts +++ b/packages/rfq-indexer/indexer/src/utils/formatAmount.ts @@ -4,6 +4,7 @@ const ADDRESSES_WITH_18_DECIMALS = [ '0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE', // ETH '0x2cFc85d8E48F8EAB294be644d9E25C3030863003', // WLD '0x163f8c2467924be0ae7b5347228cabf260318753', // WLD + '0xdC6fF44d5d932Cbd77B52E5612Ba0529DC6226F1', // WLD ].map(address => address.toLowerCase()) export function formatAmount(amount: bigint, tokenAddress: string): string { From 6b4c78e81c6f00d973a30ec772bcf2e42894daca Mon Sep 17 00:00:00 2001 From: vro <168573323+golangisfun123@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:12:02 -0500 Subject: [PATCH 20/23] feat(rfq-indexer): add `request` column to `BridgeRequested` for refunds (#3287) * feat(rfq-relayer): add MaxRelayAmount (#3259) * Feat: add quoteParams helper for test * Feat: add MaxQuoteAmount to relconfig * Feat: use MaxQuoteAmount * Feat: handle MaxQuoteAmount in quoter test * Replace: MaxQuoteAmount -> MaxRelayAmount * Feat: shouldProcess() returns false if max relay amount exceeded * Feat: add test for MaxRelayAmount * add request field for refunds * adding to events typing --------- Co-authored-by: dwasse Co-authored-by: defi-moses --- .../rfq-indexer/api/src/graphql/resolvers.ts | 1 + .../api/src/graphql/types/events.graphql | 1 + .../api/src/queries/depositsQueries.ts | 1 + packages/rfq-indexer/api/src/types/index.ts | 1 + packages/rfq-indexer/indexer/ponder.schema.ts | 1 + packages/rfq-indexer/indexer/src/index.ts | 2 + services/rfq/relayer/quoter/quoter.go | 21 ++++- services/rfq/relayer/quoter/quoter_test.go | 82 ++++++++++++++++--- services/rfq/relayer/relconfig/config.go | 2 + services/rfq/relayer/relconfig/getters.go | 35 ++++++++ 10 files changed, 135 insertions(+), 12 deletions(-) diff --git a/packages/rfq-indexer/api/src/graphql/resolvers.ts b/packages/rfq-indexer/api/src/graphql/resolvers.ts index 1deb7950d9..b346371ec7 100644 --- a/packages/rfq-indexer/api/src/graphql/resolvers.ts +++ b/packages/rfq-indexer/api/src/graphql/resolvers.ts @@ -20,6 +20,7 @@ const qDeposits = () => { 'BridgeRequestEvents.originAmountFormatted', 'BridgeRequestEvents.destAmountFormatted', 'BridgeRequestEvents.sender', + 'BridgeRequestEvents.request', 'BridgeRequestEvents.sendChainGas', ]) .where('BridgeRequestEvents.blockTimestamp', '>', 1722729600) diff --git a/packages/rfq-indexer/api/src/graphql/types/events.graphql b/packages/rfq-indexer/api/src/graphql/types/events.graphql index 2e3716de0e..45fcf930db 100644 --- a/packages/rfq-indexer/api/src/graphql/types/events.graphql +++ b/packages/rfq-indexer/api/src/graphql/types/events.graphql @@ -17,6 +17,7 @@ scalar BigInt destAmountFormatted: String! destChainId: Int! destChain: String! + request: String! sendChainGas: Boolean! } diff --git a/packages/rfq-indexer/api/src/queries/depositsQueries.ts b/packages/rfq-indexer/api/src/queries/depositsQueries.ts index 61e33aa3d1..e765e032d5 100644 --- a/packages/rfq-indexer/api/src/queries/depositsQueries.ts +++ b/packages/rfq-indexer/api/src/queries/depositsQueries.ts @@ -17,6 +17,7 @@ export const qDeposits = () => { 'BridgeRequestEvents.originAmountFormatted', 'BridgeRequestEvents.destAmountFormatted', 'BridgeRequestEvents.sender', + 'BridgeRequestEvents.request', 'BridgeRequestEvents.sendChainGas', ]) .where('BridgeRequestEvents.blockTimestamp', '>', 1722729600) diff --git a/packages/rfq-indexer/api/src/types/index.ts b/packages/rfq-indexer/api/src/types/index.ts index 738e9469fd..503563e741 100644 --- a/packages/rfq-indexer/api/src/types/index.ts +++ b/packages/rfq-indexer/api/src/types/index.ts @@ -10,6 +10,7 @@ export interface BridgeRequestEvents { originChainId: ColumnType originChain: ColumnType sender: ColumnType + request: ColumnType originToken: ColumnType destToken: ColumnType originAmount: ColumnType diff --git a/packages/rfq-indexer/indexer/ponder.schema.ts b/packages/rfq-indexer/indexer/ponder.schema.ts index 8d32ea595c..24f80bdf00 100644 --- a/packages/rfq-indexer/indexer/ponder.schema.ts +++ b/packages/rfq-indexer/indexer/ponder.schema.ts @@ -5,6 +5,7 @@ export default createSchema((p) => ({ id: p.string(), transactionId: p.string(), sender: p.string(), + request: p.string(), originToken: p.string(), destToken: p.string(), originAmount: p.bigint().optional(), diff --git a/packages/rfq-indexer/indexer/src/index.ts b/packages/rfq-indexer/indexer/src/index.ts index 3a6a71380f..f61146c7d6 100644 --- a/packages/rfq-indexer/indexer/src/index.ts +++ b/packages/rfq-indexer/indexer/src/index.ts @@ -16,6 +16,7 @@ ponder.on('FastBridgeV2:BridgeRequested', async ({ event, context }) => { args: { transactionId, sender, + request, destChainId, originToken, destToken, @@ -33,6 +34,7 @@ ponder.on('FastBridgeV2:BridgeRequested', async ({ event, context }) => { data: { transactionId, sender: trim(sender), + request: request, originChainId: Number(chainId), originChain: getChainName(Number(chainId)), destChainId: Number(destChainId), diff --git a/services/rfq/relayer/quoter/quoter.go b/services/rfq/relayer/quoter/quoter.go index 3b5ecc8352..2cd3dfcf94 100644 --- a/services/rfq/relayer/quoter/quoter.go +++ b/services/rfq/relayer/quoter/quoter.go @@ -207,6 +207,15 @@ func (m *Manager) ShouldProcess(parentCtx context.Context, quote reldb.QuoteRequ return false, nil } + // check relay amount + maxRelayAmount := m.config.GetMaxRelayAmount(int(quote.Transaction.OriginChainId), quote.Transaction.OriginToken) + if maxRelayAmount != nil { + if quote.Transaction.OriginAmount.Cmp(maxRelayAmount) > 0 { + span.AddEvent("origin amount is greater than max relay amount") + return false, nil + } + } + // all checks have passed return true, nil } @@ -713,7 +722,7 @@ func (m *Manager) getOriginAmount(parentCtx context.Context, input QuoteInput) ( } } - // Finally, clip the quoteAmount by the dest balance + // Clip the quoteAmount by the dest balance if quoteAmount.Cmp(input.DestBalance) > 0 { span.AddEvent("quote amount greater than destination balance", trace.WithAttributes( attribute.String("quote_amount", quoteAmount.String()), @@ -722,6 +731,16 @@ func (m *Manager) getOriginAmount(parentCtx context.Context, input QuoteInput) ( quoteAmount = input.DestBalance } + // Clip the quoteAmount by the maxQuoteAmount + maxQuoteAmount := m.config.GetMaxRelayAmount(input.DestChainID, input.DestTokenAddr) + if maxQuoteAmount != nil && quoteAmount.Cmp(maxQuoteAmount) > 0 { + span.AddEvent("quote amount greater than max quote amount", trace.WithAttributes( + attribute.String("quote_amount", quoteAmount.String()), + attribute.String("max_quote_amount", maxQuoteAmount.String()), + )) + quoteAmount = maxQuoteAmount + } + // Deduct gas cost from the quote amount, if necessary quoteAmount, err = m.deductGasCost(ctx, quoteAmount, input.DestTokenAddr, input.DestChainID) if err != nil { diff --git a/services/rfq/relayer/quoter/quoter_test.go b/services/rfq/relayer/quoter/quoter_test.go index 1d6a52c7de..321d55b189 100644 --- a/services/rfq/relayer/quoter/quoter_test.go +++ b/services/rfq/relayer/quoter/quoter_test.go @@ -136,6 +136,13 @@ func (s *QuoterSuite) TestShouldProcess() { s.False(s.manager.ShouldProcess(s.GetTestContext(), quote)) s.manager.SetRelayPaused(false) s.True(s.manager.ShouldProcess(s.GetTestContext(), quote)) + + // Set max relay amount + originTokenCfg := s.config.Chains[int(s.origin)].Tokens["USDC"] + originTokenCfg.MaxRelayAmount = "900" // less than balance + s.config.Chains[int(s.origin)].Tokens["USDC"] = originTokenCfg + s.manager.SetConfig(s.config) + s.False(s.manager.ShouldProcess(s.GetTestContext(), quote)) } func (s *QuoterSuite) TestIsProfitable() { @@ -173,13 +180,23 @@ func (s *QuoterSuite) TestGetOriginAmount() { originAddr := common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48") balance := big.NewInt(1000_000_000) // 1000 USDC - setQuoteParams := func(quotePct, quoteOffset float64, minQuoteAmount, maxBalance string) { - s.config.BaseChainConfig.QuotePct = "ePct + type quoteParams struct { + quotePct float64 + quoteOffset float64 + minQuoteAmount string + maxBalance string + maxQuoteAmount string + } + + setQuoteParams := func(params quoteParams) { + s.config.BaseChainConfig.QuotePct = ¶ms.quotePct destTokenCfg := s.config.Chains[dest].Tokens["USDC"] - destTokenCfg.MinQuoteAmount = minQuoteAmount + destTokenCfg.MinQuoteAmount = params.minQuoteAmount + destTokenCfg.MaxRelayAmount = params.maxQuoteAmount originTokenCfg := s.config.Chains[origin].Tokens["USDC"] - originTokenCfg.QuoteOffsetBps = quoteOffset - originTokenCfg.MaxBalance = &maxBalance + originTokenCfg.QuoteOffsetBps = params.quoteOffset + originTokenCfg.MaxBalance = ¶ms.maxBalance + originTokenCfg.MaxRelayAmount = params.maxQuoteAmount s.config.Chains[dest].Tokens["USDC"] = destTokenCfg s.config.Chains[origin].Tokens["USDC"] = originTokenCfg s.manager.SetConfig(s.config) @@ -201,42 +218,85 @@ func (s *QuoterSuite) TestGetOriginAmount() { s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 50 with MinQuoteAmount of 0; should be 50% of balance. - setQuoteParams(50, 0, "0", "0") + setQuoteParams(quoteParams{ + quotePct: 50, + quoteOffset: 0, + minQuoteAmount: "0", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 50 with QuoteOffset of -1%. Should be 1% less than 50% of balance. - setQuoteParams(50, -100, "0", "0") + setQuoteParams(quoteParams{ + quotePct: 50, + quoteOffset: -100, + minQuoteAmount: "0", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(495_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 500; should be 50% of balance. - setQuoteParams(25, 0, "500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 500; should be 50% of balance. - setQuoteParams(25, 0, "500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) s.Equal(expectedAmount, quoteAmount) // Set QuotePct to 25 with MinQuoteAmount of 1500; should be total balance. - setQuoteParams(25, 0, "1500", "0") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "1500", + maxBalance: "0", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(1000_000_000) s.Equal(expectedAmount, quoteAmount) + // Set QuotePct to 100 with MinQuoteAmount of 0 and MaxRelayAmount of 500; should be 500. + setQuoteParams(quoteParams{ + quotePct: 100, + quoteOffset: 0, + minQuoteAmount: "0", + maxBalance: "0", + maxQuoteAmount: "500", + }) + quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) + s.NoError(err) + expectedAmount = big.NewInt(500_000_000) + s.Equal(expectedAmount, quoteAmount) + // Set QuotePct to 25 with MinQuoteAmount of 1500 and MaxBalance of 1200; should be 200. - setQuoteParams(25, 0, "1500", "1200") + setQuoteParams(quoteParams{ + quotePct: 25, + quoteOffset: 0, + minQuoteAmount: "1500", + maxBalance: "1200", + }) quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(200_000_000) diff --git a/services/rfq/relayer/relconfig/config.go b/services/rfq/relayer/relconfig/config.go index a4449bf8db..220627e13a 100644 --- a/services/rfq/relayer/relconfig/config.go +++ b/services/rfq/relayer/relconfig/config.go @@ -124,6 +124,8 @@ type TokenConfig struct { PriceUSD float64 `yaml:"price_usd"` // MinQuoteAmount is the minimum amount to quote for this token in human-readable units. MinQuoteAmount string `yaml:"min_quote_amount"` + // MaxRelayAmount is the maximum amount to quote and relay for this token in human-readable units. + MaxRelayAmount string `yaml:"max_relay_amount"` // RebalanceMethods are the supported methods for rebalancing. RebalanceMethods []string `yaml:"rebalance_methods"` // MaintenanceBalancePct is the percentage of the total balance under which a rebalance will be triggered. diff --git a/services/rfq/relayer/relconfig/getters.go b/services/rfq/relayer/relconfig/getters.go index 2cb4880712..a3fbb25cc7 100644 --- a/services/rfq/relayer/relconfig/getters.go +++ b/services/rfq/relayer/relconfig/getters.go @@ -746,6 +746,41 @@ func (c Config) GetMinQuoteAmount(chainID int, addr common.Address) *big.Int { return quoteAmountScaled } +var defaultMaxRelayAmount *big.Int // nil + +// GetMaxRelayAmount returns the quote amount for the given chain and address. +// Note that this getter returns the value in native token decimals. +func (c Config) GetMaxRelayAmount(chainID int, addr common.Address) *big.Int { + chainCfg, ok := c.Chains[chainID] + if !ok { + return defaultMaxRelayAmount + } + + var tokenCfg *TokenConfig + for _, cfg := range chainCfg.Tokens { + if common.HexToAddress(cfg.Address).Hex() == addr.Hex() { + cfgCopy := cfg + tokenCfg = &cfgCopy + break + } + } + if tokenCfg == nil { + return defaultMaxRelayAmount + } + quoteAmountFlt, ok := new(big.Float).SetString(tokenCfg.MaxRelayAmount) + if !ok { + return defaultMaxRelayAmount + } + if quoteAmountFlt.Cmp(big.NewFloat(0)) <= 0 { + return defaultMaxRelayAmount + } + + // Scale the minQuoteAmount by the token decimals. + denomDecimalsFactor := new(big.Int).Exp(big.NewInt(10), big.NewInt(int64(tokenCfg.Decimals)), nil) + quoteAmountScaled, _ := new(big.Float).Mul(quoteAmountFlt, new(big.Float).SetInt(denomDecimalsFactor)).Int(nil) + return quoteAmountScaled +} + var defaultMinRebalanceAmount = big.NewInt(1000) // GetMinRebalanceAmount returns the min rebalance amount for the given chain and address. From d0867c507db9f73af0bfe92fb8d2ffe75b5bd318 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 17 Oct 2024 12:45:59 -0500 Subject: [PATCH 21/23] idr --- contrib/opbot/botmd/commands.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index 000bca8700..73a86a72ab 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -157,7 +157,7 @@ func (b *Bot) traceCommand() *slacker.CommandDefinition { func (b *Bot) rfqLookupCommand() *slacker.CommandDefinition { return &slacker.CommandDefinition{ Command: "rfq ", - Description: "find a rfq transaction by either tx hash or txid on all configured relayers", + Description: "find a rfq transaction by either tx hash or txid from the rfq-indexer api", Examples: []string{ "rfq 0x30f96b45ba689c809f7e936c140609eb31c99b182bef54fccf49778716a7e1ca", }, From fce526bbddd8a6d8b95fe3f746fd6b5133114422 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 17 Oct 2024 13:22:13 -0500 Subject: [PATCH 22/23] merge --- services/rfq/relayer/quoter/quoter_test.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/services/rfq/relayer/quoter/quoter_test.go b/services/rfq/relayer/quoter/quoter_test.go index 9ad8460813..932658d6fd 100644 --- a/services/rfq/relayer/quoter/quoter_test.go +++ b/services/rfq/relayer/quoter/quoter_test.go @@ -289,7 +289,6 @@ func (s *QuoterSuite) TestGetOriginAmount() { minQuoteAmount: "500", maxBalance: "0", }) -<<<<<<< HEAD quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) @@ -302,8 +301,6 @@ func (s *QuoterSuite) TestGetOriginAmount() { minQuoteAmount: "500", maxBalance: "0", }) -======= ->>>>>>> 6b4c78e81c6f00d973a30ec772bcf2e42894daca quoteAmount, err = s.manager.GetOriginAmount(s.GetTestContext(), input) s.NoError(err) expectedAmount = big.NewInt(500_000_000) From 146d28dbbd791cfc49928b4e775f8c3def4fc2c2 Mon Sep 17 00:00:00 2001 From: golangisfun123 Date: Thu, 17 Oct 2024 13:27:09 -0500 Subject: [PATCH 23/23] refund from rfq indexer --- contrib/opbot/botmd/commands.go | 2 +- contrib/opbot/internal/model.go | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/opbot/botmd/commands.go b/contrib/opbot/botmd/commands.go index 354fd87159..d216c41782 100644 --- a/contrib/opbot/botmd/commands.go +++ b/contrib/opbot/botmd/commands.go @@ -279,7 +279,7 @@ func (b *Bot) rfqRefund() *slacker.CommandDefinition { ctx.Context(), big.NewInt(int64(rawRequest.Bridge.OriginChainID)), func(transactor *bind.TransactOpts) (tx *types.Transaction, err error) { - tx, err = fastBridgeContract.Refund(transactor, common.Hex2Bytes(rawRequest.QuoteRequestRaw)) + tx, err = fastBridgeContract.Refund(transactor, common.Hex2Bytes(rawRequest.BridgeRequest.Request)) if err != nil { return nil, fmt.Errorf("error submitting refund: %w", err) } diff --git a/contrib/opbot/internal/model.go b/contrib/opbot/internal/model.go index 9a1f944886..f7afcbad37 100644 --- a/contrib/opbot/internal/model.go +++ b/contrib/opbot/internal/model.go @@ -29,6 +29,7 @@ type BridgeRequest struct { BlockNumber string `json:"blockNumber"` BlockTimestamp int64 `json:"blockTimestamp"` TransactionHash string `json:"transactionHash"` + Request string `json:"request"` } // BridgeRelay contains the bridge relay information.