Files
Prad NukalaandGitHub 13e6c3e84d Master (#1262)
* clear

* feat: Add everything

* fix: Commenht
2025-10-03 14:45:52 -04:00

192 lines
4.9 KiB
Go

package keeper
import (
"fmt"
"time"
"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/sonr-io/sonr/x/dex/types"
)
// ProvideLiquidity handles liquidity provision through ICA
func (k Keeper) ProvideLiquidity(
ctx sdk.Context,
did string,
connectionID string,
poolID uint64,
tokenA sdk.Coin,
tokenB sdk.Coin,
minShares math.Int,
) (uint64, error) {
// Get the DEX account
account, err := k.GetDEXAccount(ctx, did, connectionID)
if err != nil {
return 0, fmt.Errorf("DEX account not found: %w", err)
}
// Verify account is active
if account.Status != types.ACCOUNT_STATUS_ACTIVE {
return 0, fmt.Errorf("DEX account is not active")
}
// Create liquidity provision message for remote chain
// This is a placeholder - actual implementation would use chain-specific messages
lpMsg := &banktypes.MsgSend{
FromAddress: account.AccountAddress,
ToAddress: account.AccountAddress, // Placeholder
Amount: sdk.NewCoins(tokenA, tokenB),
}
// Send the liquidity transaction via ICA
sequence, err := k.SendDEXTransaction(
ctx,
did,
connectionID,
[]sdk.Msg{lpMsg},
fmt.Sprintf("provide_liquidity_pool_%d", poolID),
30*time.Second,
)
if err != nil {
return 0, fmt.Errorf("failed to send liquidity transaction: %w", err)
}
// Emit liquidity event
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeLiquidityProvided,
sdk.NewAttribute("did", did),
sdk.NewAttribute("connection", connectionID),
sdk.NewAttribute("pool_id", fmt.Sprintf("%d", poolID)),
sdk.NewAttribute("token_a", tokenA.String()),
sdk.NewAttribute("token_b", tokenB.String()),
sdk.NewAttribute("sequence", fmt.Sprintf("%d", sequence)),
),
)
return sequence, nil
}
// RemoveLiquidity handles liquidity removal through ICA
func (k Keeper) RemoveLiquidity(
ctx sdk.Context,
did string,
connectionID string,
poolID uint64,
shares math.Int,
minAmountA math.Int,
minAmountB math.Int,
) (uint64, error) {
// Get the DEX account
account, err := k.GetDEXAccount(ctx, did, connectionID)
if err != nil {
return 0, fmt.Errorf("DEX account not found: %w", err)
}
// Verify account is active
if account.Status != types.ACCOUNT_STATUS_ACTIVE {
return 0, fmt.Errorf("DEX account is not active")
}
// Create liquidity removal message for remote chain
// This is a placeholder - actual implementation would use chain-specific messages
removeMsg := &banktypes.MsgSend{
FromAddress: account.AccountAddress,
ToAddress: account.AccountAddress, // Placeholder
Amount: sdk.NewCoins(sdk.NewCoin("shares", shares)),
}
// Send the removal transaction via ICA
sequence, err := k.SendDEXTransaction(
ctx,
did,
connectionID,
[]sdk.Msg{removeMsg},
fmt.Sprintf("remove_liquidity_pool_%d", poolID),
30*time.Second,
)
if err != nil {
return 0, fmt.Errorf("failed to send liquidity removal transaction: %w", err)
}
// Emit removal event
ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeLiquidityRemoved,
sdk.NewAttribute("did", did),
sdk.NewAttribute("connection", connectionID),
sdk.NewAttribute("pool_id", fmt.Sprintf("%d", poolID)),
sdk.NewAttribute("shares", shares.String()),
sdk.NewAttribute("sequence", fmt.Sprintf("%d", sequence)),
),
)
return sequence, nil
}
// EstimateLPShares estimates the LP shares for given liquidity
func (k Keeper) EstimateLPShares(
ctx sdk.Context,
connectionID string,
poolID uint64,
tokenA sdk.Coin,
tokenB sdk.Coin,
) (math.Int, error) {
// This would query the remote chain for LP share estimation
// For now, return a placeholder value
totalValue := tokenA.Amount.Add(tokenB.Amount)
return totalValue.QuoRaw(2), nil // Simple average as placeholder
}
// GetPoolInfo retrieves pool information from remote chain
func (k Keeper) GetPoolInfo(
ctx sdk.Context,
connectionID string,
poolID uint64,
) (*PoolInfo, error) {
// This would query the remote chain for pool info
// For now, return placeholder data
return &PoolInfo{
PoolID: poolID,
TokenA: "uatom",
TokenB: "uosmo",
TotalShares: math.NewInt(1000000),
TotalLiquidity: sdk.NewCoins(
sdk.NewCoin("uatom", math.NewInt(500000)),
sdk.NewCoin("uosmo", math.NewInt(500000)),
),
}, nil
}
// PoolInfo represents pool information
type PoolInfo struct {
PoolID uint64
TokenA string
TokenB string
TotalShares math.Int
TotalLiquidity sdk.Coins
}
// ValidateLiquidityParameters validates liquidity parameters
func (k Keeper) ValidateLiquidityParameters(
tokenA sdk.Coin,
tokenB sdk.Coin,
minShares math.Int,
) error {
if tokenA.IsZero() || tokenB.IsZero() {
return fmt.Errorf("token amounts cannot be zero")
}
if tokenA.Denom == tokenB.Denom {
return fmt.Errorf("cannot provide liquidity with same token")
}
if minShares.IsNegative() {
return fmt.Errorf("minimum shares cannot be negative")
}
return nil
}