diff --git a/.coverage b/.coverage index e1a528b..7fc6300 100644 Binary files a/.coverage and b/.coverage differ diff --git a/README.md b/README.md index 5eff862..0792d9b 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,6 @@ By default, Jupiter Ultra provides gasless swaps when the user has < 0.01 SOL an This plugin enables Solana Agent to swap tokens using DFlow's Swap API with a Solana keypair. DFlow offers faster swaps compared to Jupiter Ultra with competitive rates. -**Note:** Platform fees are not supported with DFlow. Use Solana Ultra (Jupiter) if you need to collect fees on swaps. - ```python config = { "tools": { @@ -113,6 +111,8 @@ config = { "private_key": "my-private-key", # Required - base58 string "payer_private_key": "payer-private-key", # Optional - for gasless/sponsored transactions "rpc_url": "https://api.mainnet-beta.solana.com", # Optional - RPC URL (defaults to mainnet) + "platform_fee_bps": 50, # Optional - fee in basis points (50 = 0.5%) + "referral_account": "your-wallet-pubkey", # Optional - wallet to receive fees (DFlow creates ATAs automatically) }, }, } @@ -121,6 +121,7 @@ config = { **Features:** - **Fast Swaps**: DFlow typically executes faster than Jupiter Ultra - **Gasless Transactions**: Optionally sponsor gas fees for users via `payer_private_key` +- **Platform Fees**: Collect fees on swaps via `referral_account` - DFlow auto-creates token accounts ### Jupiter Trigger @@ -374,6 +375,8 @@ config = { "signing_key": "wallet-auth:your-signing-key", # Required - your Privy wallet authorization signing key "rpc_url": "https://mainnet.helius-rpc.com/?api-key=YOUR_KEY", # Required - Helius recommended for priority fees "payer_private_key": "payer-private-key", # Optional - for gasless/sponsored transactions + "platform_fee_bps": 50, # Optional - fee in basis points (50 = 0.5%) + "referral_account": "your-wallet-pubkey", # Optional - wallet to receive fees (DFlow creates ATAs automatically) }, }, } @@ -384,6 +387,7 @@ config = { - **Privy Delegated Wallets**: Seamless user experience with embedded wallets - **Helius Priority Fees**: Uses Helius priority fee estimation for reliable transaction landing - **Gasless Transactions**: Optionally sponsor gas fees for users via `payer_private_key` +- **Platform Fees**: Collect fees on swaps via `referral_account` - DFlow auto-creates token accounts **RPC URL (Required):** Helius RPC is strongly recommended (`https://mainnet.helius-rpc.com/?api-key=YOUR_KEY`). Helius provides priority fee estimation and better blockhash handling, which significantly improves transaction success rates. Get a free API key at [helius.dev](https://helius.dev). diff --git a/pyproject.toml b/pyproject.toml index 584e9f3..1e6416c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "sakit" -version = "14.1.4" +version = "14.1.5" description = "Solana Agent Kit" authors = ["Bevan Hunt "] license = "MIT" diff --git a/sakit/privy_dflow_swap.py b/sakit/privy_dflow_swap.py index 7dcc144..eeefa64 100644 --- a/sakit/privy_dflow_swap.py +++ b/sakit/privy_dflow_swap.py @@ -8,8 +8,8 @@ Transactions are signed via Privy's signTransaction and sent via Helius RPC for priority fees and reliable blockhash handling. -Note: Platform fees are not supported. Use Jupiter Ultra (privy_ultra) if you -need to collect fees on swaps. +Supports platform fee collection via referralAccount - DFlow auto-creates the +required token accounts to receive fees in the output token. """ import base64 @@ -210,6 +210,8 @@ def __init__(self, registry: Optional[ToolRegistry] = None): self._signing_key: Optional[str] = None self._payer_private_key: Optional[str] = None self._rpc_url: Optional[str] = None + self._platform_fee_bps: Optional[int] = None + self._referral_account: Optional[str] = None def get_schema(self) -> Dict[str, Any]: return { @@ -250,6 +252,9 @@ def configure(self, config: Dict[str, Any]) -> None: self._payer_private_key = tool_cfg.get("payer_private_key") # RPC URL for sending transactions (Helius recommended for priority fees) self._rpc_url = tool_cfg.get("rpc_url") + # Platform fee configuration (uses referralAccount for auto ATA creation) + self._platform_fee_bps = tool_cfg.get("platform_fee_bps") + self._referral_account = tool_cfg.get("referral_account") async def execute( # pragma: no cover self, @@ -302,6 +307,8 @@ async def execute( # pragma: no cover user_public_key=public_key, slippage_bps=slippage_bps if slippage_bps > 0 else None, sponsor=sponsor, + platform_fee_bps=self._platform_fee_bps, + referral_account=self._referral_account, ) if not order_result.success: diff --git a/sakit/solana_dflow_swap.py b/sakit/solana_dflow_swap.py index 7d71d34..7969aa0 100644 --- a/sakit/solana_dflow_swap.py +++ b/sakit/solana_dflow_swap.py @@ -3,8 +3,8 @@ Enables fast token swaps using DFlow's Swap API with a Solana keypair. DFlow offers faster swaps compared to Jupiter Ultra with similar liquidity. -Note: Platform fees are not supported. Use Jupiter Ultra (solana_ultra) if you -need to collect fees on swaps. +Supports platform fee collection via referralAccount - DFlow auto-creates the +required token accounts to receive fees in the output token. """ import base64 @@ -80,6 +80,8 @@ def __init__(self, registry: Optional[ToolRegistry] = None): self._private_key: Optional[str] = None self._payer_private_key: Optional[str] = None self._rpc_url: Optional[str] = None + self._platform_fee_bps: Optional[int] = None + self._referral_account: Optional[str] = None def get_schema(self) -> Dict[str, Any]: return { @@ -113,6 +115,9 @@ def configure(self, config: Dict[str, Any]) -> None: self._private_key = tool_cfg.get("private_key") self._payer_private_key = tool_cfg.get("payer_private_key") self._rpc_url = tool_cfg.get("rpc_url") or DEFAULT_RPC_URL + # Platform fee configuration (uses referralAccount for auto ATA creation) + self._platform_fee_bps = tool_cfg.get("platform_fee_bps") + self._referral_account = tool_cfg.get("referral_account") async def execute( self, @@ -146,6 +151,8 @@ async def execute( user_public_key=user_pubkey, slippage_bps=slippage_bps if slippage_bps > 0 else None, sponsor=sponsor, + platform_fee_bps=self._platform_fee_bps, + referral_account=self._referral_account, ) if not order_result.success: diff --git a/tests/test_privy_dflow_swap_tool.py b/tests/test_privy_dflow_swap_tool.py index 7c8df95..3e5ba8b 100644 --- a/tests/test_privy_dflow_swap_tool.py +++ b/tests/test_privy_dflow_swap_tool.py @@ -67,6 +67,8 @@ def test_configure_sets_credentials(self): "signing_key": "test_signing_key", "payer_private_key": "payer_key", "rpc_url": "https://custom-rpc.com", + "platform_fee_bps": 50, + "referral_account": "RefAcct123", } } } @@ -78,6 +80,8 @@ def test_configure_sets_credentials(self): assert tool._signing_key == "test_signing_key" assert tool._payer_private_key == "payer_key" assert tool._rpc_url == "https://custom-rpc.com" + assert tool._platform_fee_bps == 50 + assert tool._referral_account == "RefAcct123" class TestPrivyDFlowSwapToolExecute: diff --git a/tests/test_solana_dflow_swap_tool.py b/tests/test_solana_dflow_swap_tool.py index f6715dd..94bf9e4 100644 --- a/tests/test_solana_dflow_swap_tool.py +++ b/tests/test_solana_dflow_swap_tool.py @@ -71,6 +71,8 @@ def test_configure_sets_credentials(self): "private_key": "test_private_key", "payer_private_key": "payer_key", "rpc_url": "https://custom-rpc.com", + "platform_fee_bps": 50, + "referral_account": "RefAcct123", } } } @@ -80,6 +82,8 @@ def test_configure_sets_credentials(self): assert tool._private_key == "test_private_key" assert tool._payer_private_key == "payer_key" assert tool._rpc_url == "https://custom-rpc.com" + assert tool._platform_fee_bps == 50 + assert tool._referral_account == "RefAcct123" def test_configure_uses_default_rpc_url(self): """Should use default RPC URL when not provided."""