Skip to content

Commit a700796

Browse files
committed
Fusion Plus updated to 1.1
1 parent bdba0cd commit a700796

File tree

10 files changed

+914
-182
lines changed

10 files changed

+914
-182
lines changed

sdk-clients/fusionplus/api.go

Lines changed: 10 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,13 @@ package fusionplus
33
import (
44
"context"
55
"encoding/json"
6-
"errors"
76
"fmt"
87

98
"github.com/1inch/1inch-sdk-go/common"
109
)
1110

1211
func (api *api) GetOrderByOrderHash(ctx context.Context, params GetOrderByOrderHashParams) (*GetOrderFillsByHashOutputFixed, error) {
13-
u := fmt.Sprintf("/fusion-plus/orders/v1.0/order/status/%s", params.Hash)
12+
u := fmt.Sprintf("/fusion-plus/orders/v1.1/order/status/%s", params.Hash)
1413

1514
payload := common.RequestPayload{
1615
Method: "GET",
@@ -28,8 +27,8 @@ func (api *api) GetOrderByOrderHash(ctx context.Context, params GetOrderByOrderH
2827
return &response, nil
2928
}
3029

31-
func (api *api) GetReadyToAcceptFills(ctx context.Context, params GetOrderByOrderHashParams) (*ReadyToAcceptSecretFills, error) {
32-
u := fmt.Sprintf("/fusion-plus/orders/v1.0/order/ready-to-accept-secret-fills/%s", params.Hash)
30+
func (api *api) GetReadyToAcceptFills(ctx context.Context, params GetReadyToAcceptFillsParams) (*ReadyToAcceptSecretFills, error) {
31+
u := fmt.Sprintf("/fusion-plus/orders/v1.1/order/ready-to-accept-secret-fills/%s", params.Hash)
3332

3433
payload := common.RequestPayload{
3534
Method: "GET",
@@ -48,7 +47,7 @@ func (api *api) GetReadyToAcceptFills(ctx context.Context, params GetOrderByOrde
4847
}
4948

5049
func (api *api) SubmitSecret(ctx context.Context, params SecretInput) error {
51-
u := "/fusion-plus/relayer/v1.0/submit/secret"
50+
u := "/fusion-plus/relayer/v1.1/submit/secret"
5251

5352
body, err := json.Marshal(params)
5453
if err != nil {
@@ -70,57 +69,10 @@ func (api *api) SubmitSecret(ctx context.Context, params SecretInput) error {
7069
return nil
7170
}
7271

73-
func (api *api) GetActiveOrders(ctx context.Context, params OrderApiControllerGetActiveOrdersParams) (*GetActiveOrdersOutput, error) {
74-
u := fmt.Sprintf("/fusion/orders/v2.0/%d/order/active", api.chainId)
75-
76-
payload := common.RequestPayload{
77-
Method: "GET",
78-
Params: params,
79-
U: u,
80-
Body: nil,
81-
}
82-
83-
var response GetActiveOrdersOutput
84-
err := api.httpExecutor.ExecuteRequest(ctx, payload, &response)
85-
if err != nil {
86-
return nil, err
87-
}
88-
89-
return &response, nil
90-
}
91-
9272
func (api *api) GetQuote(ctx context.Context, params QuoterControllerGetQuoteParamsFixed) (*GetQuoteOutputFixed, error) {
93-
return nil, errors.New("fusion Plus API currently not supported")
94-
95-
//u := "/fusion-plus/quoter/v1.0/quote/receive"
96-
//
97-
//err := params.Validate()
98-
//if err != nil {
99-
// return nil, err
100-
//}
101-
//
102-
//payload := common.RequestPayload{
103-
// Method: "GET",
104-
// Params: params,
105-
// U: u,
106-
// Body: nil,
107-
//}
108-
//
109-
//var response GetQuoteOutputFixed
110-
//err = api.httpExecutor.ExecuteRequest(ctx, payload, &response)
111-
//if err != nil {
112-
// return nil, err
113-
//}
114-
//
115-
//// TODO must normalize response here
116-
//
117-
//return &response, nil
118-
}
119-
120-
func (api *api) GetQuoteWithCustomPreset(ctx context.Context, params QuoterControllerGetQuoteWithCustomPresetsParams, presetDetails QuoterControllerGetQuoteWithCustomPresetsJSONRequestBody) (*GetQuoteOutputFixed, error) {
121-
u := fmt.Sprintf("/fusion/quoter/v2.0/%d/quote/receive", api.chainId)
73+
u := "/fusion-plus/quoter/v1.1/quote/receive"
12274

123-
body, err := json.Marshal(presetDetails)
75+
err := params.Validate()
12476
if err != nil {
12577
return nil, err
12678
}
@@ -129,7 +81,7 @@ func (api *api) GetQuoteWithCustomPreset(ctx context.Context, params QuoterContr
12981
Method: "GET",
13082
Params: params,
13183
U: u,
132-
Body: body,
84+
Body: nil,
13385
}
13486

13587
var response GetQuoteOutputFixed
@@ -138,12 +90,14 @@ func (api *api) GetQuoteWithCustomPreset(ctx context.Context, params QuoterContr
13890
return nil, err
13991
}
14092

93+
// TODO must normalize response here
94+
14195
return &response, nil
14296
}
14397

14498
// PlaceOrder accepts a quote and submits it as a fusion plus order
14599
func (api *api) PlaceOrder(ctx context.Context, quoteParams QuoterControllerGetQuoteParamsFixed, quote *GetQuoteOutputFixed, orderParams OrderParams, wallet common.Wallet) (string, error) {
146-
u := "/fusion-plus/relayer/v1.0/submit"
100+
u := "/fusion-plus/relayer/v1.1/submit"
147101

148102
err := orderParams.Validate()
149103
if err != nil {

sdk-clients/fusionplus/escrowextension.go

Lines changed: 133 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ package fusionplus
33
import (
44
"bytes"
55
"encoding/binary"
6+
"encoding/hex"
67
"fmt"
8+
"log"
79
"math/big"
10+
"strings"
811

12+
"github.com/1inch/1inch-sdk-go/internal/bytesiterator"
913
"github.com/1inch/1inch-sdk-go/internal/hexadecimal"
10-
"github.com/1inch/1inch-sdk-go/sdk-clients/fusion"
1114
"github.com/1inch/1inch-sdk-go/sdk-clients/orderbook"
1215
"github.com/ethereum/go-ethereum/common"
1316
)
1417

1518
type EscrowExtension struct {
16-
fusion.Extension
19+
ExtensionFusion
1720
HashLock *HashLock
1821
DstChainId float32
1922
DstToken common.Address
@@ -24,13 +27,13 @@ type EscrowExtension struct {
2427

2528
func NewEscrowExtension(escrowParams EscrowExtensionParams) (*EscrowExtension, error) {
2629

27-
extension, err := fusion.NewExtension(escrowParams.ExtensionParams)
30+
extension, err := NewExtensionFusion(escrowParams.ExtensionParamsFusion)
2831
if err != nil {
2932
return nil, err
3033
}
3134

3235
escrowExtension := &EscrowExtension{
33-
Extension: *extension,
36+
ExtensionFusion: *extension,
3437
HashLock: escrowParams.HashLock,
3538
DstChainId: escrowParams.DstChainId,
3639
DstToken: escrowParams.DstToken,
@@ -83,6 +86,132 @@ func (e *EscrowExtension) ConvertToOrderbookExtension() (*orderbook.Extension, e
8386
}, nil
8487
}
8588

89+
// DecodeEscrowExtension decodes the input byte slice into an Extension struct using reflection.
90+
func DecodeEscrowExtension(data []byte) (*EscrowExtension, error) {
91+
92+
const extraDataCharacterLength = 320
93+
94+
// Create one extension that will be used for the Escrow extension data
95+
orderbookExtensionTruncated, err := orderbook.Decode(data)
96+
if err != nil {
97+
return nil, fmt.Errorf("error decoding extension: %v", err)
98+
}
99+
100+
// Remove the Fusion Plus Extension data before decoding
101+
orderbookExtensionTruncated.PostInteraction = orderbookExtensionTruncated.PostInteraction[:len(orderbookExtensionTruncated.PostInteraction)-extraDataCharacterLength]
102+
fusionExtension, err := FromLimitOrderExtension(orderbookExtensionTruncated)
103+
if err != nil {
104+
return &EscrowExtension{}, fmt.Errorf("error decoding escrow extension: %v", err)
105+
}
106+
107+
// Create a second extension that will be used as a Fusion extension
108+
orderbookExtension, err := orderbook.Decode(data)
109+
if err != nil {
110+
return nil, fmt.Errorf("error decoding extension: %v", err)
111+
}
112+
extraDataRaw := orderbookExtension.PostInteraction[len(orderbookExtension.PostInteraction)-extraDataCharacterLength:]
113+
extraDataBytes, err := hex.DecodeString(extraDataRaw)
114+
if err != nil {
115+
return nil, fmt.Errorf("error decoding escrow extension extra data: %v", err)
116+
}
117+
118+
// Send the final 160 bytes of the postInteraction to decodeExtraData
119+
extraData, err := decodeExtraData(extraDataBytes)
120+
if err != nil {
121+
return nil, fmt.Errorf("error decoding escrow extension extra data: %v", err)
122+
}
123+
124+
return &EscrowExtension{
125+
ExtensionFusion: *fusionExtension,
126+
HashLock: extraData.HashLock,
127+
DstChainId: extraData.DstChainId,
128+
DstToken: extraData.DstToken,
129+
SrcSafetyDeposit: fmt.Sprintf("%x", extraData.SrcSafetyDeposit),
130+
DstSafetyDeposit: fmt.Sprintf("%x", extraData.DstSafetyDeposit),
131+
TimeLocks: *extraData.TimeLocks,
132+
}, nil
133+
}
134+
135+
func decodeExtraData(data []byte) (*EscrowExtraData, error) {
136+
iter := bytesiterator.New(data)
137+
hashlockData, err := iter.NextUint256()
138+
if err != nil {
139+
log.Fatalf("Failed to read first uint256: %v", err)
140+
}
141+
142+
dstChainIdData, err := iter.NextUint256()
143+
if err != nil {
144+
log.Fatalf("Failed to read second uint256: %v", err)
145+
}
146+
147+
addressBig, err := iter.NextUint256()
148+
if err != nil {
149+
log.Fatalf("Failed to read address: %v", err)
150+
}
151+
152+
addressHex := strings.ToLower(common.BigToAddress(addressBig).Hex())
153+
154+
safetyDepositData, err := iter.NextUint256()
155+
if err != nil {
156+
log.Fatalf("Failed to read third uint256: %v", err)
157+
}
158+
159+
// Define a 128-bit mask (2^128 - 1)
160+
mask := new(big.Int)
161+
mask.Exp(big.NewInt(2), big.NewInt(128), nil).Sub(mask, big.NewInt(1))
162+
163+
srcSafetyDeposit := new(big.Int).And(safetyDepositData, mask)
164+
dstSafetyDeposit := new(big.Int).Rsh(safetyDepositData, 128)
165+
166+
timelocksData, err := iter.NextUint256()
167+
if err != nil {
168+
log.Fatalf("Failed to read fourth uint256: %v", err)
169+
}
170+
171+
timelocks, err := decodeTimeLocks(timelocksData)
172+
if err != nil {
173+
log.Fatalf("Failed to decode timelocks: %v", err)
174+
}
175+
176+
return &EscrowExtraData{
177+
HashLock: &HashLock{
178+
hashlockData.String(),
179+
},
180+
DstChainId: float32(dstChainIdData.Uint64()),
181+
DstToken: common.HexToAddress(addressHex),
182+
SrcSafetyDeposit: srcSafetyDeposit,
183+
DstSafetyDeposit: dstSafetyDeposit,
184+
TimeLocks: timelocks,
185+
}, nil
186+
}
187+
188+
// decodeTimeLocks takes a *big.Int containing the raw hex data and returns a TimeLocks struct.
189+
func decodeTimeLocks(value *big.Int) (*TimeLocks, error) {
190+
tl := &TimeLocks{}
191+
192+
// Convert big.Int to byte slice
193+
data := value.Bytes()
194+
195+
if len(data) < 32 {
196+
padded := make([]byte, 32)
197+
copy(padded[32-len(data):], data)
198+
data = padded
199+
}
200+
201+
//TODO big.Int cannot preserve leading zeroes, so decoding the deploy time is impossible atm
202+
203+
// tl.DeployTime = float32(binary.BigEndian.Uint32((data[0:4])))
204+
tl.DstCancellation = float32(binary.BigEndian.Uint32((data[4:8])))
205+
tl.DstPublicWithdrawal = float32(binary.BigEndian.Uint32((data[8:12])))
206+
tl.DstWithdrawal = float32(binary.BigEndian.Uint32((data[12:16])))
207+
tl.SrcPublicCancellation = float32(binary.BigEndian.Uint32((data[16:20])))
208+
tl.SrcCancellation = float32(binary.BigEndian.Uint32((data[20:24])))
209+
tl.SrcPublicWithdrawal = float32(binary.BigEndian.Uint32((data[24:28])))
210+
tl.SrcWithdrawal = float32(binary.BigEndian.Uint32((data[28:32])))
211+
212+
return tl, nil
213+
}
214+
86215
type EscrowExtraData struct {
87216
HashLock *HashLock
88217
DstChainId float32

0 commit comments

Comments
 (0)