Merge branch 'pool-swap-endpoints' into multi-pool
This commit is contained in:
		
						commit
						b9cef2b578
					
				| @ -15,7 +15,10 @@ const ( | ||||
| 	voucherHoldingsPathPrefix  = "/api/v1/holdings" | ||||
| 	voucherTransfersPathPrefix = "/api/v1/transfers/last10" | ||||
| 	voucherDataPathPrefix      = "/api/v1/token" | ||||
| 	AliasPrefix                = "api/v1/alias" | ||||
| 	aliasPrefix                = "api/v1/alias" | ||||
| 	poolDepositPrefix          = "/api/v2/pool/deposit" | ||||
| 	poolSwapQoutePrefix        = "/api/v2/pool/quote" | ||||
| 	poolSwapPrefix             = "/api/v2/pool/swap" | ||||
| 	AliasEnsPrefix             = "/api/v1/bypass" | ||||
| ) | ||||
| 
 | ||||
| @ -36,6 +39,9 @@ var ( | ||||
| 	VoucherTransfersURL string | ||||
| 	VoucherDataURL      string | ||||
| 	CheckAliasURL       string | ||||
| 	PoolDepositURL      string | ||||
| 	PoolSwapQuoteURL    string | ||||
| 	PoolSwapURL         string | ||||
| 	AliasEnsURL         string | ||||
| ) | ||||
| 
 | ||||
