Skip to content
Open
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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
dist
node_modules
node_modules
.elizadb-test
.turbo
.cursor
158 changes: 156 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,157 @@
# plugin-jupiter
# @elizaos/plugin-jupiter

This PR adds a jupiter service and functionality for executing swaps with jupiter
A powerful ElizaOS plugin that integrates Jupiter DEX functionality for seamless token swaps on Solana.

## Features

- **Token Swaps**: Get quotes and execute swaps through Jupiter's aggregator
- **Price Discovery**: Real-time token prices with configurable quote tokens
- **Route Optimization**: Find the best swap routes across multiple DEXs
- **Price Impact Analysis**: Calculate and monitor price impact for trades
- **Slippage Management**: Automatic slippage recommendations based on liquidity
- **Gas Estimation**: Accurate transaction fee calculations
- **Arbitrage Detection**: Discover profitable trading paths
- **Transaction Confirmation**: Robust retry logic for transaction confirmation

## Installation

```bash
npm install @elizaos/plugin-jupiter
```

## Usage

### Basic Setup

```typescript
import { jupiterPlugin } from '@elizaos/plugin-jupiter';

// Register the plugin with your ElizaOS agent
const agent = new Agent({
plugins: [jupiterPlugin],
// ... other configuration
});
```

### Service API

The Jupiter plugin provides a comprehensive service for interacting with Jupiter DEX:

```typescript
// Get a swap quote
const quote = await jupiterService.getQuote({
inputMint: 'So11111111111111111111111111111111111111112', // SOL
outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
amount: 1000000000, // 1 SOL (9 decimals)
slippageBps: 50, // 0.5% slippage
});

// Execute a swap
const swapResult = await jupiterService.executeSwap({
quoteResponse: quote,
userPublicKey: 'YourPublicKeyHere',
slippageBps: 50,
});

// Get current token price
const price = await jupiterService.getTokenPrice(
'So11111111111111111111111111111111111111112', // SOL
'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v', // USDC
9 // SOL decimals
);
```

### Advanced Features

#### Price Impact Calculation
```typescript
const priceImpact = await jupiterService.getPriceImpact({
inputMint: 'SOL_MINT',
outputMint: 'USDC_MINT',
amount: 1000000000,
});
```

#### Optimal Slippage Detection
```typescript
const recommendedSlippage = await jupiterService.findBestSlippage({
inputMint: 'SOL_MINT',
outputMint: 'USDC_MINT',
amount: 1000000000,
});
```

#### Arbitrage Path Discovery
```typescript
const arbitragePaths = await jupiterService.findArbitragePaths({
startingMint: 'USDC_MINT',
amount: 1000000000,
maxHops: 3,
});
```

## Configuration

The plugin can be configured through environment variables or runtime settings:

| Variable | Description | Default |
|----------|-------------|---------|
| `JUPITER_PLATFORM_FEE_BPS` | Platform fee in basis points | 200 (2%) |
| `JUPITER_PRIORITY_FEE` | Priority fee in microlamports | 5000000 |
| `JUPITER_API_URL` | Jupiter API endpoint | https://public.jupiterapi.com |

## Supported Tokens

The plugin works with any SPL tokens supported by Jupiter. Common tokens include:
- **SOL**: `So11111111111111111111111111111111111111112`
- **USDC**: `EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v`
- **USDT**: `Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB`

## Error Handling

The plugin includes comprehensive error handling for common scenarios:
- Network failures with automatic retry
- API rate limiting
- Invalid token addresses
- Insufficient liquidity
- Transaction confirmation timeouts

## Testing

The plugin includes extensive test coverage:

```bash
# Run unit tests
npm run test:unit

# Run all tests
npm test

# Check coverage (98.37%)
npm run test:coverage
```

## Architecture

The plugin follows ElizaOS best practices:
- **Service Pattern**: Core functionality encapsulated in `JupiterService`
- **Dependency Injection**: Runtime passed to service constructor
- **Lifecycle Management**: Proper start/stop methods
- **Error Handling**: Comprehensive error handling and logging
- **Type Safety**: Full TypeScript support

## Contributing

Contributions are welcome! Please ensure:
1. All tests pass
2. Code coverage remains above 95%
3. TypeScript types are properly defined
4. Follow the existing code style

## License

MIT

## Support

