Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: global struct changes #39

Merged
merged 8 commits into from
Mar 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions aggregation/aggregation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package aggregation

import (
"github.com/1inch/1inch-sdk-go/internal/common"
"github.com/1inch/1inch-sdk-go/internal/http_executor"
"net/url"
)

type api struct {
httpExecutor common.HttpExecutor
}

type Client struct {
api
}

// todo: not done
func DefaultClient() *Client {
// todo: move to input params, that will be validated before
u, _ := url.Parse("https://api.1inch.dev")
executor := http_executor.DefaultHttpClient(u, "")
api := api{
httpExecutor: &executor,
}
c := Client{
api,
}
return &c
}
186 changes: 186 additions & 0 deletions aggregation/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package aggregation

import (
"context"
"fmt"
"github.com/1inch/1inch-sdk-go/internal/common"
)

// GetApproveAllowance returns the allowance the 1inch router has to spend a token on behalf of a wallet
func (api *api) GetApproveAllowance(ctx context.Context, params ApproveAllowanceParams) (*AllowanceResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/approve/allowance", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
Params: params.ApproveControllerGetAllowanceParams,
U: u,
Body: nil,
}

var allowanceResponse AllowanceResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &allowanceResponse)
if err != nil {
return nil, err
}

return &allowanceResponse, nil
}

// GetApproveSpender returns the address of the 1inch router contract
func (api *api) GetApproveSpender(ctx context.Context, params ApproveSpenderParams) (*SpenderResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/approve/spender", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
U: u,
Params: nil,
Body: nil,
}

var spender SpenderResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &spender)
if err != nil {
return nil, err
}

return &spender, nil
}

// GetApproveTransaction returns the transaction data for approving the 1inch router to spend a token on behalf of a wallet
func (api *api) GetApproveTransaction(ctx context.Context, params ApproveTransactionParams) (*ApproveCallDataResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/approve/transaction", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
Params: params.ApproveControllerGetCallDataParams,
U: u,
Body: nil,
}

var approveCallData ApproveCallDataResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &approveCallData)
if err != nil {
return nil, err
}
return &approveCallData, nil
}

// GetLiquiditySources returns all liquidity sources tracked by the 1inch Aggregation Protocol for a given chain
func (api *api) GetLiquiditySources(ctx context.Context, params GetLiquiditySourcesParams) (*ProtocolsResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/liquidity-sources", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
Params: nil,
U: u,
Body: nil,
}

var liquiditySources ProtocolsResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &liquiditySources)
if err != nil {
return nil, err
}

return &liquiditySources, nil
}

// GetQuote returns the quote for a potential swap through the Aggregation Protocol
func (api *api) GetQuote(ctx context.Context, params GetQuoteParams) (*QuoteResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/quote", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
Params: params.AggregationControllerGetQuoteParams,
U: u,
}

var quote QuoteResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &quote)
if err != nil {
return nil, err
}

return &quote, nil
}

// GetSwap returns a swap quote with transaction data that can be used to execute a swap through the Aggregation Protocol
func (api *api) GetSwap(ctx context.Context, params GetSwapParams) (*SwapResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/swap", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

// Token info is used by certain parts of the SDK and more info by default is helpful to integrators
// Because we use generated structs with concrete types, extra data is forced on regardless of what the user passes in.
params.IncludeTokensInfo = true
params.IncludeGas = true
params.IncludeProtocols = true

payload := common.RequestPayload{
Method: "GET",
Params: params.AggregationControllerGetSwapParams,
U: u,
Body: nil,
}

var swapResponse SwapResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &swapResponse)
if err != nil {
return nil, err
}

return &swapResponse, nil
}

// GetTokens returns all tokens officially tracked by the 1inch Aggregation Protocol for a given chain
func (api *api) GetTokens(ctx context.Context, params GetTokensParams) (*TokensResponse, error) {
u := fmt.Sprintf("/swap/v5.2/%d/tokens", params.ChainId)

err := params.Validate()
if err != nil {
return nil, err
}

payload := common.RequestPayload{
Method: "GET",
Params: nil,
U: u,
Body: nil,
}

var tokens TokensResponse
err = api.httpExecutor.ExecuteRequest(ctx, payload, &tokens)
if err != nil {
return nil, err
}

return &tokens, nil
}
107 changes: 107 additions & 0 deletions aggregation/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package aggregation

import (
"context"
"fmt"
"github.com/1inch/1inch-sdk-go/internal/common"
"github.com/1inch/1inch-sdk-go/internal/helpers/consts/chains"
"reflect"
"testing"
)

type MockHttpExecutor struct {
Called bool
ExecuteErr error
ResponseObj interface{}
}

func (m *MockHttpExecutor) ExecuteRequest(ctx context.Context, payload common.RequestPayload, v interface{}) error {
m.Called = true
if m.ExecuteErr != nil {
return m.ExecuteErr
}

// Copy the mock response object to v
if m.ResponseObj != nil && v != nil {
rv := reflect.ValueOf(v)
if rv.Kind() != reflect.Ptr || rv.IsNil() {
return fmt.Errorf("v must be a non-nil pointer")
}
reflect.Indirect(rv).Set(reflect.ValueOf(m.ResponseObj))
}
return nil
}

func TestGetQuote(t *testing.T) {
ctx := context.Background()

mockedResp := QuoteResponse{
FromToken: &TokenInfo{
Address: "0x6b175474e89094c44da98b954eedeac495271d0f",
Symbol: "DAI",
Name: "Dai Stablecoin",
Decimals: 18,
LogoURI: "https://tokens.1inch.io/0x6b175474e89094c44da98b954eedeac495271d0f.png",
Tags: []string{
"PEG:USD",
"tokens",
},
},
Gas: 181416,
ToAmount: "289424403260095",
ToToken: &TokenInfo{
Address: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
Symbol: "WETH",
Name: "Wrapped Ether",
Decimals: 18,
LogoURI: "https://tokens.1inch.io/0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2.png",
Tags: []string{
"PEG:ETH",
"tokens",
},
},
Protocols: [][][]SelectedProtocol{
{
{
{
FromTokenAddress: "0x6b175474e89094c44da98b954eedeac495271d0f",
Name: "SUSHI",
Part: 100,
ToTokenAddress: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
},
},
},
},
}

mockExecutor := &MockHttpExecutor{
ResponseObj: mockedResp,
}
api := api{httpExecutor: mockExecutor}

params := GetQuoteParams{
ChainId: chains.Ethereum,
AggregationControllerGetQuoteParams: AggregationControllerGetQuoteParams{
Src: "0x6b175474e89094c44da98b954eedeac495271d0f",
Dst: "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",
Amount: "1000000000000000000",
IncludeTokensInfo: true,
IncludeGas: true,
IncludeProtocols: true,
},
}

quote, err := api.GetQuote(ctx, params)
if err != nil {
t.Fatalf("GetQuote returned an error: %v", err)
}

if !mockExecutor.Called {
t.Errorf("Expected ExecuteRequest to be called")
}

expectedQuote := mockedResp
if !reflect.DeepEqual(*quote, expectedQuote) {
t.Errorf("Expected quote to be %+v, got %+v", expectedQuote, *quote)
}
}
Loading