| @ -72,7 +78,11 @@ func LoadConfig() error { | ||||
| 	VoucherHoldingsURL, _ = url.JoinPath(dataURLBase, voucherHoldingsPathPrefix) | ||||
| 	VoucherTransfersURL, _ = url.JoinPath(dataURLBase, voucherTransfersPathPrefix) | ||||
| 	VoucherDataURL, _ = url.JoinPath(dataURLBase, voucherDataPathPrefix) | ||||
| 	CheckAliasURL, _ = url.JoinPath(dataURLBase, AliasPrefix) | ||||
| 	CheckAliasURL, _ = url.JoinPath(dataURLBase, aliasPrefix) | ||||
| 	PoolDepositURL, _ = url.JoinPath(custodialURLBase, poolDepositPrefix) | ||||
| 	PoolSwapQuoteURL, _ = url.JoinPath(custodialURLBase, poolSwapQoutePrefix) | ||||
| 	PoolSwapURL, _ = url.JoinPath(custodialURLBase, poolSwapPrefix) | ||||
| 
 | ||||
| 	AliasEnsURL, _ = url.JoinPath(aliasEnsURLBase, AliasEnsPrefix) | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										180
									
								
								dev/api.go
									
									
									
									
									
								
							
							
						
						
									
										180
									
								
								dev/api.go
									
									
									
									
									
								
							| @ -34,6 +34,9 @@ const ( | ||||
| 	defaultDecimals               = 6 | ||||
| 	zeroAddress           string  = "0x0000000000000000000000000000000000000000" | ||||
| 	defaultVoucherBalance float64 = 500.00 | ||||
| 	cityPoolAddress       string  = "0x3b517308D858a47458aD5C8E699697C5dc91Da0F" | ||||
| 	poolName              string  = "citypool" | ||||
| 	PoolSymbol            string  = "CTY" | ||||
| ) | ||||
| 
 | ||||
| type Tx struct { | ||||
| @ -91,6 +94,14 @@ type Voucher struct { | ||||
| 	Location  string `json: "location"` | ||||
| } | ||||
| 
 | ||||
| type Pool struct { | ||||
| 	Name      string            `json: "name"` | ||||
| 	Symbol    string            `json: "symbol"` | ||||
| 	Address   string            `json: "address"` | ||||
| 	Vouchers  []Voucher         `json: "voucher"` | ||||
| 	PoolLimit map[string]string `json: "poollimit"` | ||||
| } | ||||
| 
 | ||||
| type DevAccountService struct { | ||||
| 	db               db.Db | ||||
| 	accounts         map[string]Account | ||||
| @ -106,6 +117,7 @@ type DevAccountService struct { | ||||
| 	defaultAccount   string | ||||
| 	emitterFunc      event.EmitterFunc | ||||
| 	pfx              []byte | ||||
| 	pool             Pool | ||||
| } | ||||
| 
 | ||||
| func NewDevAccountService(ctx context.Context, ss storage.StorageService) *DevAccountService { | ||||
| @ -118,6 +130,7 @@ func NewDevAccountService(ctx context.Context, ss storage.StorageService) *DevAc | ||||
| 		txs:              make(map[string]Tx), | ||||
| 		txsTrack:         make(map[string]string), | ||||
| 		autoVoucherValue: make(map[string]int), | ||||
| 		pool:             Pool{Address: cityPoolAddress, Name: poolName}, | ||||
| 		defaultAccount:   zeroAddress, | ||||
| 		pfx:              []byte("__"), | ||||
| 	} | ||||
| @ -171,6 +184,15 @@ func (das *DevAccountService) loadAccount(ctx context.Context, pubKey string, v | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (p *Pool) hasVoucher(voucherAddress string) bool { | ||||
| 	for _, value := range p.Vouchers { | ||||
| 		if value.Address == voucherAddress { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) loadTx(ctx context.Context, hsh string, v []byte) error { | ||||
| 	var mytx Tx | ||||
| 
 | ||||
| @ -193,6 +215,18 @@ func (das *DevAccountService) loadAlias(ctx context.Context, alias string, key [ | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) loadPoolInfo(ctx context.Context, name string, v []byte) error { | ||||
| 	var pool Pool | ||||
| 
 | ||||
| 	err := json.Unmarshal(v, &pool) | ||||
| 	if err != nil { | ||||
| 		return fmt.Errorf("failed to unmarshall pool info: %v", err) | ||||
| 	} | ||||
| 	das.pool = pool | ||||
| 	logg.InfoCtxf(ctx, "loaded pool info", "name", das.pool.Name, "vouchers", das.pool.Vouchers) | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte) error { | ||||
| 	var err error | ||||
| 	s := string(k) | ||||
| @ -209,6 +243,8 @@ func (das *DevAccountService) loadItem(ctx context.Context, k []byte, v []byte) | ||||
| 	} else if ss[0] == "alias" { | ||||
| 		err = das.loadAlias(ctx, ss[1], k) | ||||
| 		logg.ErrorCtxf(ctx, "loading aliases failed", "error_load_aliases", err) | ||||
| 	} else if ss[0] == "pool" { | ||||
| 		err = das.loadPoolInfo(ctx, ss[1], v) | ||||
| 	} else { | ||||
| 		logg.ErrorCtxf(ctx, "unknown double underscore key", "key", ss[0]) | ||||
| 	} | ||||
| @ -224,13 +260,13 @@ func (das *DevAccountService) loadAll(ctx context.Context) error { | ||||
| 	} | ||||
| 	for true { | ||||
| 		k, v := dumper.Next(ctx) | ||||
| 		logg.InfoCtxf(ctx, "loading all", "key", string(k), "value", string(v)) | ||||
| 		if k == nil { | ||||
| 			break | ||||
| 		} | ||||
| 		if !bytes.HasPrefix(k, das.pfx) { | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		err = das.loadItem(ctx, k, v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| @ -265,6 +301,12 @@ func (das *DevAccountService) WithAutoVoucher(ctx context.Context, symbol string | ||||
| 	return das | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) RegisterPool() { | ||||
| 	das.pool.Name = poolName | ||||
| 	das.pool.Address = cityPoolAddress | ||||
| 	das.pool.Symbol = PoolSymbol | ||||
| } | ||||
| 
 | ||||
| // TODO: add persistence for vouchers
 | ||||
| // TODO: set max balance for 0x00 address
 | ||||
| func (das *DevAccountService) AddVoucher(ctx context.Context, symbol string) error { | ||||
| @ -345,6 +387,20 @@ func (das *DevAccountService) saveAccount(ctx context.Context, acc Account) erro | ||||
| 	return das.db.Put(ctx, []byte(k), v) | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) savePoolInfo(ctx context.Context, pool Pool) error { | ||||
| 	if das.db == nil { | ||||
| 		return nil | ||||
| 	} | ||||
| 	k := das.prefixKeyFor("pool", pool.Name) | ||||
| 	v, err := json.Marshal(pool) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	das.db.SetSession("") | ||||
| 	das.db.SetPrefix(db.DATATYPE_USERDATA) | ||||
| 	return das.db.Put(ctx, []byte(k), v) | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) saveAlias(ctx context.Context, alias map[string]string) error { | ||||
| 	if das.db == nil { | ||||
| 		return fmt.Errorf("Db cannot be nil") | ||||
| @ -415,6 +471,81 @@ func (das *DevAccountService) CreateAccount(ctx context.Context) (*models.Accoun | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) PoolDeposit(ctx context.Context, amount, from, poolAddress, tokenAddress string) (*models.PoolDepositResult, error) { | ||||
| 	_, ok := das.accounts[from] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("account not found (publickey): %v", from) | ||||
| 	} | ||||
| 	sym, ok := das.vouchersAddress[tokenAddress] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("voucher address %v not found", tokenAddress) | ||||
| 	} | ||||
| 	uid, err := uuid.NewV4() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	voucher, ok := das.vouchers[sym] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("voucher address %v found but does not resolve", tokenAddress) | ||||
| 	} | ||||
| 
 | ||||
| 	das.pool.Vouchers = append(das.pool.Vouchers, voucher) | ||||
| 	das.pool.PoolLimit = map[string]string{tokenAddress: amount} | ||||
| 
 | ||||
| 	err = das.savePoolInfo(ctx, das.pool) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &models.PoolDepositResult{ | ||||
| 		TrackingId: uid.String(), | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) GetPoolSwapQuote(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapQuoteResult, error) { | ||||
| 	_, ok := das.accounts[from] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("account not found (publickey): %v", from) | ||||
| 	} | ||||
| 	//resolve the token address you are trying to swap from(fromTokenAddress)
 | ||||
| 	_, ok = das.vouchersAddress[fromTokenAddress] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("voucher address %v not found", fromTokenAddress) | ||||
| 	} | ||||
| 	p := das.pool | ||||
| 
 | ||||
| 	//check if  pool has voucher to swap  to
 | ||||
| 	if !p.hasVoucher(toTokenAddress) { | ||||
| 		return nil, fmt.Errorf("Voucher with address: %v not found in the pool", toTokenAddress) | ||||
| 	} | ||||
| 	//Return a a quote that is equal to the amount entered
 | ||||
| 	return &models.PoolSwapQuoteResult{IncludesFeesDeduction: false, OutValue: amount}, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) PoolSwap(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapResult, error) { | ||||
| 	uid, err := uuid.NewV4() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	_, ok := das.accounts[from] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("account not found (publickey): %v", from) | ||||
| 	} | ||||
| 	_, ok = das.vouchersAddress[fromTokenAddress] | ||||
| 	if !ok { | ||||
| 		return nil, fmt.Errorf("voucher address %v not found", fromTokenAddress) | ||||
| 	} | ||||
| 	p := das.pool | ||||
| 
 | ||||
| 	//check if  pool has voucher to swap  to
 | ||||
| 	if !p.hasVoucher(toTokenAddress) { | ||||
| 		return nil, fmt.Errorf("Voucher with address: %v not found in the pool", toTokenAddress) | ||||
| 	} | ||||
| 
 | ||||
| 	return &models.PoolSwapResult{TrackingId: uid.String()}, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) TrackAccountStatus(ctx context.Context, publicKey string) (*models.TrackStatusResult, error) { | ||||
| 	var ok bool | ||||
| 	_, ok = das.accounts[publicKey] | ||||
| @ -653,3 +784,50 @@ func (das *DevAccountService) RequestAlias(ctx context.Context, publicKey string | ||||
| 		Alias: alias, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) FetchTopPools(ctx context.Context) ([]dataserviceapi.PoolDetails, error) { | ||||
| 	var topPools []dataserviceapi.PoolDetails | ||||
| 
 | ||||
| 	pool := dataserviceapi.PoolDetails{ | ||||
| 		PoolName:            das.pool.Name, | ||||
| 		PoolSymbol:          das.pool.Symbol, | ||||
| 		PoolContractAdrress: das.pool.Address, | ||||
| 	} | ||||
| 
 | ||||
| 	// Add the citypool as the main pool
 | ||||
| 	topPools = append(topPools, pool) | ||||
| 
 | ||||
| 	return topPools, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) GetPoolSwappableFromVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	var swapFromList []dataserviceapi.TokenHoldings | ||||
| 
 | ||||
| 	for _, voucher := range das.pool.Vouchers { | ||||
| 		swapFromList = append(swapFromList, dataserviceapi.TokenHoldings{ | ||||
| 			ContractAddress: voucher.Address, | ||||
| 			TokenSymbol:     voucher.Symbol, | ||||
| 			TokenDecimals:   string(defaultDecimals), | ||||
| 			Balance:         fmt.Sprintf("%f", defaultVoucherBalance), | ||||
| 		}) | ||||
| 	} | ||||
| 	return swapFromList, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) GetPoolSwappableVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	swapToList := []dataserviceapi.TokenHoldings{ | ||||
| 		{ | ||||
| 			ContractAddress: "0x765DE816845861e75A25fCA122bb6898B8B1282a", | ||||
| 			TokenSymbol:     "cUSD", | ||||
| 			TokenDecimals:   "18", | ||||
| 			Balance:         "", | ||||
| 		}, | ||||
| 	} | ||||
| 	return swapToList, nil | ||||
| } | ||||
| 
 | ||||
| func (das *DevAccountService) GetSwapFromTokenMaxLimit(ctx context.Context, poolAddress, fromTokenAddress, toTokenAddress, publicKey string) (*models.MaxLimitResult, error) { | ||||
| 	return &models.MaxLimitResult{ | ||||
| 		Max: "1339482", | ||||
| 	}, nil | ||||
| } | ||||
|  | ||||
							
								
								
									
										32
									
								
								dev/data/swap_from.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								dev/data/swap_from.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| { | ||||
|     "ok": true, | ||||
|     "description": "Swap from list", | ||||
|     "result": { | ||||
|         "filtered": [ | ||||
|             { | ||||
|                 "contractAddress": "0xc7B78Ac9ACB9E025C8234621FC515bC58179dEAe", | ||||
|                 "tokenSymbol": "AMANI", | ||||
|                 "tokenDecimals": "6", | ||||
|                 "balance": "" | ||||
|             }, | ||||
|             { | ||||
|                 "contractAddress": "0xF0C3C7581b8b96B59a97daEc8Bd48247cE078674", | ||||
|                 "tokenSymbol": "AMUA", | ||||
|                 "tokenDecimals": "6", | ||||
|                 "balance": "" | ||||
|             }, | ||||
|             { | ||||
|                 "contractAddress": "0x371455a30fc62736145Bd8429Fcc6481186f235F", | ||||
|                 "tokenSymbol": "BAHARI", | ||||
|                 "tokenDecimals": "6", | ||||
|                 "balance": "" | ||||
|             }, | ||||
|             { | ||||
|                 "contractAddress": "0x7cA6113b59c24a880F382C7E12d609a6Eb05246b", | ||||
|                 "tokenSymbol": "BANGLA", | ||||
|                 "tokenDecimals": "6", | ||||
|                 "balance": "" | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
| } | ||||
							
								
								
									
										14
									
								
								dev/data/swap_to.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								dev/data/swap_to.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,14 @@ | ||||
| { | ||||
|     "ok": true, | ||||
|     "description": "Swap to list", | ||||
|     "result": { | ||||
|         "filtered": [ | ||||
|             { | ||||
|                 "contractAddress": "0x765DE816845861e75A25fCA122bb6898B8B1282a", | ||||
|                 "tokenSymbol": "cUSD", | ||||
|                 "tokenDecimals": "18", | ||||
|                 "balance": "" | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
| } | ||||
							
								
								
									
										43
									
								
								dev/data/top_pools.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								dev/data/top_pools.json
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| { | ||||
|     "ok": true, | ||||
|     "description": "Top 5 pools sorted by swaps", | ||||
|     "result": { | ||||
|         "topPools": [ | ||||
|             { | ||||
|                 "poolName": "Kenya ROLA Pool", | ||||
|                 "poolSymbol": "ROLA", | ||||
|                 "poolContractAddress": "0x48a953cA5cf5298bc6f6Af3C608351f537AAcb9e", | ||||
|                 "limiterAddress": "", | ||||
|                 "voucherRegistry": "" | ||||
|             }, | ||||
|             { | ||||
|                 "poolName": "Nairobi ROLA Pool", | ||||
|                 "poolSymbol": "NAIROBI", | ||||
|                 "poolContractAddress": "0xB0660Ac1Ee3d32ea35bc728D7CA1705Fa5A37528", | ||||
|                 "limiterAddress": "", | ||||
|                 "voucherRegistry": "" | ||||
|             }, | ||||
|             { | ||||
|                 "poolName": "Friends of Kiriba Ecosystem ", | ||||
|                 "poolSymbol": "FRIENDS", | ||||
|                 "poolContractAddress": "0xC4848263821FA02baB2181910A2eFb9CECb2c21C", | ||||
|                 "limiterAddress": "", | ||||
|                 "voucherRegistry": "" | ||||
|             }, | ||||
|             { | ||||
|                 "poolName": "Resilient Community Waqfs", | ||||
|                 "poolSymbol": "REZILIENS", | ||||
|                 "poolContractAddress": "0x1e40951d7a28147D8B4A554C60c42766C92e2Fc6", | ||||
|                 "limiterAddress": "", | ||||
|                 "voucherRegistry": "" | ||||
|             }, | ||||
|             { | ||||
|                 "poolName": "GrE Tech", | ||||
|                 "poolSymbol": "GRET", | ||||
|                 "poolContractAddress": "0xb7B9d0A264eD1a8E2418571B7AC5933C79C9c2B8", | ||||
|                 "limiterAddress": "", | ||||
|                 "voucherRegistry": "" | ||||
|             } | ||||
|         ] | ||||
|     } | ||||
| } | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @ -8,7 +8,7 @@ require ( | ||||
| 	git.grassecon.net/grassrootseconomics/visedriver v0.8.0-beta.10.0.20250122123424-6749c632b0a2 | ||||
| 	github.com/gofrs/uuid v4.4.0+incompatible | ||||
| 	github.com/grassrootseconomics/eth-custodial v1.3.0-beta | ||||
| 	github.com/grassrootseconomics/ussd-data-service v1.2.0-beta | ||||
| 	github.com/grassrootseconomics/ussd-data-service v1.4.0-beta | ||||
| 	github.com/stretchr/testify v1.9.0 | ||||
| ) | ||||
| 
 | ||||
|  | ||||
							
								
								
									
										2
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.sum
									
									
									
									
									
								
							| @ -18,6 +18,8 @@ github.com/grassrootseconomics/eth-custodial v1.3.0-beta h1:twrMBhl89GqDUL9PlkzQ | ||||
| github.com/grassrootseconomics/eth-custodial v1.3.0-beta/go.mod h1:7uhRcdnJplX4t6GKCEFkbeDhhjlcaGJeJqevbcvGLZo= | ||||
| github.com/grassrootseconomics/ussd-data-service v1.2.0-beta h1:fn1gwbWIwHVEBtUC2zi5OqTlfI/5gU1SMk0fgGixIXk= | ||||
| github.com/grassrootseconomics/ussd-data-service v1.2.0-beta/go.mod h1:omfI0QtUwIdpu9gMcUqLMCG8O1XWjqJGBx1qUMiGWC0= | ||||
| github.com/grassrootseconomics/ussd-data-service v1.4.0-beta h1:4fMd/3h2ZIhRg4GdHQmRw5FfD3MpJvFNNJQo+Q27f5M= | ||||
| github.com/grassrootseconomics/ussd-data-service v1.4.0-beta/go.mod h1:9sGnorpKaK76FmOGXoh/xv7x5siSFNYdXxQo9BKW4DI= | ||||
| github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4 h1:U4kkNYryi/qfbBF8gh7Vsbuz+cVmhf5kt6pE9bYYyLo= | ||||
| github.com/graygnuorg/go-gdbm v0.0.0-20220711140707-71387d66dce4/go.mod h1:zpZDgZFzeq9s0MIeB1P50NIEWDFFHSFBohI/NbaTD/Y= | ||||
| github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= | ||||
|  | ||||
							
								
								
									
										18
									
								
								models/pool_swap_response.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								models/pool_swap_response.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| package models | ||||
| 
 | ||||
| type PoolDepositResult struct { | ||||
| 	TrackingId string `json:"trackingId"` | ||||
| } | ||||
| 
 | ||||
| type PoolSwapQuoteResult struct { | ||||
| 	IncludesFeesDeduction bool   `json:"includesFeesDeduction"` | ||||
| 	OutValue              string `json:"outValue"` | ||||
| } | ||||
| 
 | ||||
| type PoolSwapResult struct { | ||||
| 	TrackingId string `json:"trackingId"` | ||||
| } | ||||
| 
 | ||||
| type MaxLimitResult struct { | ||||
| 	Max string `json:"max"` | ||||
| } | ||||
| @ -17,4 +17,11 @@ type AccountService interface { | ||||
| 	TokenTransfer(ctx context.Context, amount, from, to, tokenAddress string) (*models.TokenTransferResponse, error) | ||||
| 	CheckAliasAddress(ctx context.Context, alias string) (*models.AliasAddress, error) | ||||
| 	RequestAlias(ctx context.Context, hint string, publicKey string) (*models.RequestAliasResult, error) | ||||
| 	PoolDeposit(ctx context.Context, amount, from, poolAddress, tokenAddress string) (*models.PoolDepositResult, error) | ||||
| 	FetchTopPools(ctx context.Context) ([]dataserviceapi.PoolDetails, error) | ||||
| 	GetPoolSwappableFromVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) | ||||
| 	GetPoolSwappableVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) | ||||
| 	GetPoolSwapQuote(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapQuoteResult, error) | ||||
| 	PoolSwap(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapResult, error) | ||||
| 	GetSwapFromTokenMaxLimit(ctx context.Context, poolAddress, fromTokenAddress, toTokenAddress, publicKey string) (*models.MaxLimitResult, error) | ||||
| } | ||||
|  | ||||
| @ -263,6 +263,106 @@ func resolveAliasAddress(ctx context.Context, alias string) (*models.AliasAddres | ||||
| 	return &models.AliasAddress{Address: aliasEnsResult.Address}, err | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) FetchTopPools(ctx context.Context) ([]dataserviceapi.PoolDetails, error) { | ||||
| 	svc := dev.NewDevAccountService(ctx, as.SS) | ||||
| 	return svc.FetchTopPools(ctx) | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) PoolDeposit(ctx context.Context, amount, from, poolAddress, tokenAddress string) (*models.PoolDepositResult, error) { | ||||
| 	var r models.PoolDepositResult | ||||
| 
 | ||||
| 	//pool deposit payload
 | ||||
| 	payload := map[string]string{ | ||||
| 		"amount":       amount, | ||||
| 		"from":         from, | ||||
| 		"poolAddress":  poolAddress, | ||||
| 		"tokenAddress": tokenAddress, | ||||
| 	} | ||||
| 
 | ||||
| 	payloadBytes, err := json.Marshal(payload) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req, err := http.NewRequest("POST", config.TokenTransferURL, bytes.NewBuffer(payloadBytes)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	_, err = doRequest(ctx, req, &r) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &r, nil | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) GetPoolSwapQuote(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapQuoteResult, error) { | ||||
| 	var r models.PoolSwapQuoteResult | ||||
| 
 | ||||
| 	//pool swap quote payload
 | ||||
| 	payload := map[string]string{ | ||||
| 		"amount":           amount, | ||||
| 		"from":             from, | ||||
| 		"fromTokenAddress": fromTokenAddress, | ||||
| 		"poolAddress":      poolAddress, | ||||
| 		"toTokenAddress":   toTokenAddress, | ||||
| 	} | ||||
| 
 | ||||
| 	payloadBytes, err := json.Marshal(payload) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req, err := http.NewRequest("POST", config.PoolSwapQuoteURL, bytes.NewBuffer(payloadBytes)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	_, err = doRequest(ctx, req, &r) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &r, nil | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) GetPoolSwappableFromVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	svc := dev.NewDevAccountService(ctx, as.SS) | ||||
| 	return svc.GetPoolSwappableFromVouchers(ctx, poolAddress, publicKey) | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) GetPoolSwappableVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	svc := dev.NewDevAccountService(ctx, as.SS) | ||||
| 	return svc.GetPoolSwappableVouchers(ctx, poolAddress, publicKey) | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) PoolSwap(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapResult, error) { | ||||
| 	var r models.PoolSwapResult | ||||
| 
 | ||||
| 	//swap payload
 | ||||
| 	payload := map[string]string{ | ||||
| 		"amount":           amount, | ||||
| 		"from":             from, | ||||
| 		"fromTokenAddress": fromTokenAddress, | ||||
| 		"poolAddress":      poolAddress, | ||||
| 		"toTokenAddress":   toTokenAddress, | ||||
| 	} | ||||
| 
 | ||||
| 	payloadBytes, err := json.Marshal(payload) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	req, err := http.NewRequest("POST", config.PoolSwapQuoteURL, bytes.NewBuffer(payloadBytes)) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	_, err = doRequest(ctx, req, &r) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return &r, nil | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) GetSwapFromTokenMaxLimit(ctx context.Context, poolAddress, fromTokenAddress, toTokenAddress, publicKey string) (*models.MaxLimitResult, error) { | ||||
| 	svc := dev.NewDevAccountService(ctx, as.SS) | ||||
| 	return svc.GetSwapFromTokenMaxLimit(ctx, poolAddress, fromTokenAddress, toTokenAddress, publicKey) | ||||
| } | ||||
| 
 | ||||
| func (as *HTTPAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) { | ||||
| 	if as.SS == nil { | ||||
| 		return nil, fmt.Errorf("The storage service cannot be nil") | ||||
|  | ||||
| @ -57,3 +57,38 @@ func (m MockAccountService) RequestAlias(ctx context.Context, publicKey string, | ||||
| 	args := m.Called(publicKey, hint) | ||||
| 	return args.Get(0).(*models.RequestAliasResult), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) PoolDeposit(ctx context.Context, amount, from, poolAddress, tokenAddress string) (*models.PoolDepositResult, error) { | ||||
| 	args := m.Called(amount, from, poolAddress, tokenAddress) | ||||
| 	return args.Get(0).(*models.PoolDepositResult), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) FetchTopPools(ctx context.Context) ([]dataserviceapi.PoolDetails, error) { | ||||
| 	args := m.Called() | ||||
| 	return args.Get(0).([]dataserviceapi.PoolDetails), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) GetPoolSwappableFromVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	args := m.Called(poolAddress, publicKey) | ||||
| 	return args.Get(0).([]dataserviceapi.TokenHoldings), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) GetPoolSwappableVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	args := m.Called(poolAddress, publicKey) | ||||
| 	return args.Get(0).([]dataserviceapi.TokenHoldings), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) GetPoolSwapQuote(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapQuoteResult, error) { | ||||
| 	args := m.Called(amount, from, fromTokenAddress, poolAddress, toTokenAddress) | ||||
| 	return args.Get(0).(*models.PoolSwapQuoteResult), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) PoolSwap(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapResult, error) { | ||||
| 	args := m.Called(amount, from, fromTokenAddress, poolAddress, toTokenAddress) | ||||
| 	return args.Get(0).(*models.PoolSwapResult), args.Error(1) | ||||
| } | ||||
| 
 | ||||
| func (m MockAccountService) GetSwapFromTokenMaxLimit(ctx context.Context, poolAddress, fromTokenAddress, toTokenAddress, publicKey string) (*models.MaxLimitResult, error) { | ||||
| 	args := m.Called(poolAddress, fromTokenAddress, toTokenAddress, publicKey) | ||||
| 	return args.Get(0).(*models.MaxLimitResult), args.Error(1) | ||||
| } | ||||
|  | ||||
| @ -57,6 +57,10 @@ func (tas *TestAccountService) TokenTransfer(ctx context.Context, amount, from, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) PoolDeposit(ctx context.Context, amount, from, poolAddress, tokenAddress string) (*models.PoolDepositResult, error) { | ||||
| 	return &models.PoolDepositResult{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) CheckAliasAddress(ctx context.Context, alias string) (*models.AliasAddress, error) { | ||||
| 	return &models.AliasAddress{}, nil | ||||
| } | ||||
| @ -64,3 +68,27 @@ func (m TestAccountService) CheckAliasAddress(ctx context.Context, alias string) | ||||
| func (m TestAccountService) RequestAlias(ctx context.Context, publicKey string, hint string) (*models.RequestAliasResult, error) { | ||||
| 	return &models.RequestAliasResult{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) FetchTopPools(ctx context.Context) ([]dataserviceapi.PoolDetails, error) { | ||||
| 	return []dataserviceapi.PoolDetails{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) GetPoolSwappableFromVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	return []dataserviceapi.TokenHoldings{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) GetPoolSwappableVouchers(ctx context.Context, poolAddress, publicKey string) ([]dataserviceapi.TokenHoldings, error) { | ||||
| 	return []dataserviceapi.TokenHoldings{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) GetPoolSwapQuote(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapQuoteResult, error) { | ||||
| 	return &models.PoolSwapQuoteResult{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) PoolSwap(ctx context.Context, amount, from, fromTokenAddress, poolAddress, toTokenAddress string) (*models.PoolSwapResult, error) { | ||||
| 	return &models.PoolSwapResult{}, nil | ||||
| } | ||||
| 
 | ||||
| func (m TestAccountService) GetSwapFromTokenMaxLimit(ctx context.Context, poolAddress, fromTokenAddress, toTokenAddress, publicKey string) (*models.MaxLimitResult, error) { | ||||
| 	return &models.MaxLimitResult{}, nil | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user