For issues and feature requests, please visit the [GitHub repository](https://github.com/elizaos-plugins/plugin-jupiter).
224 changes: 224 additions & 0 deletions coverage/base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
body, html {
margin:0; padding: 0;
height: 100%;
}
body {
font-family: Helvetica Neue, Helvetica, Arial;
font-size: 14px;
color:#333;
}
.small { font-size: 12px; }
*, *:after, *:before {
-webkit-box-sizing:border-box;
-moz-box-sizing:border-box;
box-sizing:border-box;
}
h1 { font-size: 20px; margin: 0;}
h2 { font-size: 14px; }
pre {
font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace;
margin: 0;
padding: 0;
-moz-tab-size: 2;
-o-tab-size: 2;
tab-size: 2;
}
a { color:#0074D9; text-decoration:none; }
a:hover { text-decoration:underline; }
.strong { font-weight: bold; }
.space-top1 { padding: 10px 0 0 0; }
.pad2y { padding: 20px 0; }
.pad1y { padding: 10px 0; }
.pad2x { padding: 0 20px; }
.pad2 { padding: 20px; }
.pad1 { padding: 10px; }
.space-left2 { padding-left:55px; }
.space-right2 { padding-right:20px; }
.center { text-align:center; }
.clearfix { display:block; }
.clearfix:after {
content:'';
display:block;
height:0;
clear:both;
visibility:hidden;
}
.fl { float: left; }
@media only screen and (max-width:640px) {
.col3 { width:100%; max-width:100%; }
.hide-mobile { display:none!important; }
}

.quiet {
color: #7f7f7f;
color: rgba(0,0,0,0.5);
}
.quiet a { opacity: 0.7; }

.fraction {
font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace;
font-size: 10px;
color: #555;
background: #E8E8E8;
padding: 4px 5px;
border-radius: 3px;
vertical-align: middle;
}

div.path a:link, div.path a:visited { color: #333; }
table.coverage {
border-collapse: collapse;
margin: 10px 0 0 0;
padding: 0;
}

table.coverage td {
margin: 0;
padding: 0;
vertical-align: top;
}
table.coverage td.line-count {
text-align: right;
padding: 0 5px 0 20px;
}
table.coverage td.line-coverage {
text-align: right;
padding-right: 10px;
min-width:20px;
}

table.coverage td span.cline-any {
display: inline-block;
padding: 0 5px;
width: 100%;
}
.missing-if-branch {
display: inline-block;
margin-right: 5px;
border-radius: 3px;
position: relative;
padding: 0 4px;
background: #333;
color: yellow;
}

.skip-if-branch {
display: none;
margin-right: 10px;
position: relative;
padding: 0 4px;
background: #ccc;
color: white;
}
.missing-if-branch .typ, .skip-if-branch .typ {
color: inherit !important;
}
.coverage-summary {
border-collapse: collapse;
width: 100%;
}
.coverage-summary tr { border-bottom: 1px solid #bbb; }
.keyline-all { border: 1px solid #ddd; }
.coverage-summary td, .coverage-summary th { padding: 10px; }
.coverage-summary tbody { border: 1px solid #bbb; }
.coverage-summary td { border-right: 1px solid #bbb; }
.coverage-summary td:last-child { border-right: none; }
.coverage-summary th {
text-align: left;
font-weight: normal;
white-space: nowrap;
}
.coverage-summary th.file { border-right: none !important; }
.coverage-summary th.pct { }
.coverage-summary th.pic,
.coverage-summary th.abs,
.coverage-summary td.pct,
.coverage-summary td.abs { text-align: right; }
.coverage-summary td.file { white-space: nowrap; }
.coverage-summary td.pic { min-width: 120px !important; }
.coverage-summary tfoot td { }

.coverage-summary .sorter {
height: 10px;
width: 7px;
display: inline-block;
margin-left: 0.5em;
background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent;
}
.coverage-summary .sorted .sorter {
background-position: 0 -20px;
}
.coverage-summary .sorted-desc .sorter {
background-position: 0 -10px;
}
.status-line { height: 10px; }
/* yellow */
.cbranch-no { background: yellow !important; color: #111; }
/* dark red */
.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 }
.low .chart { border:1px solid #C21F39 }
.highlighted,
.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{
background: #C21F39 !important;
}
/* medium red */
.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE }
/* light red */
.low, .cline-no { background:#FCE1E5 }
/* light green */
.high, .cline-yes { background:rgb(230,245,208) }
/* medium green */
.cstat-yes { background:rgb(161,215,106) }
/* dark green */
.status-line.high, .high .cover-fill { background:rgb(77,146,33) }
.high .chart { border:1px solid rgb(77,146,33) }
/* dark yellow (gold) */
.status-line.medium, .medium .cover-fill { background: #f9cd0b; }
.medium .chart { border:1px solid #f9cd0b; }
/* light yellow */
.medium { background: #fff4c2; }

.cstat-skip { background: #ddd; color: #111; }
.fstat-skip { background: #ddd; color: #111 !important; }
.cbranch-skip { background: #ddd !important; color: #111; }

span.cline-neutral { background: #eaeaea; }

.coverage-summary td.empty {
opacity: .5;
padding-top: 4px;
padding-bottom: 4px;
line-height: 1;
color: #888;
}

.cover-fill, .cover-empty {
display:inline-block;
height: 12px;
}
.chart {
line-height: 0;
}
.cover-empty {
background: white;
}
.cover-full {
border-right: none !important;
}
pre.prettyprint {
border: none !important;
padding: 0 !important;
margin: 0 !important;
}
.com { color: #999 !important; }
.ignore-none { color: #999; font-weight: normal; }

.wrapper {
min-height: 100%;
height: auto !important;
height: 100%;
margin: 0 auto -48px;
}
.footer, .push {
height: 48px;
}
Loading