diff --git a/app/app.go b/app/app.go index 1dea8f41..6ad1b632 100644 --- a/app/app.go +++ b/app/app.go @@ -20,7 +20,6 @@ import ( "github.com/rs/zerolog/log" "github.com/spf13/viper" "github.com/sprintertech/lifi-solver/pkg/pricing" - lifiTypes "github.com/sprintertech/lifi-solver/pkg/protocols/lifi" "github.com/sprintertech/lifi-solver/pkg/protocols/lifi/validation" "github.com/sprintertech/lifi-solver/pkg/token" "github.com/sprintertech/lifi-solver/pkg/tokenpricing/pyth" @@ -289,7 +288,7 @@ func Run() error { resolver := token.NewTokenResolver(solverConfig, usdPricer) orderPricer := pricing.NewStandardPricer(resolver) lifiApi := lifi.NewLifiAPI() - lifiValidator := validation.NewLifiEscrowOrderValidator[lifiTypes.LifiOrder](solverConfig, orderPricer) + lifiValidator := validation.NewLifiEscrowOrderValidator(solverConfig, orderPricer) lifiMh := evmMessage.NewLifiEscrowMessageHandler( *c.GeneralChainConfig.Id, diff --git a/chains/evm/message/lifiEscrow.go b/chains/evm/message/lifiEscrow.go index d0299d86..f598472c 100644 --- a/chains/evm/message/lifiEscrow.go +++ b/chains/evm/message/lifiEscrow.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "math/big" - "strconv" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -139,7 +138,7 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal. []common.Address{borrowToken}, new(big.Int).SetUint64(destChainID), h.lifiAddresses[destChainID], - uint64(order.Order.FillDeadline), + big.NewInt(order.Order.FillDeadline.Unix()).Uint64(), data.Caller, data.LiquidityPool, data.Nonce, @@ -168,11 +167,7 @@ func (h *LifiEscrowMessageHandler) HandleMessage(m *message.Message) (*proposal. } func (h *LifiEscrowMessageHandler) borrowToken(order *lifi.LifiOrder) (common.Address, uint64, error) { - destChainID, err := strconv.ParseUint(order.Order.Outputs[0].ChainID, 10, 64) - if err != nil { - return common.Address{}, 0, err - } - + destChainID := order.Order.Outputs[0].ChainID tokenIn := common.BytesToAddress(order.GenericInputs[0].TokenAddress[:]) symbol, _, err := h.tokenStore.ConfigByAddress(h.chainID, tokenIn) if err != nil { @@ -200,7 +195,7 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro } outputs := make([]output, len(order.Order.Outputs)) for i, o := range order.Order.Outputs { - chainID, _ := new(big.Int).SetString(o.ChainID, 10) + chainID := new(big.Int).SetUint64(o.ChainID) call, err := hexutil.Decode(o.Call) if err != nil { return nil, err @@ -210,11 +205,11 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro return nil, err } outputs[i] = output{ - Oracle: common.HexToHash(o.Oracle), - Settler: common.HexToHash(o.Settler), + Oracle: *o.Oracle, + Settler: *o.Settler, ChainId: chainID, Amount: o.Amount.Int, - Recipient: common.HexToHash(o.Recipient), + Recipient: *o.Recipient, Call: call, Context: context, } @@ -224,7 +219,7 @@ func (h *LifiEscrowMessageHandler) calldata(order *lifi.LifiOrder) ([]byte, erro "fillOrderOutputs", common.HexToHash(order.Meta.OnChainOrderID), outputs, - new(big.Int).SetUint64(uint64(order.Order.FillDeadline)), + big.NewInt(order.Order.FillDeadline.Unix()), common.HexToHash(h.mpcAddress.Hex()).Bytes()) } diff --git a/chains/evm/message/lifiEscrow_test.go b/chains/evm/message/lifiEscrow_test.go index bdcf2810..b1547275 100644 --- a/chains/evm/message/lifiEscrow_test.go +++ b/chains/evm/message/lifiEscrow_test.go @@ -55,14 +55,14 @@ func (s *LifiEscrowMessageHandlerTestSuite) SetupTest() { tokens := make(map[uint64]map[string]config.TokenConfig) tokens[42161] = make(map[string]config.TokenConfig) - tokens[42161]["WETH"] = config.TokenConfig{ - Address: common.HexToAddress("0x036CbD53842c5426634e7929541eC2318f3dCF7e"), - Decimals: 18, + tokens[42161]["USDC"] = config.TokenConfig{ + Address: common.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"), + Decimals: 6, } tokens[8453] = make(map[string]config.TokenConfig) - tokens[8453]["WETH"] = config.TokenConfig{ - Address: common.HexToAddress("0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"), - Decimals: 18, + tokens[8453]["USDC"] = config.TokenConfig{ + Address: common.HexToAddress("0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"), + Decimals: 6, } tokenStore := config.TokenStore{ Tokens: tokens, @@ -150,7 +150,7 @@ func (s *LifiEscrowMessageHandlerTestSuite) Test_HandleMessage_BorrowAmountExcee ErrChn: errChn, Nonce: big.NewInt(101), LiquidityPool: common.HexToAddress("0xe59aaf21c4D9Cf92d9eD4537f4404BA031f83b23"), - BorrowAmount: big.NewInt(20001), + BorrowAmount: big.NewInt(100001), OrderID: "orderID", } s.mockOrderFetcher.EXPECT().GetOrder("orderID").Return(s.mockOrder, nil) diff --git a/go.mod b/go.mod index f2c5c8ee..6056ed15 100644 --- a/go.mod +++ b/go.mod @@ -20,8 +20,8 @@ require ( github.com/rs/zerolog v1.25.0 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.9.0 - github.com/sprintertech/lifi-solver v0.0.0-20251008075555-6feaf23baf0b - github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9 + github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84 + github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef github.com/stretchr/testify v1.10.0 github.com/sygmaprotocol/sygma-core v0.0.0-20250304150334-bd39ac4f7b82 go.opentelemetry.io/otel v1.16.0 diff --git a/go.sum b/go.sum index d713ff6b..730bc243 100644 --- a/go.sum +++ b/go.sum @@ -946,8 +946,12 @@ github.com/sprintertech/lifi-solver v0.0.0-20251001133701-76403ab387a0 h1:z6hwK1 github.com/sprintertech/lifi-solver v0.0.0-20251001133701-76403ab387a0/go.mod h1:h8+7mUc7+adJCAhYf70jvSJp2mc38aLGulBu1zSUlQ8= github.com/sprintertech/lifi-solver v0.0.0-20251008075555-6feaf23baf0b h1:kjEY1836p/5xHhM+noJvzCwbcbfKdPFCY+H5V9snUpc= github.com/sprintertech/lifi-solver v0.0.0-20251008075555-6feaf23baf0b/go.mod h1:h8+7mUc7+adJCAhYf70jvSJp2mc38aLGulBu1zSUlQ8= +github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84 h1:ZygoYNw7Dlnxc3U+o8trzmbSWkH+l7lIUlBSWYIrVvo= +github.com/sprintertech/lifi-solver v0.0.0-20251009144421-521a5d0efa84/go.mod h1:EbAH3JJxioBVuHvyjaP5zTh6uPmumCpbE93WEjwpRm0= github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9 h1:1LzvyGBjEATGzByECJjgY7bj7dPN979VEzyOQLphAmM= github.com/sprintertech/solver-config/go v0.0.0-20251002094949-6a71816a6ac9/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ= +github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef h1:WPyHT8WM/f5rRFmzxeuTvuI6MCqM7wvTeBsW/B7y3lk= +github.com/sprintertech/solver-config/go v0.0.0-20251003113310-77bd6669a2ef/go.mod h1:MrIGW6M815PSYKtWSeOd1Z7eiSeOIk/uA/6E2PhlQVQ= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/protocol/lifi/api.go b/protocol/lifi/api.go index 204598b8..dfcae6ab 100644 --- a/protocol/lifi/api.go +++ b/protocol/lifi/api.go @@ -32,7 +32,7 @@ func NewLifiAPI() *LifiAPI { // GetOrder fetches order from the LiFi API by its on-chain orderID func (a *LifiAPI) GetOrder(orderID string) (*lifi.LifiOrder, error) { - url := fmt.Sprintf("%s/orders?onChainOrderId=%s", LIFI_URL, orderID) + url := fmt.Sprintf("%s/orders/status?onChainOrderId=0x%s", LIFI_URL, orderID) resp, err := a.HTTPClient.Get(url) if err != nil { return nil, fmt.Errorf("request failed: %w", err) @@ -48,13 +48,10 @@ func (a *LifiAPI) GetOrder(orderID string) (*lifi.LifiOrder, error) { return nil, fmt.Errorf("failed to read response body: %w", err) } - s := new(Response) + s := new(lifi.LifiOrder) if err := json.Unmarshal(body, s); err != nil { return nil, fmt.Errorf("failed to unmarshal JSON: %w", err) } - if len(s.Data) == 0 { - return nil, fmt.Errorf("no order found") - } - return &s.Data[0], nil + return s, nil } diff --git a/protocol/lifi/api_test.go b/protocol/lifi/api_test.go index 3953f295..b1738886 100644 --- a/protocol/lifi/api_test.go +++ b/protocol/lifi/api_test.go @@ -1,3 +1,4 @@ +//nolint:gocognit package lifi_test import ( @@ -64,7 +65,7 @@ func Test_LifiAPI_GetOrder(t *testing.T) { t.Run(tc.name, func(t *testing.T) { client := lifi.NewLifiAPI() client.HTTPClient.Transport = roundTripperFunc(func(req *http.Request) (*http.Response, error) { - expectedURL := fmt.Sprintf("%s/orders?onChainOrderId=%s", lifi.LIFI_URL, tc.id) + expectedURL := fmt.Sprintf("%s/orders/status?onChainOrderId=0x%s", lifi.LIFI_URL, tc.id) if req.URL.String() != expectedURL { return nil, fmt.Errorf("unexpected URL: got %s, want %s", req.URL.String(), expectedURL) } @@ -96,7 +97,10 @@ func Test_LifiAPI_GetOrder(t *testing.T) { } var want *lifiProtocol.LifiOrder - _ = json.Unmarshal(tc.wantResult, &want) + err = json.Unmarshal(tc.wantResult, &want) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } if !reflect.DeepEqual(got, want) { t.Errorf("expected %+v, got %+v", tc.wantResult, got) } diff --git a/protocol/lifi/mock/mockData.go b/protocol/lifi/mock/mockData.go index b572937e..ec9cc3fd 100644 --- a/protocol/lifi/mock/mockData.go +++ b/protocol/lifi/mock/mockData.go @@ -1,7 +1,97 @@ package mock const LifiMockResponse = ` -{"data":[{"order":{"user":"0x529cebf485dee1d68073afb75244022f048b0157","nonce":"2824938975","inputs":[["36247376698627773575328963637012941151846014800421893333724382654794431230520","20000"]],"expires":1752648593,"outputs":[{"call":"0x","token":"0x000000000000000000000000036CbD53842c5426634e7929541eC2318f3dCF7e","amount":"10000","oracle":"0x000000000000000000000000ca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","chainId":"42161","context":"0x","settler":"0x000000000000000000000000df96516136684972CA74E8c98E01D0D495f34a0A","recipient":"0x000000000000000000000000529cebf485dee1d68073afb75244022f048b0157"}],"localOracle":"0xca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","fillDeadline":1752648593,"originChainId":"11155111"},"quote":{"toAsset":"0x036cbd53842c5426634e7929541ec2318f3dcf7e","toPrice":"1","discount":"1","fromAsset":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","fromPrice":"1","intermediary":"1"},"sponsorSignature":"","allocatorSignature":"0xb3377ec479bb23dcc4ecf811013a53a9dfb02590d9521f6f76430a0c95a8b8fc4fc052dd32a5a5b6fcb0a5b13dd2fe7cd77ed300abc48552127f598b965ad0431c","inputSettler":"0xb0567293b367e8Ed99cd44cDa1743980F2e6BBB2","meta":{"submitTime":1752648005381,"orderStatus":"Signed","destinationAddress":"0x529cebf485dee1d68073afb75244022f048b0157","orderIdentifier":"co_m2wMeHVReMdTygn3lEIQCA1B5Fcgdx","onChainOrderId":"0xf2c4d82bd09af0430f978a96cf5d3444756bd7143691713e580702475409efc7","signedAt":"2025-07-16T06:40:05.379Z","expiredAt":null,"lastCompactDepositBlockNumber":"8774872"}}],"meta":{"total":1,"limit":50,"offset":0}} +{ + "order": { + "user": "0x6C8A0c210C4C097270FA5df9b799d79A6887b11A", + "nonce": "834202471", + "inputs": [ + [ + "749071750893463290574776461331093852760741783827", + "100000" + ] + ], + "expires": "1760110167", + "outputs": [ + { + "call": "0x", + "token": "0x000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831", + "amount": "100000", + "oracle": "0x0000000000000000000000000000006ea400569c0040d6e5ba651c00848409be", + "chainId": "42161", + "context": "0x", + "settler": "0x00000000000000000000000000000000d7278408ce7a490015577c41e57143a5", + "recipient": "0x0000000000000000000000006c8a0c210c4c097270fa5df9b799d79a6887b11a" + } + ], + "inputOracle": "0x0000006EA400569c0040d6e5Ba651c00848409Be", + "fillDeadline": "1760110167", + "originChainId": "8453" + }, + "quote": null, + "sponsorSignature": null, + "allocatorSignature": null, + "inputSettler": "0x000001bf3f3175bd007f3889b50000c7006e72c0", + "meta": { + "submitTime": 1760102985727, + "orderStatus": "Signed", + "destinationAddress": "0x6c8a0c210c4c097270fa5df9b799d79a6887b11a", + "orderIdentifier": "intent_F_MiaNxyjvyryvvh2OqsuINeqwFMjI", + "onChainOrderId": "0xe40eb815e8fd931b07ca5bb1be759861ff2a63348624fb5c374b2ee675430638", + "signedAt": "2025-10-10T13:29:37.000Z", + "expiredAt": null, + "lastCompactDepositBlockNumber": null, + "orderInitiatedTxHash": "0xe40e3258ebfd90ce75feea3859c204f50e14ee9b28f72d971b4cfaa41eedfba4", + "orderDeliveredTxHash": null, + "orderVerifiedTxHash": null, + "orderSettledTxHash": null + } +} ` -const ExpectedLifiResponse = `{"order":{"user":"0x529cebf485dee1d68073afb75244022f048b0157","nonce":"2824938975","inputs":[["36247376698627773575328963637012941151846014800421893333724382654794431230520","20000"]],"expires":1752648593,"outputs":[{"call":"0x","token":"0x000000000000000000000000036CbD53842c5426634e7929541eC2318f3dCF7e","amount":"10000","oracle":"0x000000000000000000000000ca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","chainId":"42161","context":"0x","settler":"0x000000000000000000000000df96516136684972CA74E8c98E01D0D495f34a0A","recipient":"0x000000000000000000000000529cebf485dee1d68073afb75244022f048b0157"}],"localOracle":"0xca200b41459BF9a1C7EA7F1F22610281Bfb3a8AB","fillDeadline":1752648593,"originChainId":"11155111"},"quote":{"toAsset":"0x036cbd53842c5426634e7929541ec2318f3dcf7e","toPrice":"1","discount":"1","fromAsset":"0x1c7d4b196cb0c7b01d743fbc6116a902379c7238","fromPrice":"1","intermediary":"1"},"sponsorSignature":"","allocatorSignature":"0xb3377ec479bb23dcc4ecf811013a53a9dfb02590d9521f6f76430a0c95a8b8fc4fc052dd32a5a5b6fcb0a5b13dd2fe7cd77ed300abc48552127f598b965ad0431c","inputSettler":"0xb0567293b367e8Ed99cd44cDa1743980F2e6BBB2","meta":{"submitTime":1752648005381,"orderStatus":"Signed","destinationAddress":"0x529cebf485dee1d68073afb75244022f048b0157","orderIdentifier":"co_m2wMeHVReMdTygn3lEIQCA1B5Fcgdx","onChainOrderId":"0xf2c4d82bd09af0430f978a96cf5d3444756bd7143691713e580702475409efc7","signedAt":"2025-07-16T06:40:05.379Z","expiredAt":null,"lastCompactDepositBlockNumber":"8774872"}}` +const ExpectedLifiResponse = ` { + "order": { + "user": "0x6C8A0c210C4C097270FA5df9b799d79A6887b11A", + "nonce": "834202471", + "inputs": [ + [ + "749071750893463290574776461331093852760741783827", + "100000" + ] + ], + "expires": "1760110167", + "outputs": [ + { + "call": "0x", + "token": "0x000000000000000000000000af88d065e77c8cc2239327c5edb3a432268e5831", + "amount": "100000", + "oracle": "0x0000000000000000000000000000006ea400569c0040d6e5ba651c00848409be", + "chainId": "42161", + "context": "0x", + "settler": "0x00000000000000000000000000000000d7278408ce7a490015577c41e57143a5", + "recipient": "0x0000000000000000000000006c8a0c210c4c097270fa5df9b799d79a6887b11a" + } + ], + "inputOracle": "0x0000006EA400569c0040d6e5Ba651c00848409Be", + "fillDeadline": "1760110167", + "originChainId": "8453" + }, + "quote": null, + "sponsorSignature": null, + "allocatorSignature": null, + "inputSettler": "0x000001bf3f3175bd007f3889b50000c7006e72c0", + "meta": { + "submitTime": 1760102985727, + "orderStatus": "Signed", + "destinationAddress": "0x6c8a0c210c4c097270fa5df9b799d79a6887b11a", + "orderIdentifier": "intent_F_MiaNxyjvyryvvh2OqsuINeqwFMjI", + "onChainOrderId": "0xe40eb815e8fd931b07ca5bb1be759861ff2a63348624fb5c374b2ee675430638", + "signedAt": "2025-10-10T13:29:37.000Z", + "expiredAt": null, + "lastCompactDepositBlockNumber": null, + "orderInitiatedTxHash": "0xe40e3258ebfd90ce75feea3859c204f50e14ee9b28f72d971b4cfaa41eedfba4", + "orderDeliveredTxHash": null, + "orderVerifiedTxHash": null, + "orderSettledTxHash": null + } + }`