Merge remote-tracking branch 'sak/main'

This commit is contained in:
Damjan
2025-01-18 09:55:55 +01:00
108 changed files with 4126 additions and 296 deletions

View File

@@ -4,4 +4,5 @@ SOLANA_PRIVATE_KEY=
JUPITER_REFERRAL_ACCOUNT=
JUPITER_FEE_BPS=
FLASH_PRIVILEGE= referral | nft | none
HELIUS_API_KEY=
FLEXLEND_API_KEY=
HELIUS_API_KEY=

View File

@@ -134,10 +134,7 @@ console.log("Token Mint Address:", result.mint.toString());
```
### Create NFT Collection on 3Land
```typescript
const optionsWithBase58: StoreInitOptions = {
privateKey: "",
isMainnet: true, // if false, collection will be created on devnet 3.land (dev.3.land)
};
const isDevnet = true; // (Optional) if not present TX takes place in Mainnet
const collectionOpts: CreateCollectionOptions = {
collectionName: "",
@@ -147,18 +144,16 @@ const optionsWithBase58: StoreInitOptions = {
};
const result = await agent.create3LandCollection(
optionsWithBase58,
collectionOpts
collectionOpts,
isDevnet, // (Optional) if not present TX takes place in Mainnet
);
```
### Create NFT on 3Land
When creating an NFT using 3Land's tool, it automatically goes for sale on 3.land website
```typescript
const optionsWithBase58: StoreInitOptions = {
privateKey: "",
isMainnet: true, // if false, listing will be on devnet 3.land (dev.3.land)
};
const isDevnet = true; // (Optional) if not present TX takes place in Mainnet
const withPool = true; // (Optional) only present if NFT will be created with a Liquidity Pool for a specific SPL token
const collectionAccount = ""; //hash for the collection
const createItemOptions: CreateSingleOptions = {
itemName: "",
@@ -170,15 +165,15 @@ const createItemOptions: CreateSingleOptions = {
{ trait_type: "", value: "" },
],
price: 0, //100000000 == 0.1 sol, can be set to 0 for a free mint
splHash: "", //present if listing is on a specific SPL token, if not present sale will be on $SOL, must be present if "withPool" is true
poolName: "", // Only present if "withPool" is true
mainImageUrl: "",
splHash: "", //present if listing is on a specific SPL token, if not present sale will be on $SOL
};
const isMainnet = true;
const result = await agent.create3LandNft(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet
isDevnet, // (Optional) if not present TX takes place in Mainnet
withPool
);
```
@@ -471,6 +466,38 @@ Update the address a drift vault is delegated to.
const signature = await agent.updateDriftVaultDelegate("41Y8C4oxk4zgJT1KXyQr35UhZcfsp5mP86Z2G7UUzojU", "new-address")
```
### Get Voltr Vault Position Values
Get the current position values and total value of assets in a Voltr vault.
```typescript
const values = await agent.voltrGetPositionValues("7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K")
```
### Deposit into Voltr Strategy
Deposit assets into a specific strategy within a Voltr vault.
```typescript
const signature = await agent.voltrDepositStrategy(
new BN("1000000000"), // amount in base units (e.g., 1 USDC = 1000000)
"7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", // vault
"9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk" // strategy
)
```
### Withdraw from Voltr Strategy
Withdraw assets from a specific strategy within a Voltr vault.
```typescript
const signature = await agent.voltrWithdrawStrategy(
new BN("1000000000"), // amount in base units (e.g., 1 USDC = 1000000)
"7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", // vault
"9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk" // strategy
)
```
### Get a Solana asset by its ID
```typescript

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,2 +1,2 @@
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>executeAction | solana-agent-kit</title><meta name="description" content="Documentation for solana-agent-kit"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">solana-agent-kit</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">solana-agent-kit</a></li><li><a href="executeAction.html">executeAction</a></li></ul><h1>Function executeAction</h1></div><section class="tsd-panel"><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="executeaction" class="tsd-anchor"></a><span class="tsd-kind-call-signature">executeAction</span><span class="tsd-signature-symbol">(</span><br/>    <span class="tsd-kind-parameter">action</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Action</span><span class="tsd-signature-symbol">,</span><br/>    <span class="tsd-kind-parameter">agent</span><span class="tsd-signature-symbol">:</span> <a href="../classes/SolanaAgentKit.html" class="tsd-signature-type tsd-kind-class">SolanaAgentKit</a><span class="tsd-signature-symbol">,</span><br/>    <span class="tsd-kind-parameter">input</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">,</span><br/><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span><a href="#executeaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Execute an action with the given input</p>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">action</span>: <span class="tsd-signature-type">Action</span></span></li><li><span><span class="tsd-kind-parameter">agent</span>: <a href="../classes/SolanaAgentKit.html" class="tsd-signature-type tsd-kind-class">SolanaAgentKit</a></span></li><li><span><span class="tsd-kind-parameter">input</span>: <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/utils/actionExecutor.ts#L20">src/utils/actionExecutor.ts:20</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">action</span>: <span class="tsd-signature-type">Action</span></span></li><li><span><span class="tsd-kind-parameter">agent</span>: <a href="../classes/SolanaAgentKit.html" class="tsd-signature-type tsd-kind-class">SolanaAgentKit</a></span></li><li><span><span class="tsd-kind-parameter">input</span>: <span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Promise</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">Record</span><span class="tsd-signature-symbol">&lt;</span><span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">,</span> <span class="tsd-signature-type">any</span><span class="tsd-signature-symbol">&gt;</span><span class="tsd-signature-symbol">&gt;</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/utils/actionExecutor.ts#L20">src/utils/actionExecutor.ts:20</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>

View File

@@ -1,2 +1,2 @@
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>findAction | solana-agent-kit</title><meta name="description" content="Documentation for solana-agent-kit"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">solana-agent-kit</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">solana-agent-kit</a></li><li><a href="findAction.html">findAction</a></li></ul><h1>Function findAction</h1></div><section class="tsd-panel"><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="findaction" class="tsd-anchor"></a><span class="tsd-kind-call-signature">findAction</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">query</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Action</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">undefined</span><a href="#findaction" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Find an action by its name or one of its similes</p>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">query</span>: <span class="tsd-signature-type">string</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Action</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">undefined</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/utils/actionExecutor.ts#L8">src/utils/actionExecutor.ts:8</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">query</span>: <span class="tsd-signature-type">string</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">Action</span> <span class="tsd-signature-symbol">|</span> <span class="tsd-signature-type">undefined</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/utils/actionExecutor.ts#L8">src/utils/actionExecutor.ts:8</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>

View File

@@ -1,2 +1,2 @@
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>getActionExamples | solana-agent-kit</title><meta name="description" content="Documentation for solana-agent-kit"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">solana-agent-kit</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">solana-agent-kit</a></li><li><a href="getActionExamples.html">getActionExamples</a></li></ul><h1>Function getActionExamples</h1></div><section class="tsd-panel"><ul class="tsd-signatures"><li class="tsd-signature tsd-anchor-link"><a id="getactionexamples" class="tsd-anchor"></a><span class="tsd-kind-call-signature">getActionExamples</span><span class="tsd-signature-symbol">(</span><span class="tsd-kind-parameter">action</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">Action</span><span class="tsd-signature-symbol">)</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><a href="#getactionexamples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></li><li class="tsd-description"><div class="tsd-comment tsd-typography"><p>Get examples for an action</p>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">action</span>: <span class="tsd-signature-type">Action</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/utils/actionExecutor.ts#L58">src/utils/actionExecutor.ts:58</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
</div><div class="tsd-parameters"><h4 class="tsd-parameters-title">Parameters</h4><ul class="tsd-parameter-list"><li><span><span class="tsd-kind-parameter">action</span>: <span class="tsd-signature-type">Action</span></span></li></ul></div><h4 class="tsd-returns-title">Returns <span class="tsd-signature-type">string</span></h4><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/utils/actionExecutor.ts#L58">src/utils/actionExecutor.ts:58</a></li></ul></aside></li></ul></section></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>

File diff suppressed because one or more lines are too long

View File

@@ -1,16 +1,16 @@
<!DOCTYPE html><html class="default" lang="en" data-base=".."><head><meta charset="utf-8"/><meta http-equiv="x-ua-compatible" content="IE=edge"/><title>Action | solana-agent-kit</title><meta name="description" content="Documentation for solana-agent-kit"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="stylesheet" href="../assets/style.css"/><link rel="stylesheet" href="../assets/highlight.css"/><script defer src="../assets/main.js"></script><script async src="../assets/icons.js" id="tsd-icons-script"></script><script async src="../assets/search.js" id="tsd-search-script"></script><script async src="../assets/navigation.js" id="tsd-nav-script"></script></head><body><script>document.documentElement.dataset.theme = localStorage.getItem("tsd-theme") || "os";document.body.style.display="none";setTimeout(() => app?app.showPage():document.body.style.removeProperty("display"),500)</script><header class="tsd-page-toolbar"><div class="tsd-toolbar-contents container"><div class="table-cell" id="tsd-search"><div class="field"><label for="tsd-search-field" class="tsd-widget tsd-toolbar-icon search no-caption"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-search"></use></svg></label><input type="text" id="tsd-search-field" aria-label="Search"/></div><div class="field"><div id="tsd-toolbar-links"></div></div><ul class="results"><li class="state loading">Preparing search index...</li><li class="state failure">The search index is not available</li></ul><a href="../index.html" class="title">solana-agent-kit</a></div><div class="table-cell" id="tsd-widgets"><a href="#" class="tsd-widget tsd-toolbar-icon menu no-caption" data-toggle="menu" aria-label="Menu"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-menu"></use></svg></a></div></div></header><div class="container container-main"><div class="col-content"><div class="tsd-page-title"><ul class="tsd-breadcrumb"><li><a href="../modules.html">solana-agent-kit</a></li><li><a href="Action.html">Action</a></li></ul><h1>Interface Action</h1></div><section class="tsd-panel tsd-comment"><div class="tsd-comment tsd-typography"><p>Main Action interface inspired by ELIZA
This interface makes it easier to implement actions across different frameworks</p>
</div><div class="tsd-comment tsd-typography"></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">Action</span> <span class="tsd-signature-symbol">{</span><br/>    <a class="tsd-kind-property" href="Action.html#description">description</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#examples">examples</a><span class="tsd-signature-symbol">:</span> <a href="ActionExample.html" class="tsd-signature-type tsd-kind-interface">ActionExample</a><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#handler">handler</a><span class="tsd-signature-symbol">:</span> <a href="../types/Handler.html" class="tsd-signature-type tsd-kind-type-alias">Handler</a><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#name">name</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#schema">schema</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">ZodType</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#similes">similes</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L127">src/types/index.ts:127</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="Action.html#description" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>description</span></a>
</div><div class="tsd-comment tsd-typography"></div></section><div class="tsd-signature"><span class="tsd-signature-keyword">interface</span> <span class="tsd-kind-interface">Action</span> <span class="tsd-signature-symbol">{</span><br/>    <a class="tsd-kind-property" href="Action.html#description">description</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#examples">examples</a><span class="tsd-signature-symbol">:</span> <a href="ActionExample.html" class="tsd-signature-type tsd-kind-interface">ActionExample</a><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#handler">handler</a><span class="tsd-signature-symbol">:</span> <a href="../types/Handler.html" class="tsd-signature-type tsd-kind-type-alias">Handler</a><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#name">name</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#schema">schema</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">ZodType</span><span class="tsd-signature-symbol">;</span><br/>    <a class="tsd-kind-property" href="Action.html#similes">similes</a><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">;</span><br/><span class="tsd-signature-symbol">}</span></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L128">src/types/index.ts:128</a></li></ul></aside><section class="tsd-panel-group tsd-index-group"><section class="tsd-panel tsd-index-panel"><details class="tsd-index-content tsd-accordion" open><summary class="tsd-accordion-summary tsd-index-summary"><h5 class="tsd-index-heading uppercase" role="button" aria-expanded="false" tabIndex="0"><svg width="16" height="16" viewBox="0 0 16 16" fill="none"><use href="../assets/icons.svg#icon-chevronSmall"></use></svg> Index</h5></summary><div class="tsd-accordion-details"><section class="tsd-index-section"><h3 class="tsd-index-heading">Properties</h3><div class="tsd-index-list"><a href="Action.html#description" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>description</span></a>
<a href="Action.html#examples" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>examples</span></a>
<a href="Action.html#handler" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>handler</span></a>
<a href="Action.html#name" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a>
<a href="Action.html#schema" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>schema</span></a>
<a href="Action.html#similes" class="tsd-index-link"><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>similes</span></a>
</div></section></div></details></section></section><details class="tsd-panel-group tsd-member-group tsd-accordion" open><summary class="tsd-accordion-summary" data-key="section-Properties"><h2><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg> Properties</h2></summary><section><section class="tsd-panel tsd-member"><a id="description" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>description</span><a href="#description" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">description</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>Detailed description of what the action does</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L141">src/types/index.ts:141</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="examples" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>examples</span><a href="#examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">examples</span><span class="tsd-signature-symbol">:</span> <a href="ActionExample.html" class="tsd-signature-type tsd-kind-interface">ActionExample</a><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">[]</span></div><div class="tsd-comment tsd-typography"><p>Array of example inputs and outputs for the action
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L142">src/types/index.ts:142</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="examples" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>examples</span><a href="#examples" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">examples</span><span class="tsd-signature-symbol">:</span> <a href="ActionExample.html" class="tsd-signature-type tsd-kind-interface">ActionExample</a><span class="tsd-signature-symbol">[]</span><span class="tsd-signature-symbol">[]</span></div><div class="tsd-comment tsd-typography"><p>Array of example inputs and outputs for the action
Each inner array represents a group of related examples</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L147">src/types/index.ts:147</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="handler" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>handler</span><a href="#handler" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">handler</span><span class="tsd-signature-symbol">:</span> <a href="../types/Handler.html" class="tsd-signature-type tsd-kind-type-alias">Handler</a></div><div class="tsd-comment tsd-typography"><p>Function that executes the action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L157">src/types/index.ts:157</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="name" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>name</span><a href="#name" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">name</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>Unique name of the action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L131">src/types/index.ts:131</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="schema" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>schema</span><a href="#schema" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">schema</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">ZodType</span></div><div class="tsd-comment tsd-typography"><p>Zod schema for input validation</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L152">src/types/index.ts:152</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="similes" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>similes</span><a href="#similes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">similes</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">[]</span></div><div class="tsd-comment tsd-typography"><p>Alternative names/phrases that can trigger this action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/47be1a835935cbf4f7a478c4d50759402e9dbafa/src/types/index.ts#L136">src/types/index.ts:136</a></li></ul></aside></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#description" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>description</span></a><a href="#examples" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>examples</span></a><a href="#handler" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>handler</span></a><a href="#name" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a><a href="#schema" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>schema</span></a><a href="#similes" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>similes</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L148">src/types/index.ts:148</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="handler" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>handler</span><a href="#handler" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">handler</span><span class="tsd-signature-symbol">:</span> <a href="../types/Handler.html" class="tsd-signature-type tsd-kind-type-alias">Handler</a></div><div class="tsd-comment tsd-typography"><p>Function that executes the action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L158">src/types/index.ts:158</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="name" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>name</span><a href="#name" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">name</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span></div><div class="tsd-comment tsd-typography"><p>Unique name of the action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L132">src/types/index.ts:132</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="schema" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>schema</span><a href="#schema" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">schema</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">ZodType</span></div><div class="tsd-comment tsd-typography"><p>Zod schema for input validation</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L153">src/types/index.ts:153</a></li></ul></aside></section><section class="tsd-panel tsd-member"><a id="similes" class="tsd-anchor"></a><h3 class="tsd-anchor-link"><span>similes</span><a href="#similes" aria-label="Permalink" class="tsd-anchor-icon"><svg viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-anchor"></use></svg></a></h3><div class="tsd-signature"><span class="tsd-kind-property">similes</span><span class="tsd-signature-symbol">:</span> <span class="tsd-signature-type">string</span><span class="tsd-signature-symbol">[]</span></div><div class="tsd-comment tsd-typography"><p>Alternative names/phrases that can trigger this action</p>
</div><div class="tsd-comment tsd-typography"></div><aside class="tsd-sources"><ul><li>Defined in <a href="https://github.com/sendaifun/solana-agent-kit/blob/54382a542eb43b7e901bf2d93a883186d7d6ef3e/src/types/index.ts#L137">src/types/index.ts:137</a></li></ul></aside></section></section></details></div><div class="col-sidebar"><div class="page-menu"><div class="tsd-navigation settings"><details class="tsd-accordion"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Settings</h3></summary><div class="tsd-accordion-details"><div class="tsd-filter-visibility"><span class="settings-label">Member Visibility</span><ul id="tsd-filter-options"><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-protected" name="protected"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Protected</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-inherited" name="inherited" checked/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>Inherited</span></label></li><li class="tsd-filter-item"><label class="tsd-filter-input"><input type="checkbox" id="tsd-filter-external" name="external"/><svg width="32" height="32" viewBox="0 0 32 32" aria-hidden="true"><rect class="tsd-checkbox-background" width="30" height="30" x="1" y="1" rx="6" fill="none"></rect><path class="tsd-checkbox-checkmark" d="M8.35422 16.8214L13.2143 21.75L24.6458 10.25" stroke="none" stroke-width="3.5" stroke-linejoin="round" fill="none"></path></svg><span>External</span></label></li></ul></div><div class="tsd-theme-toggle"><label class="settings-label" for="tsd-theme">Theme</label><select id="tsd-theme"><option value="os">OS</option><option value="light">Light</option><option value="dark">Dark</option></select></div></div></details></div><details open class="tsd-accordion tsd-page-navigation"><summary class="tsd-accordion-summary"><h3><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>On This Page</h3></summary><div class="tsd-accordion-details"><details open class="tsd-accordion tsd-page-navigation-section"><summary class="tsd-accordion-summary" data-key="section-Properties"><svg width="20" height="20" viewBox="0 0 24 24" fill="none"><use href="../assets/icons.svg#icon-chevronDown"></use></svg>Properties</summary><div><a href="#description" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>description</span></a><a href="#examples" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>examples</span></a><a href="#handler" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>handler</span></a><a href="#name" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>name</span></a><a href="#schema" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>schema</span></a><a href="#similes" class=""><svg class="tsd-kind-icon" viewBox="0 0 24 24"><use href="../assets/icons.svg#icon-1024"></use></svg><span>similes</span></a></div></details></div></details></div><div class="site-menu"><nav class="tsd-navigation"><a href="../modules.html">solana-agent-kit</a><ul class="tsd-small-nested-navigation" id="tsd-nav-container"><li>Loading...</li></ul></nav></div></div></div><footer><p class="tsd-generator">Generated using <a href="https://typedoc.org/" target="_blank">TypeDoc</a></p></footer><div class="overlay"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,123 @@
module.exports = {
env: {
es2021: true,
node: true,
},
root: true,
settings: {
'import/resolver': {
typescript: {},
},
},
ignorePatterns: [
'.eslintrc.js',
'webpack.config.js',
'dist/*',
'**/*.js',
'node_modules/*',
],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 12,
project: 'tsconfig.json',
tsconfigRootDir: '.',
sourceType: 'module',
},
extends: [
'airbnb-base',
'plugin:@typescript-eslint/recommended-requiring-type-checking',
'plugin:prettier/recommended',
'plugin:sonarjs/recommended',
'plugin:security/recommended',
'plugin:promise/recommended',
'prettier',
],
plugins: [
'@typescript-eslint/eslint-plugin',
'sonarjs',
'security',
'promise',
'prettier',
],
rules: {
semi: [2, 'always'],
quotes: [1, 'single', { allowTemplateLiterals: true }],
curly: [2, 'all'],
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/no-floating-promises': 'warn',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-argument': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/restrict-template-expressions': 'off',
'@typescript-eslint/ban-ts-comment': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-misused-promises': [
'error',
{ checksVoidReturn: false },
],
'security/detect-non-literal-regexp': 0,
'security/detect-object-injection': 0,
'promise/always-return': 0,
'promise/no-callback-in-promise': 0,
'sonarjs/cognitive-complexity': [2, 50],
'sonarjs/no-duplicate-string': 0,
'sonarjs/no-useless-catch': 1,
'sonarjs/no-nested-template-literals': 0,
'sonarjs/prefer-single-boolean-return': 1,
'sonarjs/no-small-switch': 'off',
'@typescript-eslint/no-unused-vars': [
1,
{ argsIgnorePattern: '^_|^returns$|^of$|^type$' },
],
'import/extensions': 'off',
'import/no-import-module-exports': 'off',
'import/prefer-default-export': 'off',
'import/no-extraneous-dependencies': 'off',
'import/no-dynamic-require': 'off',
'prettier/prettier': [
'error',
{
useTabs: false,
arrowParens: 'always',
printWidth: 80,
singleQuote: true,
trailingComma: 'all',
endOfLine: 'auto',
bracketSpacing: true,
},
{
usePrettierrc: false,
},
],
'no-restricted-imports': [
'error',
{
patterns: ['**/dist/**'],
},
],
'no-use-before-define': 'off',
'no-console': 'off',
'no-return-await': 'off',
'consistent-return': 'off',
'default-case': 'off',
'no-fallthrough': 'off',
'no-plusplus': 'off',
'no-await-in-loop': 'off',
'no-restricted-syntax': 'off',
'no-continue': 'off',
'no-nested-ternary': 'off',
'no-void': 'off',
'no-param-reassign': 'off',
'class-methods-use-this': 'off',
'no-return-assign': 'off',
'no-case-declarations': 'off',
'global-require': 'off',
'security/detect-non-literal-require': 'off',
'global-require': 'off',
},
};

View File

@@ -1,6 +1,6 @@
{
"name": "solana-agent-kit",
"version": "1.4.0",
"version": "1.4.1",
"description": "connect any ai agents to solana protocols",
"main": "dist/index.js",
"types": "dist/index.d.ts",
@@ -19,11 +19,11 @@
"node": ">=22.0.0",
"pnpm": ">=8.0.0"
},
"keywords": [],
"keywords": ["solana", "agent", "ai", "solana agent kit", "sendai"],
"author": "sendaifun",
"license": "Apache-2.0",
"dependencies": {
"@3land/listings-sdk": "^0.0.4",
"@3land/listings-sdk": "^0.0.6",
"@ai-sdk/openai": "^1.0.11",
"@bonfida/spl-name-service": "^3.0.7",
"@cks-systems/manifest-sdk": "0.1.59",
@@ -43,6 +43,9 @@
"@metaplex-foundation/umi": "^0.9.2",
"@metaplex-foundation/umi-bundle-defaults": "^0.9.2",
"@metaplex-foundation/umi-web3js-adapters": "^0.9.2",
"@mercurial-finance/dynamic-amm-sdk": "^1.1.19",
"@meteora-ag/alpha-vault": "^1.1.7",
"@meteora-ag/dlmm": "^1.3.0",
"@onsol/tldparser": "^0.6.7",
"@orca-so/common-sdk": "0.6.4",
"@orca-so/whirlpools-sdk": "^0.13.12",
@@ -53,6 +56,7 @@
"@sqds/multisig": "^2.1.3",
"@tensor-oss/tensorswap-sdk": "^4.5.0",
"@tiplink/api": "^0.3.1",
"@voltr/vault-sdk": "^0.1.1",
"ai": "^4.0.22",
"bn.js": "^5.2.1",
"bs58": "^6.0.0",

900
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,55 @@
import { MainnetSpotMarkets } from "@drift-labs/sdk";
import type { Action } from "../../types";
import { z } from "zod";
import {
getAvailableDriftPerpMarkets,
getAvailableDriftSpotMarkets,
} from "../../tools";
const availableDriftMarketsAction: Action = {
name: "AVAILABLE_DRIFT_MARKETS",
description: "Get a list of available drift markets",
similes: [
"get drift markets",
"drift markets",
"available drift markets",
"get available drift perp markets",
"get available spot markets on drift",
],
examples: [
[
{
input: {
marketType: "spot",
},
output: {
status: "success",
message: `The list of available spot markets are ${MainnetSpotMarkets.map((v) => v.symbol).join(", ")}`,
data: MainnetSpotMarkets,
},
explanation: "Get the list of available spot markets/tokens on drift",
},
],
],
schema: z.object({
marketType: z
.enum(["spot", "perp"])
.describe("Type of market to get")
.optional(),
}),
handler: async (agent, input) => {
switch (input.marketType) {
case "perp":
return getAvailableDriftPerpMarkets();
case "spot":
return getAvailableDriftSpotMarkets();
default:
return {
spot: getAvailableDriftSpotMarkets(),
perp: getAvailableDriftPerpMarkets(),
};
}
},
};
export default availableDriftMarketsAction;

View File

@@ -27,7 +27,12 @@ const createDriftUserAccountAction: Action = {
],
],
schema: z.object({
amount: z.number().positive().describe("Amount of the token to deposit"),
amount: z
.number()
.positive()
.describe(
"Amount of the token to deposit. In normal token amounts e.g 50 SOL, 100 USDC, etc",
),
symbol: z.string().describe("Symbol of the token to deposit"),
}),
handler: async (agent, input) => {

View File

@@ -53,9 +53,14 @@ const createDriftVaultAction: Action = {
.int()
.min(100, "Max tokens must be at least 100")
.describe(
"The maximum amount of tokens the vault will be accomodating. For example some vaults have a cap at 10 million USDC",
"The maximum amount of tokens the vault will be accomodating. For example some vaults have a cap at 10 million USDC. This amount should be normal token amounts e.g 50 SOL, 100 USDC, etc",
),
minDepositAmount: z
.number()
.positive()
.describe(
"Minimum deposit amount in normal token values e.g 50 SOL, 100 USDC, etc",
),
minDepositAmount: z.number().positive().describe("Minimum deposit amount"),
managementFee: z
.number()
.positive()

View File

@@ -28,7 +28,9 @@ const depositIntoDriftVaultAction: Action = {
amount: z
.number()
.positive()
.describe("The amount in tokens you'd like to deposit into the vault"),
.describe(
"The amount in tokens you'd like to deposit into the vault in normal token amounts e.g 50 SOL, 100 USDC, etc",
),
}),
handler: async (agent, input) => {
try {

View File

@@ -34,7 +34,7 @@ const depositToDriftUserAccountAction: Action = {
.number()
.positive()
.describe(
"The amount in tokens you'd like to deposit into your drift user account",
"The amount in tokens you'd like to deposit into your drift user account in normal token amounts e.g 50 SOL, 100 USDC, etc",
),
symbol: z
.string()

View File

@@ -0,0 +1,65 @@
import { z } from "zod";
import type { Action } from "../../types";
import { getEntryQuoteOfPerpTrade } from "../../tools";
const entryQuoteOfPerpTradeAction: Action = {
name: "DRIFT_GET_ENTRY_QUOTE_OF_PERP_TRADE_ACTION",
description: "Get the entry quote of a perpetual trade on Drift",
similes: [
"get the entry quote of a perpetual trade on drift",
"get the entry quote of a perp trade on drift",
"get the entry quote of the BTC-PERP trade on drift",
"get the entry quote of the SOL-PERP trade on drift",
"get the entry quote of a 1000 USDC long on the SOL-PERP market",
"get the entry quote of a 1000 USDC short on the SOL-PERP market",
"quote for a $1000 long on the BTC-PERP market",
],
examples: [
[
{
input: {
marketSymbol: "BTC-PERP",
type: "long",
amount: 1000,
},
output: {
status: "success",
data: {
entryPrice: 100000,
priceImpact: 0.0001,
bestPrice: 100001,
worstPrice: 99999,
baseFilled: 1000,
quoteFilled: 1000,
},
},
explanation:
"Get the entry quote of a $1000 long on the BTC-PERP market",
},
],
],
schema: z.object({
marketSymbol: z.string().describe("Symbol of the perpetual market"),
type: z.enum(["long", "short"]).describe("Type of trade"),
amount: z.number().positive().describe("Amount to trade"),
}),
handler: async (agent, input) => {
try {
const data = await getEntryQuoteOfPerpTrade(
input.marketSymbol,
input.amount,
input.type,
);
return data;
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default entryQuoteOfPerpTradeAction;

View File

@@ -0,0 +1,52 @@
import { z } from "zod";
import type { Action } from "../../types";
import { getLendingAndBorrowAPY } from "../../tools";
const lendAndBorrowAPYAction: Action = {
name: "DRIFT_GET_LEND_AND_BORROW_APY_ACTION",
description: "Get the lending and borrowing APY (in %) of a token on Drift",
similes: [
"get the lending and borrowing APY of a token on drift",
"get the lending and borrowing APY of a token on drift",
"get the lending and borrowing APY of the USDC token on drift",
"get the lending and borrowing APY of the SOL token on drift",
],
examples: [
[
{
input: {
symbol: "USDC",
},
output: {
status: "success",
data: {
lendingAPY: 10,
borrowingAPY: 12.1,
},
},
explanation: "Get the lending and borrowing APY of the USDC token",
},
],
],
schema: z.object({
symbol: z.string().describe("Symbol of the token"),
}),
handler: async (agent, input) => {
try {
const data = await getLendingAndBorrowAPY(agent, input.symbol);
return {
status: "success",
data,
};
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default lendAndBorrowAPYAction;

View File

@@ -0,0 +1,61 @@
import { z } from "zod";
import type { Action } from "../../types";
import { calculatePerpMarketFundingRate } from "../../tools";
const perpMarktetFundingRateAction: Action = {
name: "DRIFT_PERP_MARKET_FUNDING_RATE_ACTION",
description: "Get the funding rate of a perpetual market on Drift",
similes: [
"get the yearly funding rate of a perpetual market on drift",
"get the funding rate of a perp market on drift",
"get the hourly funding rate of a perpetual market on drift",
"get the funding rate of the BTC-PERP market on drift",
"get the funding rate of the SOL-PERP market on drift",
],
examples: [
[
{
input: {
marketSymbol: "BTC-PERP",
},
output: {
status: "success",
data: {
longRate: 0.0001,
shortRate: 0.0002,
},
},
explanation: "Get the funding rate of the BTC-PERP market",
},
],
],
schema: z.object({
marketSymbol: z
.string()
.toUpperCase()
.describe("Symbol of the perpetual market"),
period: z.enum(["year", "hour"]).default("hour").optional(),
}),
handler: async (agent, input) => {
try {
const data = await calculatePerpMarketFundingRate(
agent,
input.marketSymbol,
input.period,
);
return {
status: "success",
data,
};
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default perpMarktetFundingRateAction;

View File

@@ -0,0 +1,61 @@
import { z } from "zod";
import type { Action } from "../../types";
import { requestUnstakeFromDriftInsuranceFund } from "../../tools";
const requestUnstakeFromDriftInsuranceFundAction: Action = {
name: "REQUEST_UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ACTION",
description:
"Request to unstake a certain amount of a token from the Drift Insurance Fund",
similes: [
"request an unstake from the drift insurance fund",
"request to unstake an amount from the drift insurance fund",
],
examples: [
[
{
input: {
amount: 100,
symbol: "SOL",
},
output: {
status: "success",
message: "Requested to unstake 100 SOL from the Drift Insurance Fund",
signature: "4FdasklhiIHyOI",
},
explanation: "Request to unstake 100 SOL from the Drift Insurance Fund",
},
],
],
schema: z.object({
amount: z
.number()
.positive()
.describe("Amount to unstake in normal units e.g 50 === 50 SOL"),
symbol: z.string().describe("Symbol of the token to unstake"),
}),
handler: async (agent, input) => {
try {
const tx = await requestUnstakeFromDriftInsuranceFund(
agent,
input.amount,
input.symbol,
);
return {
status: "success",
message: `Requested to unstake ${input.amount} ${input.symbol} from the Drift Insurance Fund`,
data: {
signature: tx,
},
};
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default requestUnstakeFromDriftInsuranceFundAction;

View File

@@ -29,7 +29,9 @@ const requestWithdrawalFromVaultAction: Action = {
amount: z
.number()
.positive()
.describe("Amount of shares you would like to withdraw from the vault"),
.describe(
"Amount of shares you would like to withdraw from the vault in normal token amounts e.g 50 SOL, 100 USDC, etc",
),
}),
handler: async (agent: SolanaAgentKit, input) => {
try {

View File

@@ -0,0 +1,59 @@
import { z } from "zod";
import type { Action } from "../../types";
import { stakeToDriftInsuranceFund } from "../../tools";
const stakeToDriftInsuranceFundAction: Action = {
name: "STAKE_TO_DRIFT_INSURANCE_FUND_ACTION",
description: "Stake a token to Drift Insurance Fund",
similes: ["Stake a token to Drift Insurance Fund"],
examples: [
[
{
input: {
amount: 100,
symbol: "SOL",
},
output: {
status: "success",
message: "Staked 100 SOL to the Drift Insurance Fund",
data: {
signature: "signature",
},
},
explanation: "Stake 100 SOL to the Drift Insurance Fund",
},
],
],
schema: z.object({
amount: z
.number()
.positive()
.describe("Amount to stake in normal units e.g 50 === 50 SOL"),
symbol: z.string().describe("Symbol of the token stake"),
}),
handler: async (agent, input) => {
try {
const tx = await stakeToDriftInsuranceFund(
agent,
input.amount,
input.symbol,
);
return {
status: "sucess",
message: `Staked ${input.amount} ${input.symbol} to the Drift Insurance Fund`,
data: {
signature: tx,
},
};
} catch (error) {
return {
status: "error",
// @ts-expect-error error is not a string
message: error.message,
};
}
},
};
export default stakeToDriftInsuranceFundAction;

View File

@@ -0,0 +1,78 @@
import { z } from "zod";
import type { Action } from "../../types";
import { swapSpotToken } from "../../tools";
const driftSpotTokenSwapAction: Action = {
name: "DRIFT_SPOT_TOKEN_SWAP_ACTION",
description: "Swap a token for another token on Drift",
similes: [
"swap a token for another token on drift",
"exchange a token for another token on drift",
"trade a token for another token on drift",
"swap usdc to 5 sol on drift (in this case 5 sol is the toAmount)",
"swap 5 usdt to DRIFT on drift (in this case 5 usdt is the fromAmount)",
],
examples: [
[
{
input: {
fromSymbol: "SOL",
toSymbol: "USDC",
fromAmount: 100,
},
output: {
status: "success",
message: "Swapped 100 SOL for USDC on Drift",
signature: "4FdasklhiIHyOI",
},
explanation: "Swap 100 SOL for USDC on Drift",
},
],
],
schema: z.object({
fromSymbol: z.string().describe("Symbol of the token to swap from"),
toSymbol: z.string().describe("Symbol of the token to swap to"),
fromAmount: z
.number()
.positive()
.describe("Amount to swap from e.g 50 === 50 SOL")
.optional(),
toAmount: z
.number()
.positive()
.describe("Amount to swap to e.g 5000 === 5000 USDC")
.optional(),
slippage: z
.number()
.positive()
.describe("Slippage tolerance in percentage e.g 0.5 === 0.5%")
.default(0.5),
}),
handler: async (agent, input) => {
try {
const tx = await swapSpotToken(agent, {
fromSymbol: input.fromSymbol,
toSymbol: input.toSymbol,
fromAmount: input.fromAmount,
toAmount: input.toAmount,
slippage: input.slippage,
});
return {
status: "success",
message: `Swapped ${input.fromAmount} ${input.fromSymbol} for ${input.toAmount} ${input.toSymbol} on Drift`,
data: {
signature: tx,
},
};
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default driftSpotTokenSwapAction;

View File

@@ -64,11 +64,20 @@ const tradeDelegatedDriftVaultAction: Action = {
],
schema: z.object({
vaultAddress: z.string().describe("Address of the Drift vault to trade in"),
amount: z.number().positive().describe("Amount to trade"),
amount: z
.number()
.positive()
.describe(
"Amount to trade in normal token amounts e.g 50 SOL, 100 USDC, etc",
),
symbol: z.string().describe("Symbol of the token to trade"),
action: z.enum(["long", "short"]).describe("Trade action - long or short"),
type: z.enum(["market", "limit"]).describe("Trade type - market or limit"),
price: z.number().positive().optional().describe("Price for limit order"),
price: z
.number()
.positive()
.optional()
.describe("USD price for limit order"),
}),
handler: async (agent: SolanaAgentKit, input) => {
try {

View File

@@ -46,14 +46,27 @@ export const tradeDriftPerpAccountAction: Action = {
],
],
schema: z.object({
amount: z.number().positive(),
amount: z
.number()
.positive()
.describe(
"The amount of the token to trade in normal token amounts e.g 50 SOL, 100 USDC",
),
symbol: z
.string()
.toUpperCase()
.describe("Symbol of the token to open a position on "),
action: z.enum(["long", "short"]),
type: z.enum(["market", "limit"]),
price: z.number().positive().optional(),
action: z
.enum(["long", "short"])
.describe(
"The action you would like to carry out whether it be a long or a short",
),
type: z
.enum(["market", "limit"])
.describe(
"The type of trade you would like to open, market or limit order",
),
price: z.number().positive().optional().describe("USD price of the token"),
}),
handler: async (agent, input) => {
try {

View File

@@ -0,0 +1,51 @@
import { z } from "zod";
import type { Action } from "../../types";
import { unstakeFromDriftInsuranceFund } from "../../tools";
const unstakeFromDriftInsuranceFundAction: Action = {
name: "UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ACTION",
description:
"Unstake requested unstake token from the Drift Insurance fund once the cool period has elapsed",
similes: [
"unstake from the drift insurance fund",
"withdraw from the drift insurance fund",
"take out funds from the drift insurance fund",
],
examples: [
[
{
input: {
symbol: "SOL",
},
output: {
status: "success",
message: "Unstaked your SOL from the Drift Insurance Fund",
signature: "4FdasklhiIHyOI",
},
explanation: "Unstake SOL from the Drift Insurance Fund",
},
],
],
schema: z.object({
symbol: z.string().describe("Symbol of the token to unstake"),
}),
handler: async (agent, input) => {
try {
const tx = await unstakeFromDriftInsuranceFund(agent, input.symbol);
return {
status: "success",
message: `Unstaked your ${input.symbol} from the Drift Insurance Fund`,
signature: tx,
};
} catch (e) {
return {
status: "error",
// @ts-expect-error error is not a string
message: e.message,
};
}
},
};
export default unstakeFromDriftInsuranceFundAction;

View File

@@ -24,8 +24,8 @@ const updateDriftVaultDelegateAction: Action = {
],
],
schema: z.object({
vaultAddress: z.string(),
newDelegate: z.string(),
vaultAddress: z.string().describe("vault's address"),
newDelegate: z.string().describe("new address to delegate the vault to"),
}),
handler: async (agent, input) => {
try {

View File

@@ -41,16 +41,35 @@ const updateDriftVaultAction: Action = {
redeemPeriod: z
.number()
.int()
.min(1, "Redeem period must be at least 1")
.min(1, "Redeem period must be at least 1 day")
.optional(),
maxTokens: z
.number()
.int()
.min(100, "Max tokens must be at least 100")
.optional(),
minDepositAmount: z.number().positive().optional(),
managementFee: z.number().positive().max(20).optional(),
profitShare: z.number().positive().max(90).optional(),
.min(100, "Max tokens must be at least be 100 units")
.optional()
.describe(
"The maximum number of tokens the vault is willing to accept and manage",
),
minDepositAmount: z
.number()
.positive()
.optional()
.describe(
"The minimum amount that is allowed to be deposited into the vault in normal token amounts e.g 10 USDC",
),
managementFee: z
.number()
.positive()
.max(20)
.optional()
.describe("The percentage fee the vault takes for asset management"),
profitShare: z
.number()
.positive()
.max(90)
.optional()
.describe("Profit share in percentage e.g 2 === 2%"),
handleRate: z.number().optional(),
permissioned: z
.boolean()

View File

@@ -36,7 +36,7 @@ const withdrawFromDriftAccountAction: Action = {
.number()
.positive()
.describe(
"The amount in tokens you'd like to withdraw from your drift account",
"The amount in tokens you'd like to withdraw from your drift account in normal token amounts, e.g 50 SOL, 100 USDC, etc",
),
symbol: z
.string()

View File

@@ -25,7 +25,7 @@ const withdrawFromVaultAction: Action = {
],
],
schema: z.object({
vaultAddress: z.string(),
vaultAddress: z.string().describe("Vault's address"),
}),
handler: async (agent: SolanaAgentKit, input) => {
try {

View File

@@ -14,6 +14,8 @@ import stakeWithJupAction from "./jupiter/stakeWithJup";
import stakeWithSolayerAction from "./solayer/stakeWithSolayer";
import registerDomainAction from "./sns/registerDomain";
import lendAssetAction from "./lulo/lendAsset";
import luloLendAction from "./lulo/luloLend";
import luloWithdrawAction from "./lulo/luloWithdraw";
import createGibworkTaskAction from "./gibwork/createGibworkTask";
import resolveSolDomainAction from "./sns/resolveSolDomain";
import pythFetchPriceAction from "./pyth/pythFetchPrice";
@@ -59,6 +61,17 @@ import withdrawFromDriftAccountAction from "./drift/withdrawFromDriftAccount";
import driftUserAccountInfoAction from "./drift/driftUserAccountInfo";
import deriveDriftVaultAddressAction from "./drift/deriveVaultAddress";
import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate";
import availableDriftMarketsAction from "./drift/availableMarkets";
import stakeToDriftInsuranceFundAction from "./drift/stakeToDriftInsuranceFund";
import requestUnstakeFromDriftInsuranceFundAction from "./drift/requestUnstakeFromDriftInsuranceFund";
import unstakeFromDriftInsuranceFundAction from "./drift/unstakeFromDriftInsuranceFund";
import driftSpotTokenSwapAction from "./drift/swapSpotToken";
import perpMarktetFundingRateAction from "./drift/perpMarketFundingRate";
import entryQuoteOfPerpTradeAction from "./drift/entryQuoteOfPerpTrade";
import lendAndBorrowAPYAction from "./drift/getLendAndBorrowAPY";
import getVoltrPositionValuesAction from "./voltr/getPositionValues";
import depositVoltrStrategyAction from "./voltr/depositStrategy";
import withdrawVoltrStrategyAction from "./voltr/withdrawStrategy";
import getAssetAction from "./metaplex/getAsset";
import getAssetsByAuthorityAction from "./metaplex/getAssetsByAuthority";
import getAssetsByCreatorAction from "./metaplex/getAssetsByCreator";
@@ -82,6 +95,8 @@ export const ACTIONS = {
STAKE_WITH_SOLAYER_ACTION: stakeWithSolayerAction,
REGISTER_DOMAIN_ACTION: registerDomainAction,
LEND_ASSET_ACTION: lendAssetAction,
LULO_LEND_ACTION: luloLendAction,
LULO_WITHDRAW_ACTION: luloWithdrawAction,
CREATE_GIBWORK_TASK_ACTION: createGibworkTaskAction,
RESOLVE_SOL_DOMAIN_ACTION: resolveSolDomainAction,
PYTH_FETCH_PRICE_ACTION: pythFetchPriceAction,
@@ -127,6 +142,18 @@ export const ACTIONS = {
DRIFT_USER_ACCOUNT_INFO_ACTION: driftUserAccountInfoAction,
DERIVE_DRIFT_VAULT_ADDRESS_ACTION: deriveDriftVaultAddressAction,
UPDATE_DRIFT_VAULT_DELEGATE_ACTION: updateDriftVaultDelegateAction,
AVAILABLE_DRIFT_MARKETS_ACTION: availableDriftMarketsAction,
STAKE_TO_DRIFT_INSURANCE_FUND_ACTION: stakeToDriftInsuranceFundAction,
REQUEST_UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ACTION:
requestUnstakeFromDriftInsuranceFundAction,
UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ACTION: unstakeFromDriftInsuranceFundAction,
DRIFT_SPOT_TOKEN_SWAP_ACTION: driftSpotTokenSwapAction,
DRIFT_PERP_MARKET_FUNDING_RATE_ACTION: perpMarktetFundingRateAction,
DRIFT_GET_ENTRY_QUOTE_OF_PERP_TRADE_ACTION: entryQuoteOfPerpTradeAction,
DRIFT_GET_LEND_AND_BORROW_APY_ACTION: lendAndBorrowAPYAction,
GET_VOLTR_POSITION_VALUES_ACTION: getVoltrPositionValuesAction,
DEPOSIT_VOLTR_STRATEGY_ACTION: depositVoltrStrategyAction,
WITHDRAW_VOLTR_STRATEGY_ACTION: withdrawVoltrStrategyAction,
GET_ASSET_ACTION: getAssetAction,
GET_ASSETS_BY_AUTHORITY_ACTION: getAssetsByAuthorityAction,
GET_ASSETS_BY_CREATOR_ACTION: getAssetsByCreatorAction,

View File

@@ -0,0 +1,62 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { luloLend } from "../../tools/lulo";
const luloLendAction: Action = {
name: "LULO_LEND",
similes: [
"lend USDC with lulo",
"lend PYUSD with lulo",
"lend USDS with lulo",
"lend USDT with lulo",
"lend SQL with lulo",
"lend jitoSQL with lulo",
"lend bSQL with lulo",
"lend mSQL with lulo",
"lend BONK with lulo",
"lend JUP with lulo",
],
description: "Lend SPL tokens using Lulo protocol",
examples: [
[
{
input: {
mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amount: 100,
},
output: {
status: "success",
signature: "4xKpN2...",
message: "Successfully lend 100 USDC",
},
explanation: "Lend 100 USDC on Lulo",
},
],
],
schema: z.object({
mintAddress: z.string().describe("SPL Mint address"),
amount: z.number().positive().describe("Amount to lend"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const mintAddress = input.mintAddress as string;
const amount = input.amount as number;
const response = await luloLend(agent, mintAddress, amount);
return {
status: "success",
signature: response,
message: `Successfully lend ${amount} of token ${mintAddress}`,
};
} catch (error: any) {
return {
status: "error",
message: `Lend failed: ${error.message}`,
};
}
},
};
export default luloLendAction;

View File

@@ -0,0 +1,62 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { luloWithdraw } from "../../tools/lulo";
const luloWithdrawAction: Action = {
name: "LULO_WITHDRAW",
similes: [
"withdraw USDC with lulo",
"withdraw PYUSD with lulo",
"withdraw USDS with lulo",
"withdraw USDT with lulo",
"withdraw SQL with lulo",
"withdraw jitoSQL with lulo",
"withdraw bSQL with lulo",
"withdraw mSQL with lulo",
"withdraw BONK with lulo",
"withdraw JUP with lulo",
],
description: "Withdraw SPL tokens using Lulo protocol",
examples: [
[
{
input: {
mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
amount: 100,
},
output: {
status: "success",
signature: "4xKpN2...",
message: "Successfully withdraw 100 USDC",
},
explanation: "Withdraw 100 USDC on Lulo",
},
],
],
schema: z.object({
mintAddress: z.string().describe("SPL Mint address"),
amount: z.number().positive().describe("Amount to lend"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const mintAddress = input.mintAddress as string;
const amount = input.amount as number;
const response = await luloWithdraw(agent, mintAddress, amount);
return {
status: "success",
signature: response,
message: `Successfully withdraw ${amount} of token ${mintAddress}`,
};
} catch (error: any) {
return {
status: "error",
message: `Withdraw failed: ${error.message}`,
};
}
},
};
export default luloWithdrawAction;

View File

@@ -0,0 +1,83 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
import { BN } from "bn.js";
const depositVoltrStrategyAction: Action = {
name: "DEPOSIT_VOLTR_STRATEGY",
similes: [
"deposit to voltr strategy",
"add funds to voltr vault strategy",
"invest in voltr strategy",
"deposit assets to voltr",
"contribute to voltr vault",
"fund voltr strategy",
],
description: "Deposit assets into a specific strategy within a Voltr vault",
examples: [
[
{
input: {
depositAmount: "1000000000", // 1 USDC with 6 decimals
vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K",
strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk",
},
output: {
status: "success",
vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K",
strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk",
signature: "2ZE7Rz...",
message: "Successfully deposited 1000000000 into strategy",
},
explanation: "Deposit 1 USDC into a Voltr vault strategy",
},
],
],
schema: z.object({
depositAmount: z
.string()
.min(1)
.describe("The amount to deposit (in base units including decimals)"),
vault: z
.string()
.min(1)
.describe(
"The public key of the Voltr source vault to take assets from, e.g., 'Ga27...'",
),
strategy: z
.string()
.min(1)
.describe(
"The public key of the initialized target strategy to deposit into, e.g., 'Jheh...'",
),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const depositAmount = new BN(input.depositAmount);
const vault = new PublicKey(input.vault);
const strategy = new PublicKey(input.strategy);
const signature = await agent.voltrDepositStrategy(
depositAmount,
vault,
strategy,
);
return {
status: "success",
vault: vault.toBase58(),
strategy: strategy.toBase58(),
signature,
message: `Successfully deposited ${input.depositAmount} into strategy`,
};
} catch (error: any) {
return {
status: "error",
message: `Failed to deposit into strategy: ${error.message}`,
};
}
},
};
export default depositVoltrStrategyAction;

View File

@@ -0,0 +1,74 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
const getVoltrPositionValuesAction: Action = {
name: "GET_VOLTR_POSITION_VALUES",
similes: [
"get voltr vault value",
"check voltr position",
"get voltr vault assets",
"view voltr holdings",
"check voltr portfolio",
"get voltr vault breakdown",
],
description:
"Get the current position values and total assets for a Voltr vault",
examples: [
[
{
input: {
vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K",
},
output: {
status: "success",
data: {
totalValue: 1000000,
positions: [
{
strategy: "4JHtgXyMb9gFJ1hGd2sh645jrZcxurSG3QP7Le3aTMTx",
value: 600000,
},
{
strategy: "4i9kzGr1UkxBCCUkQUQ4vsF51fjdt2knKxrwM1h1NW4g",
value: 400000,
},
],
},
message: "Successfully retrieved Voltr vault position values",
},
explanation:
"Get position values for a Voltr vault showing total value and value per strategy",
},
],
],
schema: z.object({
vault: z
.string()
.min(1)
.describe("The public key of the Voltr vault to query, e.g., 'Ga27...'"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const vault = new PublicKey(input.vault);
const result = await agent.voltrGetPositionValues(vault);
const positionData = JSON.parse(result);
return {
status: "success",
vault: vault.toBase58(),
data: positionData,
message: "Successfully retrieved Voltr vault position values",
};
} catch (error: any) {
return {
status: "error",
message: `Failed to get vault position values: ${error.message}`,
};
}
},
};
export default getVoltrPositionValuesAction;

View File

@@ -0,0 +1,83 @@
import { Action } from "../../types/action";
import { SolanaAgentKit } from "../../agent";
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
import { BN } from "bn.js";
const withdrawVoltrStrategyAction: Action = {
name: "WITHDRAW_VOLTR_STRATEGY",
similes: [
"withdraw from voltr strategy",
"remove funds from voltr vault strategy",
"take out from voltr strategy",
"withdraw assets from voltr",
"pull from voltr vault",
"redeem from voltr strategy",
],
description: "Withdraw assets from a specific strategy within a Voltr vault",
examples: [
[
{
input: {
withdrawAmount: "1000000000", // 1 USDC with 6 decimals
vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K",
strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk",
},
output: {
status: "success",
vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K",
strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk",
signature: "2ZE7Rz...",
message: "Successfully withdrew 1000000000 from strategy",
},
explanation: "Withdraw 1 USDC from a Voltr vault strategy",
},
],
],
schema: z.object({
withdrawAmount: z
.string()
.min(1)
.describe("The amount to withdraw (in base units including decimals)"),
vault: z
.string()
.min(1)
.describe(
"The public key of the Voltr source vault to deposit assets into, e.g., 'Ga27...'",
),
strategy: z
.string()
.min(1)
.describe(
"The public key of the initialized target strategy to withdraw from, e.g., 'Jheh...'",
),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const withdrawAmount = new BN(input.withdrawAmount);
const vault = new PublicKey(input.vault);
const strategy = new PublicKey(input.strategy);
const signature = await agent.voltrWithdrawStrategy(
withdrawAmount,
vault,
strategy,
);
return {
status: "success",
vault: vault.toBase58(),
strategy: strategy.toBase58(),
signature,
message: `Successfully withdrew ${input.withdrawAmount} from strategy`,
};
} catch (error: any) {
return {
status: "error",
message: `Failed to withdraw from strategy: ${error.message}`,
};
}
},
};
export default withdrawVoltrStrategyAction;

View File

@@ -18,6 +18,8 @@ import {
getPrimaryDomain,
launchPumpFunToken,
lendAsset,
luloLend,
luloWithdraw,
mintCollectionNFT,
openbookCreateMarket,
manifestCreateMarket,
@@ -67,6 +69,8 @@ import {
fetchPythPriceFeedID,
flashOpenTrade,
flashCloseTrade,
createMeteoraDynamicAMMPool,
createMeteoraDlmmPool,
createCollection,
createSingle,
multisig_transfer_from_treasury,
@@ -98,6 +102,18 @@ import {
withdrawFromDriftVault,
updateVaultDelegate,
get_token_balance,
getAvailableDriftSpotMarkets,
getAvailableDriftPerpMarkets,
stakeToDriftInsuranceFund,
requestUnstakeFromDriftInsuranceFund,
unstakeFromDriftInsuranceFund,
swapSpotToken,
calculatePerpMarketFundingRate,
getEntryQuoteOfPerpTrade,
getLendingAndBorrowAPY,
voltrGetPositionValues,
voltrDepositStrategy,
voltrWithdrawStrategy,
get_asset,
get_assets_by_authority,
get_assets_by_creator,
@@ -322,6 +338,14 @@ export class SolanaAgentKit {
return lendAsset(this, amount);
}
async luloLend(mintAddress: string, amount: number): Promise<string> {
return luloLend(this, mintAddress, amount);
}
async luloWithdraw(mintAddress: string, amount: number): Promise<string> {
return luloWithdraw(this, mintAddress, amount);
}
async getTPS(): Promise<number> {
return getTPS(this);
}
@@ -386,6 +410,57 @@ export class SolanaAgentKit {
);
}
async meteoraCreateDynamicPool(
tokenAMint: PublicKey,
tokenBMint: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
tradeFeeNumerator: number,
activationPoint: BN | null,
hasAlphaVault: boolean,
activationType: number,
): Promise<string> {
return createMeteoraDynamicAMMPool(
this,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
{
tradeFeeNumerator,
activationPoint,
hasAlphaVault,
activationType,
padding: new Array(90).fill(0),
},
);
}
async meteoraCreateDlmmPool(
tokenAMint: PublicKey,
tokenBMint: PublicKey,
binStep: number,
initialPrice: number,
priceRoundingUp: boolean,
feeBps: number,
activationType: number,
hasAlphaVault: boolean,
activationPoint: BN | undefined,
): Promise<string> {
return createMeteoraDlmmPool(
this,
binStep,
tokenAMint,
tokenBMint,
initialPrice,
priceRoundingUp,
feeBps,
activationType,
hasAlphaVault,
activationPoint,
);
}
async orcaClosePosition(positionMintAddress: PublicKey) {
return orcaClosePosition(this, positionMintAddress);
}
@@ -642,24 +717,43 @@ export class SolanaAgentKit {
}
async create3LandCollection(
optionsWithBase58: StoreInitOptions,
collectionOpts: CreateCollectionOptions,
isDevnet: boolean = false,
): Promise<string> {
const optionsWithBase58: StoreInitOptions = {
privateKey: this.wallet.secretKey,
};
if (isDevnet) {
optionsWithBase58.isMainnet = false;
} else {
optionsWithBase58.isMainnet = true;
}
const tx = await createCollection(optionsWithBase58, collectionOpts);
return `Transaction: ${tx}`;
}
async create3LandNft(
optionsWithBase58: StoreInitOptions,
collectionAccount: string,
createItemOptions: CreateSingleOptions,
isMainnet: boolean,
isDevnet: boolean = false,
withPool: boolean = false,
): Promise<string> {
const optionsWithBase58: StoreInitOptions = {
privateKey: this.wallet.secretKey,
};
if (isDevnet) {
optionsWithBase58.isMainnet = false;
} else {
optionsWithBase58.isMainnet = true;
}
const tx = await createSingle(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet,
!isDevnet,
withPool,
);
return `Transaction: ${tx}`;
}
@@ -738,6 +832,7 @@ export class SolanaAgentKit {
async createDriftUserAccount(depositAmount: number, depositSymbol: string) {
return await createDriftUserAccount(this, depositAmount, depositSymbol);
}
async createDriftVault(params: {
name: string;
marketName: `${string}-${string}`;
@@ -751,6 +846,7 @@ export class SolanaAgentKit {
}) {
return await createVault(this, params);
}
async depositIntoDriftVault(amount: number, vault: string) {
return await depositIntoVault(this, amount, vault);
}
@@ -833,6 +929,87 @@ export class SolanaAgentKit {
return await updateVaultDelegate(this, vaultAddress, delegate);
}
getAvailableDriftMarkets(type?: "spot" | "perp") {
switch (type) {
case "spot":
return getAvailableDriftSpotMarkets();
case "perp":
return getAvailableDriftPerpMarkets();
default:
return {
spot: getAvailableDriftSpotMarkets(),
perp: getAvailableDriftPerpMarkets(),
};
}
}
async stakeToDriftInsuranceFund(amount: number, symbol: string) {
return await stakeToDriftInsuranceFund(this, amount, symbol);
}
async requestUnstakeFromDriftInsuranceFund(amount: number, symbol: string) {
return await requestUnstakeFromDriftInsuranceFund(this, amount, symbol);
}
async unstakeFromDriftInsuranceFund(symbol: string) {
return await unstakeFromDriftInsuranceFund(this, symbol);
}
async driftSpotTokenSwap(
params: {
fromSymbol: string;
toSymbol: string;
slippage?: number;
} & (
| {
toAmount: number;
}
| { fromAmount: number }
),
) {
return await swapSpotToken(this, {
fromSymbol: params.fromSymbol,
toSymbol: params.toSymbol,
// @ts-expect-error - fromAmount and toAmount are mutually exclusive
fromAmount: params.fromAmount,
// @ts-expect-error - fromAmount and toAmount are mutually exclusive
toAmount: params.toAmount,
slippage: params.slippage,
});
}
async getPerpMarketFundingRate(
symbol: `${string}-PERP`,
period: "year" | "hour" = "year",
) {
return calculatePerpMarketFundingRate(this, symbol, period);
}
async getEntryQuoteOfPerpTrade(
amount: number,
symbol: `${string}-PERP`,
action: "short" | "long",
) {
return getEntryQuoteOfPerpTrade(symbol, amount, action);
}
async getLendAndBorrowAPY(symbol: string) {
return getLendingAndBorrowAPY(this, symbol);
}
async voltrDepositStrategy(
depositAmount: BN,
vault: PublicKey,
strategy: PublicKey,
): Promise<string> {
return voltrDepositStrategy(this, depositAmount, vault, strategy);
}
async voltrWithdrawStrategy(
withdrawAmount: BN,
vault: PublicKey,
strategy: PublicKey,
): Promise<string> {
return voltrWithdrawStrategy(this, withdrawAmount, vault, strategy);
}
async voltrGetPositionValues(vault: PublicKey): Promise<string> {
return voltrGetPositionValues(this, vault);
}
async getAsset(assetId: string): Promise<DasApiAsset> {
return get_asset(this, assetId);
}

View File

@@ -27,9 +27,23 @@ export const DEFAULT_OPTIONS = {
LEVERAGE_BPS: 50000, // 10000 = x1, 50000 = x5, 100000 = x10, 1000000 = x100
} as const;
export const METEORA_DYNAMIC_FEE_DENOMINATOR = 100000;
/**
* Jupiter API URL
*/
export const JUP_API = "https://quote-api.jup.ag/v6";
export const JUP_REFERRAL_ADDRESS =
"REFER4ZgmyYx9c6He5XfaTMiGfdLwRnkV4RPp9t9iF3";
export const METEORA_DYNAMIC_AMM_PROGRAM_ID = new PublicKey(
"Eo7WjKq67rjJQSZxS6z3YkapzY3eMj6Xy8X5EQVn5UaB",
);
export const METEORA_DLMM_PROGRAM_ID = new PublicKey(
"LbVRzDTvBDEcrthxfZ4RL6yiq3uZw8bS6MwtdY6UhFQ",
);
/**
* Minimum compute price required to carry out complex transactions on the Drift protocol
*/
export const MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS =
0.000003 * 1000000 * 1000000;

View File

@@ -1,16 +1,12 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import {
CreateCollectionOptions,
StoreInitOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
import { CreateCollectionOptions } from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
export class Solana3LandCreateCollection extends Tool {
name = "3land_minting_tool";
description = `Creates an NFT Collection that you can visit on 3.land's website (3.land/collection/{collectionAccount})
Inputs:
privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
isMainnet (required): defines is the tx takes places in mainnet
collectionSymbol (required): the symbol of the collection
collectionName (required): the name of the collection
@@ -26,14 +22,8 @@ export class Solana3LandCreateCollection extends Tool {
protected async _call(input: string): Promise<string> {
try {
const inputFormat = JSON.parse(input);
const privateKey = inputFormat.privateKey;
const isMainnet = inputFormat.isMainnet;
const optionsWithBase58: StoreInitOptions = {
...(privateKey && { privateKey }),
...(isMainnet && { isMainnet }),
};
const collectionSymbol = inputFormat?.collectionSymbol;
const collectionName = inputFormat?.collectionName;
const collectionDescription = inputFormat?.collectionDescription;
@@ -49,8 +39,8 @@ export class Solana3LandCreateCollection extends Tool {
};
const tx = await this.solanaKit.create3LandCollection(
optionsWithBase58,
collectionOpts,
!isMainnet,
);
return JSON.stringify({
status: "success",

View File

@@ -1,16 +1,12 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import {
CreateSingleOptions,
StoreInitOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
import { CreateSingleOptions } from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
export class Solana3LandCreateSingle extends Tool {
name = "3land_minting_tool";
description = `Creates an NFT and lists it on 3.land's website
Inputs:
privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
collectionAccount (optional): represents the account for the nft collection
itemName (required): the name of the NFT
sellerFee (required): the fee of the seller
@@ -21,7 +17,9 @@ export class Solana3LandCreateSingle extends Tool {
mainImageUrl (required): the main image of the NFT
coverImageUrl (optional): the cover image of the NFT
splHash (optional): the hash of the spl token, if not provided listing will be in $SOL
isMainnet (required): defines is the tx takes places in mainnet
poolName (optional): the name of the pool
isMainnet (required): defines if the tx takes places in mainnet
withPool (optional): defines if minted edition will be tied to a liquidity pool
`;
constructor(private solanaKit: SolanaAgentKit) {
@@ -31,13 +29,9 @@ export class Solana3LandCreateSingle extends Tool {
protected async _call(input: string): Promise<string> {
try {
const inputFormat = JSON.parse(input);
const privateKey = inputFormat.privateKey;
const isMainnet = inputFormat.isMainnet;
const optionsWithBase58: StoreInitOptions = {
...(privateKey && { privateKey }),
...(isMainnet && { isMainnet }),
};
const withPool = inputFormat.withPool;
const poolName = inputFormat.poolName;
const collectionAccount = inputFormat.collectionAccount;
@@ -52,6 +46,15 @@ export class Solana3LandCreateSingle extends Tool {
const coverImageUrl = inputFormat?.coverImageUrl;
const splHash = inputFormat?.splHash;
if (withPool) {
if (!poolName) {
throw new Error("poolName is required when withPool is true");
}
if (!splHash) {
throw new Error("splHash is required when withPool is true");
}
}
const createItemOptions: CreateSingleOptions = {
...(itemName && { itemName }),
...(sellerFee && { sellerFee }),
@@ -63,6 +66,7 @@ export class Solana3LandCreateSingle extends Tool {
...(mainImageUrl && { mainImageUrl }),
...(coverImageUrl && { coverImageUrl }),
...(splHash && { splHash }),
...(poolName && { poolName }),
};
if (!collectionAccount) {
@@ -70,10 +74,10 @@ export class Solana3LandCreateSingle extends Tool {
}
const tx = await this.solanaKit.create3LandNft(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet,
!isMainnet,
withPool,
);
return JSON.stringify({
status: "success",

View File

@@ -0,0 +1,39 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaDriftEntryQuoteOfPerpTradeTool extends Tool {
name = "drift_entry_quote_of_perp_trade";
description = `Get an entry quote for a perpetual trade on Drift protocol.
Inputs (JSON string):
- amount: number, amount to trade (required)
- symbol: string, market symbol (required)
- action: "long" | "short", trade direction (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const quote = await this.solanaKit.getEntryQuoteOfPerpTrade(
parsedInput.amount,
parsedInput.symbol,
parsedInput.action,
);
return JSON.stringify({
status: "success",
message: `Entry quote retrieved for ${parsedInput.action} ${parsedInput.amount} ${parsedInput.symbol}`,
data: quote,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "ENTRY_QUOTE_OF_PERP_TRADE_ERROR",
});
}
}
}

View File

@@ -13,3 +13,10 @@ export * from "./update_vault";
export * from "./vault_info";
export * from "./withdraw_from_account";
export * from "./withdraw_from_vault";
export * from "./perp_market_funding_rate";
export * from "./entry_quote_of_perp_trade";
export * from "./lend_and_borrow_apy";
export * from "./stake_to_insurance_fund";
export * from "./swap_spot_token";
export * from "./unstake_from_insurance_fund";
export * from "./request_unstake_from_insurance_fund";

View File

@@ -0,0 +1,32 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaDriftLendAndBorrowAPYTool extends Tool {
name = "drift_lend_and_borrow_apy";
description = `Get lending and borrowing APY for a token on Drift protocol.
Inputs (JSON string):
- symbol: string, token symbol (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const apyInfo = await this.solanaKit.getLendAndBorrowAPY(input);
return JSON.stringify({
status: "success",
message: `APY information retrieved for ${input}`,
data: apyInfo,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "LEND_AND_BORROW_APY_ERROR",
});
}
}
}

View File

@@ -0,0 +1,36 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaDriftPerpMarketFundingRateTool extends Tool {
name = "drift_perp_market_funding_rate";
description = `Get the funding rate for a perpetual market on Drift protocol.
Inputs (JSON string):
- symbol: string, market symbol (required)
- period: year or hour (default: hour)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const fundingRate = await this.solanaKit.getPerpMarketFundingRate(
parsedInput.symbol,
parsedInput.period,
);
return JSON.stringify({
status: "success",
message: `Funding rate retrieved for ${parsedInput.symbol}`,
data: fundingRate,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
});
}
}
}

View File

@@ -0,0 +1,37 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaRequestUnstakeFromDriftInsuranceFundTool extends Tool {
name = "request_unstake_from_drift_insurance_fund";
description = `Request to unstake tokens from Drift Insurance Fund.
Inputs (JSON string):
- amount: number, amount to unstake (required)
- symbol: string, token symbol (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const tx = await this.solanaKit.requestUnstakeFromDriftInsuranceFund(
parsedInput.amount,
parsedInput.symbol,
);
return JSON.stringify({
status: "success",
message: `Requested unstake of ${parsedInput.amount} ${parsedInput.symbol} from the Drift Insurance Fund`,
signature: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "REQUEST_UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ERROR",
});
}
}
}

View File

@@ -0,0 +1,37 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaStakeToDriftInsuranceFundTool extends Tool {
name = "stake_to_drift_insurance_fund";
description = `Stake a token to Drift Insurance Fund.
Inputs (JSON string):
- amount: number, amount to stake (required)
- symbol: string, token symbol (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const tx = await this.solanaKit.stakeToDriftInsuranceFund(
parsedInput.amount,
parsedInput.symbol,
);
return JSON.stringify({
status: "success",
message: `Staked ${parsedInput.amount} ${parsedInput.symbol} to the Drift Insurance Fund`,
signature: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "STAKE_TO_DRIFT_INSURANCE_FUND_ERROR",
});
}
}
}

View File

@@ -0,0 +1,37 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaDriftSpotTokenSwapTool extends Tool {
name = "drift_spot_token_swap";
description = `Swap spot tokens on Drift protocol.
Inputs (JSON string):
- fromSymbol: string, symbol of token to swap from (required)
- toSymbol: string, symbol of token to swap to (required)
- fromAmount: number, amount to swap from (optional) required if toAmount is not provided
- toAmount: number, amount to swap to (optional) required if fromAmount is not provided
- slippage: number, slippage tolerance in percentage (optional)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const tx = await this.solanaKit.driftSpotTokenSwap(parsedInput);
return JSON.stringify({
status: "success",
message: `Swapped ${parsedInput.fromAmount} ${parsedInput.fromSymbol} for ${parsedInput.toSymbol}`,
signature: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "DRIFT_SPOT_TOKEN_SWAP_ERROR",
});
}
}
}

View File

@@ -0,0 +1,32 @@
import { Tool } from "langchain/tools";
import type { SolanaAgentKit } from "../../agent";
export class SolanaUnstakeFromDriftInsuranceFundTool extends Tool {
name = "unstake_from_drift_insurance_fund";
description = `Unstake tokens from Drift Insurance Fund after request period has elapsed.
Inputs (JSON string):
- symbol: string, token symbol (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const tx = await this.solanaKit.unstakeFromDriftInsuranceFund(input);
return JSON.stringify({
status: "success",
message: `Unstaked ${input} from the Drift Insurance Fund`,
signature: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNSTAKE_FROM_DRIFT_INSURANCE_FUND_ERROR",
});
}
}
}

View File

@@ -24,10 +24,12 @@ export * from "./tiplink";
export * from "./sns";
export * from "./lightprotocol";
export * from "./squads";
export * from "./meteora";
export * from "./helius";
export * from "./drift";
export * from "./voltr";
import { SolanaAgentKit } from "../agent";
import type { SolanaAgentKit } from "../agent";
import {
SolanaBalanceTool,
SolanaBalanceOtherTool,
@@ -42,6 +44,8 @@ import {
SolanaPumpfunTokenLaunchTool,
SolanaCreateImageTool,
SolanaLendAssetTool,
SolanaLuloLendTool,
SolanaLuloWithdrawTool,
SolanaTPSCalculatorTool,
SolanaStakeTool,
SolanaRestakeTool,
@@ -93,6 +97,8 @@ import {
SolanaApproveProposal2by2Multisig,
SolanaExecuteProposal2by2Multisig,
SolanaRejectProposal2by2Multisig,
SolanaMeteoraCreateDynamicPool,
SolanaMeteoraCreateDlmmPool,
SolanaSendTransactionWithPriorityFee,
SolanaHeliusWebhookTool,
SolanaGetHeliusWebhookTool,
@@ -114,6 +120,16 @@ import {
SolanaUpdateDriftVaultTool,
SolanaWithdrawFromDriftAccountTool,
SolanaWithdrawFromDriftVaultTool,
SolanaDriftLendAndBorrowAPYTool,
SolanaDriftEntryQuoteOfPerpTradeTool,
SolanaDriftPerpMarketFundingRateTool,
SolanaDriftSpotTokenSwapTool,
SolanaRequestUnstakeFromDriftInsuranceFundTool,
SolanaStakeToDriftInsuranceFundTool,
SolanaUnstakeFromDriftInsuranceFundTool,
SolanaVoltrGetPositionValues,
SolanaVoltrDepositStrategy,
SolanaVoltrWithdrawStrategy,
SolanaGetAssetTool,
SolanaGetAssetsByAuthorityTool,
SolanaGetAssetsByCreatorTool,
@@ -135,6 +151,8 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaPumpfunTokenLaunchTool(solanaKit),
new SolanaCreateImageTool(solanaKit),
new SolanaLendAssetTool(solanaKit),
new SolanaLuloLendTool(solanaKit),
new SolanaLuloWithdrawTool(solanaKit),
new SolanaTPSCalculatorTool(solanaKit),
new SolanaStakeTool(solanaKit),
new SolanaRestakeTool(solanaKit),
@@ -152,6 +170,8 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaBatchOrderTool(solanaKit),
new SolanaCancelAllOrdersTool(solanaKit),
new SolanaWithdrawAllTool(solanaKit),
new SolanaMeteoraCreateDynamicPool(solanaKit),
new SolanaMeteoraCreateDlmmPool(solanaKit),
new SolanaClosePosition(solanaKit),
new SolanaOrcaCreateCLMM(solanaKit),
new SolanaOrcaCreateSingleSideLiquidityPool(solanaKit),
@@ -212,6 +232,16 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaDriftVaultInfoTool(solanaKit),
new SolanaWithdrawFromDriftAccountTool(solanaKit),
new SolanaWithdrawFromDriftVaultTool(solanaKit),
new SolanaDriftSpotTokenSwapTool(solanaKit),
new SolanaStakeToDriftInsuranceFundTool(solanaKit),
new SolanaRequestUnstakeFromDriftInsuranceFundTool(solanaKit),
new SolanaUnstakeFromDriftInsuranceFundTool(solanaKit),
new SolanaDriftLendAndBorrowAPYTool(solanaKit),
new SolanaDriftEntryQuoteOfPerpTradeTool(solanaKit),
new SolanaDriftPerpMarketFundingRateTool(solanaKit),
new SolanaVoltrGetPositionValues(solanaKit),
new SolanaVoltrDepositStrategy(solanaKit),
new SolanaVoltrWithdrawStrategy(solanaKit),
new SolanaGetAssetTool(solanaKit),
new SolanaGetAssetsByAuthorityTool(solanaKit),
new SolanaGetAssetsByCreatorTool(solanaKit),

View File

@@ -1 +1,3 @@
export * from "./lend_asset";
export * from "./lulo_lend";
export * from "./lulo_withdraw";

View File

@@ -0,0 +1,37 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
export class SolanaLuloLendTool extends Tool {
name = "solana_lulo_lend";
description = `Lend token for yield using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP)
Inputs:
mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)
amount: number, eg 1, 0.01 (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const mintAddress = parsedInput.mintAddress;
const amount = parsedInput.amount;
const tx = await this.solanaKit.luloLend(mintAddress, amount);
return JSON.stringify({
status: "success",
message: "Asset lent successfully",
transaction: tx,
amount,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -0,0 +1,37 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
export class SolanaLuloWithdrawTool extends Tool {
name = "solana_lulo_withdraw";
description = `Withdraw token USDC using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP)
Inputs (input is a json string):
mintAddress: string, eg "So11111111111111111111111111111111111111112" (required)
amount: number, eg 1, 0.01 (required)`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
const mintAddress = parsedInput.mintAddress;
const amount = parsedInput.amount;
const tx = await this.solanaKit.luloWithdraw(mintAddress, amount);
return JSON.stringify({
status: "success",
message: "Asset withdraw successfully",
transaction: tx,
amount,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -0,0 +1,2 @@
export * from "./meteora_dlmm_pool";
export * from "./meteora_dynamic_pool";

View File

@@ -0,0 +1,78 @@
import { PublicKey } from "@solana/web3.js";
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import { BN } from "bn.js";
export class SolanaMeteoraCreateDlmmPool extends Tool {
name = "meteora_create_dlmm_pool";
description = `Create a Meteora DLMM Pool. This function doesn't add liquidity.
Inputs (JSON string):
- tokenAMint: string, token A mint (required).
- tokenBMint: string, token B mint (required).
- binStep: number, pool bin step, e.g., 20 (required).
- initialPrice: number, pool initial price, e.g., 0.25 (required).
- feeBps: number, trade fee in percentage, e.g. 20 for 0.2% (required).
- priceRoundingUp: boolean, whether the initial price should be rounded up or not, default is true (optional).
- activationType: number, pool start trading time indicator. 0 is slot and 1 is timestamp, default is 1 for timestamp (optional).
- activationPoint: number, pool start trading slot / timestamp, default is null means pool can start trading immediately (optional).
- hasAlphaVault: boolean, whether the pool supports alpha vault, default is false (optional).
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
interface CreateMeteoraDlmmPoolInput {
tokenAMint: string;
tokenBMint: string;
binStep: number;
initialPrice: number;
feeBps: number;
priceRoundingUp?: boolean;
activationType?: number;
activationPoint?: number;
hasAlphaVault?: boolean;
}
const inputFormat: CreateMeteoraDlmmPoolInput = JSON.parse(input);
const tokenAMint = new PublicKey(inputFormat.tokenAMint);
const tokenBMint = new PublicKey(inputFormat.tokenBMint);
const binStep = inputFormat.binStep;
const initialPrice = inputFormat.initialPrice;
const feeBps = inputFormat.feeBps;
const priceRoundingUp = inputFormat.priceRoundingUp ?? true;
const activationType = inputFormat.activationType ?? 1;
const activationPoint = inputFormat.activationPoint
? new BN(inputFormat.activationPoint)
: undefined;
const hasAlphaVault = inputFormat.hasAlphaVault ?? false;
const txId = await this.solanaKit.meteoraCreateDlmmPool(
tokenAMint,
tokenBMint,
binStep,
initialPrice,
priceRoundingUp,
feeBps,
activationType,
hasAlphaVault,
activationPoint,
);
return JSON.stringify({
status: "success",
message: "Meteora DLMM pool created successfully.",
transaction: txId,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -0,0 +1,111 @@
import { PublicKey } from "@solana/web3.js";
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import { BN } from "bn.js";
import { MintLayout } from "@solana/spl-token";
import Decimal from "decimal.js";
export class SolanaMeteoraCreateDynamicPool extends Tool {
name = "meteora_create_dynamic_pool";
description = `Create a Meteora Dynamic Pool. This function adds liquidity with a constant-product formula.
Inputs (JSON string):
- tokenAMint: string, token A mint (required).
- tokenBMint: string, token B mint (required).
- tokenAAmount: number, token A amount not including decimals, e.g., 1 (required).
- tokenBAmount: number, token B amount not including decimals, e.g., 0.2 (required).
- tradeFeeNumerator: number, trade fee numerator, e.g., 2500 for 2.5% (required).
- activationType: number, pool start trading time indicator, 0 is slot and 1 is timestamp, default is 1 for timestamp (optional).
- activationPoint: number, pool start trading slot / timestamp, default is null means pool can start trading immediately (optional).
- hasAlphaVault: boolean, whether the pool supports alpha vault, default is false (optional).
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
interface CreateMeteoraDynamicAmmPoolInput {
tokenAMint: string;
tokenBMint: string;
tokenAAmount: number;
tokenBAmount: number;
tradeFeeNumerator: number;
activationType?: number;
activationPoint?: number;
hasAlphaVault?: boolean;
}
const inputFormat: CreateMeteoraDynamicAmmPoolInput = JSON.parse(input);
const tokenAMint = new PublicKey(inputFormat.tokenAMint);
const tokenBMint = new PublicKey(inputFormat.tokenBMint);
const tokenAMintInfo =
await this.solanaKit.connection.getAccountInfo(tokenAMint);
const tokenBMintInfo =
await this.solanaKit.connection.getAccountInfo(tokenBMint);
if (!tokenAMintInfo) {
return JSON.stringify({
status: "error",
message: "failed to fetch tokenAMint info",
code: "UNKNOWN_ERROR",
});
}
if (!tokenBMintInfo) {
return JSON.stringify({
status: "error",
message: "failed to fetch tokenBMint info",
code: "UNKNOWN_ERROR",
});
}
const tokenADecimals = MintLayout.decode(tokenAMintInfo.data).decimals;
const tokenBDecimals = MintLayout.decode(tokenBMintInfo.data).decimals;
const tokenAAmount = new BN(
new Decimal(inputFormat.tokenAAmount)
.mul(10 ** tokenADecimals)
.toString(),
);
const tokenBAmount = new BN(
new Decimal(inputFormat.tokenBAmount)
.mul(10 ** tokenBDecimals)
.toString(),
);
const tradeFeeNumerator = new BN(
inputFormat.tradeFeeNumerator.toString(),
).toNumber();
const activationType = inputFormat.activationType ?? 1;
const activationPoint = inputFormat.activationPoint
? new BN(inputFormat.activationPoint)
: null;
const hasAlphaVault = inputFormat.hasAlphaVault ?? false;
const txId = await this.solanaKit.meteoraCreateDynamicPool(
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
tradeFeeNumerator,
activationPoint,
hasAlphaVault,
activationType,
);
return JSON.stringify({
status: "success",
message: "Meteora Dynamic pool created successfully.",
transaction: txId,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -0,0 +1,39 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import { PublicKey } from "@solana/web3.js";
import { BN } from "bn.js";
export class SolanaVoltrDepositStrategy extends Tool {
name = "solana_voltr_deposit_strategy";
description = `Deposit amount into a strategy for Voltr's vaults
Inputs (input is a json string):
depositAmount: number (required)
vault: string (required)
strategy: string (required)
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
const inputFormat = JSON.parse(input);
const tx = await this.solanaKit.voltrDepositStrategy(
new BN(inputFormat.depositAmount),
new PublicKey(inputFormat.vault),
new PublicKey(inputFormat.strategy),
);
return JSON.stringify({
status: "success",
message: `Deposited ${inputFormat.depositAmount} into strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`,
transaction: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -0,0 +1,18 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import { PublicKey } from "@solana/web3.js";
export class SolanaVoltrGetPositionValues extends Tool {
name = "solana_voltr_get_position_values";
description = `Get the total asset value and current value for each strategy of a given Voltr vault
Inputs:
vault: string (required)
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
return this.solanaKit.voltrGetPositionValues(new PublicKey(input));
}
}

View File

@@ -0,0 +1,3 @@
export * from "./deposit_strategy";
export * from "./withdraw_strategy";
export * from "./get_position_values";

View File

@@ -0,0 +1,39 @@
import { Tool } from "langchain/tools";
import { SolanaAgentKit } from "../../agent";
import { PublicKey } from "@solana/web3.js";
import { BN } from "bn.js";
export class SolanaVoltrWithdrawStrategy extends Tool {
name = "solana_voltr_withdraw_strategy";
description = `Withdraw amount from a strategy for Voltr's vaults
Inputs (input is a json string):
withdrawAmount: number (required)
vault: string (required)
strategy: string (required)
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
async _call(input: string): Promise<string> {
try {
const inputFormat = JSON.parse(input);
const tx = await this.solanaKit.voltrWithdrawStrategy(
new BN(inputFormat.withdrawAmount),
new PublicKey(inputFormat.vault),
new PublicKey(inputFormat.strategy),
);
return JSON.stringify({
status: "success",
message: `Withdrew ${inputFormat.withdrawAmount} from strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`,
transaction: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}

View File

@@ -37,7 +37,8 @@ export async function createSingle(
optionsWithBase58: StoreInitOptions,
collectionAccount: string,
createItemOptions: CreateSingleOptions,
isMainnet: boolean,
isMainnet: boolean = false,
withPool: boolean = false,
) {
try {
const landStore = isMainnet
@@ -49,6 +50,8 @@ export async function createSingle(
landStore,
collectionAccount,
createItemOptions,
true, //isAI
withPool,
);
return singleEditionTx;
} catch (error: any) {

View File

@@ -1,14 +1,25 @@
import {
BASE_PRECISION,
BigNum,
calculateDepositRate,
calculateEstimatedEntryPriceWithL2,
calculateInterestRate,
calculateLongShortFundingRateAndLiveTwaps,
convertToNumber,
DRIFT_PROGRAM_ID,
DriftClient,
FastSingleTxSender,
FUNDING_RATE_BUFFER_PRECISION,
FUNDING_RATE_PRECISION_EXP,
getInsuranceFundStakeAccountPublicKey,
getLimitOrderParams,
getMarketOrderParams,
getUserAccountPublicKeySync,
JupiterClient,
MainnetPerpMarkets,
MainnetSpotMarkets,
numberToSafeBN,
PERCENTAGE_PRECISION,
PositionDirection,
PostOnlyParams,
PRICE_PRECISION,
@@ -23,6 +34,8 @@ import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import { PublicKey } from "@solana/web3.js";
import { Transaction } from "@solana/web3.js";
import { ComputeBudgetProgram } from "@solana/web3.js";
import type { RawL2Output } from "./types";
import { MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS } from "../../constants";
export async function initClients(
agent: SolanaAgentKit,
@@ -56,7 +69,7 @@ export async function initClients(
activeSubAccountId: params?.activeSubAccountId,
subAccountIds: params?.subAccountIds,
txParams: {
computeUnitsPrice: 0.000001 * 1000000 * 1000000,
computeUnitsPrice: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
},
txSender: new FastSingleTxSender({
connection: agent.connection,
@@ -115,7 +128,10 @@ export async function createDriftUserAccount(
);
if (!token) {
throw new Error(`Token with symbol ${symbol} not found`);
throw new Error(`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}
`);
}
if (!userAccountExists) {
@@ -171,7 +187,11 @@ export async function depositToDriftUserAccount(
);
if (!token) {
throw new Error(`Token with symbol ${symbol} not found`);
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
if (!userAccountExists) {
@@ -193,7 +213,7 @@ export async function depositToDriftUserAccount(
const tx = new Transaction().add(...depInstruction).add(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 0.000001 * 1000000 * 1000000,
microLamports: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
}),
);
tx.recentBlockhash = latestBlockhash.blockhash;
@@ -237,7 +257,11 @@ export async function withdrawFromDriftUserAccount(
);
if (!token) {
throw new Error(`Token with symbol ${symbol} not found`);
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const withdrawAmount = numberToSafeBN(amount, token.precision);
@@ -254,7 +278,7 @@ export async function withdrawFromDriftUserAccount(
const tx = new Transaction().add(...withdrawInstruction).add(
ComputeBudgetProgram.setComputeUnitPrice({
microLamports: 0.000001 * 1000000 * 1000000,
microLamports: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
}),
);
tx.recentBlockhash = latestBlockhash.blockhash;
@@ -313,7 +337,11 @@ export async function driftPerpTrade(
);
if (!market) {
throw new Error(`Token with symbol ${params.symbol} not found`);
throw new Error(
`Token with symbol ${params.symbol} not found. Here's a list of available perp markets: ${MainnetPerpMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const baseAssetPrice = driftClient.getOracleDataForPerpMarket(
@@ -357,7 +385,7 @@ export async function driftPerpTrade(
marketIndex: market.marketIndex,
}),
{
computeUnitsPrice: 0.000001 * 1000000 * 1000000,
computeUnitsPrice: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
},
);
}
@@ -388,9 +416,11 @@ export async function doesUserHaveDriftAccount(agent: SolanaAgentKit) {
agent.wallet.publicKey,
),
});
await user.subscribe();
user.getActivePerpPositions();
const userAccountExists = await user.exists();
await cleanUp();
await user.unsubscribe();
return {
hasAccount: userAccountExists,
account: user.userAccountPublicKey,
@@ -433,10 +463,9 @@ export async function driftUserAccountInfo(agent: SolanaAgentKit) {
}));
const spotPositions = account.spotPositions.map((pos) => ({
...pos,
scaledBalance: convertToNumber(pos.scaledBalance, BASE_PRECISION),
cumulativeDeposits: convertToNumber(
pos.cumulativeDeposits,
BASE_PRECISION,
availableBalance: convertToNumber(
pos.scaledBalance,
MainnetSpotMarkets[pos.marketIndex].precision,
),
symbol: MainnetSpotMarkets.find((v) => v.marketIndex === pos.marketIndex)
?.symbol,
@@ -446,8 +475,6 @@ export async function driftUserAccountInfo(agent: SolanaAgentKit) {
...account,
name: account.name,
authority: account.authority,
totalDeposits: `$${convertToNumber(account.totalDeposits, QUOTE_PRECISION)}`,
totalWithdraws: `$${convertToNumber(account.totalWithdraws, QUOTE_PRECISION)}`,
settledPerpPnl: `$${convertToNumber(account.settledPerpPnl, QUOTE_PRECISION)}`,
lastActiveSlot: account.lastActiveSlot.toNumber(),
perpPositions,
@@ -458,3 +485,523 @@ export async function driftUserAccountInfo(agent: SolanaAgentKit) {
throw new Error(`Failed to check user account: ${e.message}`);
}
}
/**
* Get available spot markets on drift protocol
*/
export function getAvailableDriftSpotMarkets() {
return MainnetSpotMarkets;
}
/**
* Get available perp markets on drift protocol
*/
export function getAvailableDriftPerpMarkets() {
return MainnetPerpMarkets;
}
/**
* Stake a token to the drift insurance fund
* @param agent
* @param amount
* @param symbol
*/
export async function stakeToDriftInsuranceFund(
agent: SolanaAgentKit,
amount: number,
symbol: string,
) {
try {
const { cleanUp, driftClient } = await initClients(agent);
const token = MainnetSpotMarkets.find(
(v) => v.symbol === symbol.toUpperCase(),
);
if (!token) {
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const deriveInsuranceFundStakeAccount =
getInsuranceFundStakeAccountPublicKey(
driftClient.program.programId,
agent.wallet.publicKey,
token.marketIndex,
);
let shouldCreateAccount = false;
try {
await driftClient.connection.getAccountInfo(
deriveInsuranceFundStakeAccount,
);
} catch (e) {
// @ts-expect-error - error message is a string
if (e.message.includes("Account not found")) {
shouldCreateAccount = true;
}
}
const signature = await driftClient.addInsuranceFundStake({
amount: numberToSafeBN(amount, token.precision),
marketIndex: token.marketIndex,
collateralAccountPublicKey: getAssociatedTokenAddressSync(
token.mint,
agent.wallet.publicKey,
),
initializeStakeAccount: shouldCreateAccount,
txParams: {
computeUnitsPrice: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
},
});
await cleanUp();
return signature;
} catch (e) {
// @ts-expect-error - error message is a string
throw new Error(`Failed to get APYs: ${e.message}`);
}
}
/**
* Request an unstake from the drift insurance fund
* @param agent
* @param amount
* @param symbol
*/
export async function requestUnstakeFromDriftInsuranceFund(
agent: SolanaAgentKit,
amount: number,
symbol: string,
) {
try {
const { driftClient, cleanUp } = await initClients(agent);
const token = MainnetSpotMarkets.find(
(v) => v.symbol === symbol.toUpperCase(),
);
if (!token) {
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const signature = await driftClient.requestRemoveInsuranceFundStake(
token.marketIndex,
numberToSafeBN(amount, token.precision),
{ computeUnitsPrice: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS },
);
await cleanUp();
return signature;
} catch (e) {
// @ts-expect-error error message is a string
throw new Error(`Failed to unstake from insurance fund: ${e.message}`);
}
}
/**
* Unstake requested funds from the drift insurance fund once cool down period is elapsed
* @param agent
* @param symbol
*/
export async function unstakeFromDriftInsuranceFund(
agent: SolanaAgentKit,
symbol: string,
) {
try {
const { driftClient, cleanUp } = await initClients(agent);
const token = MainnetSpotMarkets.find(
(v) => v.symbol === symbol.toUpperCase(),
);
if (!token) {
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const signature = await driftClient.removeInsuranceFundStake(
token.marketIndex,
getAssociatedTokenAddressSync(token.mint, agent.wallet.publicKey),
{
computeUnitsPrice: MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS,
},
);
await cleanUp();
return signature;
} catch (e) {
// @ts-expect-error error message is a string
throw new Error(`Failed to unstake from insurance fund: ${e.message}`);
}
}
/**
* Swap a spot token for another on drift
* @param agent
* @param params
* @param params.fromSymbol symbol of the token to deposit
* @param params.toSymbol symbol of the token to receive
* @param params.fromAmount amount of the token to deposit
* @param params.toAmount amount of the token to receive
* @param params.slippage slippage tolerance in percentage
*/
export async function swapSpotToken(
agent: SolanaAgentKit,
params: {
fromSymbol: string;
toSymbol: string;
slippage?: number | undefined;
} & (
| {
fromAmount: number;
}
| {
toAmount: number;
}
),
) {
try {
const { driftClient, cleanUp } = await initClients(agent);
const fromToken = MainnetSpotMarkets.find(
(v) => v.symbol === params.fromSymbol.toUpperCase(),
);
const toToken = MainnetSpotMarkets.find(
(v) => v.symbol === params.toSymbol.toUpperCase(),
);
if (!fromToken) {
throw new Error(
`Token with symbol ${params.fromSymbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
if (!toToken) {
throw new Error(
`Token with symbol ${params.toSymbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
let txSig: string;
// @ts-expect-error - false undefined type conflict
if (params.fromAmount) {
const jupiterClient = new JupiterClient({ connection: agent.connection });
// @ts-expect-error - false undefined type conflict
const fromAmount = numberToSafeBN(params.fromAmount, fromToken.precision);
const res = await (
await fetch(
`https://quote-api.jup.ag/v6/quote?inputMint=${fromToken.mint}&outputMint=${toToken.mint}&amount=${fromAmount.toNumber()}&slippageBps=${(params.slippage ?? 0.5) * 100}&swapMode=ExactIn`,
)
).json();
const signature = await driftClient.swap({
amount: fromAmount,
inMarketIndex: fromToken.marketIndex,
outMarketIndex: toToken.marketIndex,
jupiterClient: jupiterClient,
v6: {
quote: res,
},
slippageBps: (params.slippage ?? 0.5) * 100,
swapMode: "ExactIn",
});
txSig = signature;
}
// @ts-expect-error - false undefined type conflict
if (params.toAmount) {
const jupiterClient = new JupiterClient({ connection: agent.connection });
// @ts-expect-error - false undefined type conflict
const toAmount = numberToSafeBN(params.toAmount, toToken.precision);
const res = await (
await fetch(
`https://quote-api.jup.ag/v6/quote?inputMint=${fromToken.mint}&outputMint=${toToken.mint}&amount=${toAmount.toNumber()}&slippageBps=${(params.slippage ?? 0.5) * 100}&swapMode=ExactOut`,
)
).json();
const signature = await driftClient.swap({
amount: toAmount,
inMarketIndex: toToken.marketIndex,
outMarketIndex: fromToken.marketIndex,
jupiterClient: jupiterClient,
v6: {
quote: res,
},
slippageBps: (params.slippage ?? 0.5) * 100,
swapMode: "ExactOut",
});
txSig = signature;
}
await cleanUp();
// @ts-expect-error - false use before assignment
if (txSig) {
return txSig;
}
throw new Error("Either fromAmount or toAmount must be provided");
} catch (e) {
// @ts-expect-error error message is a string
throw new Error(`Failed to swap token: ${e.message}`);
}
}
/**
* To get funding rate as a percentage, you need to multiply by the funding rate buffer precision
* @param rawFundingRate
*/
export function getFundingRateAsPercentage(rawFundingRate: anchor.BN) {
return BigNum.from(
rawFundingRate.mul(FUNDING_RATE_BUFFER_PRECISION),
FUNDING_RATE_PRECISION_EXP,
).toNum();
}
/**
* Calculate the funding rate for a perpetual market
* @param agent
* @param marketSymbol
*/
export async function calculatePerpMarketFundingRate(
agent: SolanaAgentKit,
marketSymbol: `${string}-PERP`,
period: "year" | "hour",
) {
try {
const { driftClient, cleanUp } = await initClients(agent);
const market = driftClient.getMarketIndexAndType(
`${marketSymbol.toUpperCase()}`,
);
if (!market) {
throw new Error(
`This market isn't available on the Drift Protocol. Here's a list of markets that are: ${MainnetPerpMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const marketAccount = driftClient.getPerpMarketAccount(market.marketIndex);
if (!marketAccount) {
throw new Error("Market account not found");
}
const [, , longFundingRate, shortFundingRate] =
await calculateLongShortFundingRateAndLiveTwaps(
marketAccount,
driftClient.getOracleDataForPerpMarket(market.marketIndex),
undefined,
new anchor.BN(Date.now()),
);
await cleanUp();
let longFundingRateNum = getFundingRateAsPercentage(longFundingRate);
let shortFundingRateNum = getFundingRateAsPercentage(shortFundingRate);
if (period === "year") {
const paymentsPerYear = 24 * 365.25;
longFundingRateNum *= paymentsPerYear;
shortFundingRateNum *= paymentsPerYear;
}
const longsArePaying = longFundingRateNum > 0;
const shortsArePaying = !(shortFundingRateNum > 0);
const longsAreString = longsArePaying ? "pay" : "receive";
const shortsAreString = !shortsArePaying ? "receive" : "pay";
const absoluteLongFundingRateNum = Math.abs(longFundingRateNum);
const absoluteShortFundingRateNum = Math.abs(shortFundingRateNum);
const formattedLongRatePct = absoluteLongFundingRateNum.toFixed(
period === "hour" ? 5 : 2,
);
const formattedShortRatePct = absoluteShortFundingRateNum.toFixed(
period === "hour" ? 5 : 2,
);
const paymentUnit = period === "year" ? "% APR" : "%";
const friendlyString = `At this rate, longs would ${longsAreString} ${formattedLongRatePct} ${paymentUnit} and shorts would ${shortsAreString} ${formattedShortRatePct} ${paymentUnit} at the end of the hour.`;
return {
longRate: longsArePaying
? -absoluteLongFundingRateNum
: absoluteLongFundingRateNum,
shortRate: shortsArePaying
? -absoluteShortFundingRateNum
: absoluteShortFundingRateNum,
friendlyString,
};
} catch (e) {
throw new Error(
// @ts-expect-error e.message is a string
`Something went wrong while trying to get the market's funding rate. Here's some more context: ${e.message}`,
);
}
}
export async function getL2OrderBook(marketSymbol: `${string}-PERP`) {
try {
const serializedOrderbook: RawL2Output = await (
await fetch(
`https://dlob.drift.trade/l2?marketName=${marketSymbol.toUpperCase()}&includeOracle=true`,
)
).json();
return {
asks: serializedOrderbook.asks.map((ask) => ({
price: new anchor.BN(ask.price),
size: new anchor.BN(ask.size),
sources: Object.entries(ask.sources).reduce((previous, [key, val]) => {
return {
...(previous ?? {}),
[key]: new anchor.BN(val),
};
}, {}),
})),
bids: serializedOrderbook.bids.map((bid) => ({
price: new anchor.BN(bid.price),
size: new anchor.BN(bid.size),
sources: Object.entries(bid.sources).reduce((previous, [key, val]) => {
return {
...(previous ?? {}),
[key]: new anchor.BN(val),
};
}, {}),
})),
oracleData: {
price: serializedOrderbook.oracleData.price
? new anchor.BN(serializedOrderbook.oracleData.price)
: undefined,
slot: serializedOrderbook.oracleData.slot
? new anchor.BN(serializedOrderbook.oracleData.slot)
: undefined,
confidence: serializedOrderbook.oracleData.confidence
? new anchor.BN(serializedOrderbook.oracleData.confidence)
: undefined,
hasSufficientNumberOfDataPoints:
serializedOrderbook.oracleData.hasSufficientNumberOfDataPoints,
twap: serializedOrderbook.oracleData.twap
? new anchor.BN(serializedOrderbook.oracleData.twap)
: undefined,
twapConfidence: serializedOrderbook.oracleData.twapConfidence
? new anchor.BN(serializedOrderbook.oracleData.twapConfidence)
: undefined,
maxPrice: serializedOrderbook.oracleData.maxPrice
? new anchor.BN(serializedOrderbook.oracleData.maxPrice)
: undefined,
},
slot: serializedOrderbook.slot,
};
} catch (e) {
throw new Error(`Failed to get ${marketSymbol} order book: ${e}`);
}
}
/**
* Get the estimated entry quote of a perp trade
* @param agent
* @param marketSymbol
* @param amount
* @param type
*/
export async function getEntryQuoteOfPerpTrade(
marketSymbol: `${string}-PERP`,
amount: number,
type: "long" | "short",
) {
try {
const l2OrderBookData = await getL2OrderBook(marketSymbol);
const estimatedEntryPriceData = calculateEstimatedEntryPriceWithL2(
"quote",
numberToSafeBN(amount, BASE_PRECISION),
type === "long" ? PositionDirection.LONG : PositionDirection.SHORT,
BASE_PRECISION,
// @ts-expect-error - false type conflict
l2OrderBookData,
);
return {
entryPrice: convertToNumber(
estimatedEntryPriceData.entryPrice,
QUOTE_PRECISION,
),
priceImpact: convertToNumber(
estimatedEntryPriceData.priceImpact,
QUOTE_PRECISION,
),
bestPrice: convertToNumber(
estimatedEntryPriceData.bestPrice,
QUOTE_PRECISION,
),
worstPrice: convertToNumber(
estimatedEntryPriceData.worstPrice,
QUOTE_PRECISION,
),
};
} catch (e) {
// @ts-expect-error - error message is a string
throw new Error(`Failed to get entry quote: ${e.message}`);
}
}
/**
* Get the APY for lending and borrowing a specific token on drift protocol
* @param agent
* @param symbol
*/
export async function getLendingAndBorrowAPY(
agent: SolanaAgentKit,
symbol: string,
) {
try {
const { driftClient, cleanUp } = await initClients(agent);
const token = MainnetSpotMarkets.find(
(v) => v.symbol === symbol.toUpperCase(),
);
if (!token) {
throw new Error(
`Token with symbol ${symbol} not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map(
(v) => v.symbol,
).join(", ")}`,
);
}
const marketAccount = driftClient.getSpotMarketAccount(token.marketIndex);
if (!marketAccount) {
throw new Error("Market account not found");
}
const lendAPY = calculateDepositRate(marketAccount);
const borrowAPY = calculateInterestRate(marketAccount);
await cleanUp();
return {
lendingAPY: convertToNumber(lendAPY, PERCENTAGE_PRECISION) * 100, // convert to percentage
borrowAPY: convertToNumber(borrowAPY, PERCENTAGE_PRECISION) * 100, // convert to percentage
};
} catch (e) {
// @ts-expect-error - error message is a string
throw new Error(`Failed to get APYs: ${e.message}`);
}
}

View File

@@ -37,14 +37,18 @@ export function getMarketIndexAndType(name: `${string}-${string}`) {
if (type === "PERP") {
const token = MainnetPerpMarkets.find((v) => v.baseAssetSymbol === symbol);
if (!token) {
throw new Error("Drift doesn't have that market");
throw new Error(
`Drift doesn't have that market. Here's a list of available perp markets: ${MainnetPerpMarkets.map((v) => v.baseAssetSymbol).join(", ")}`,
);
}
return { marketIndex: token.marketIndex, marketType: MarketType.PERP };
}
const token = MainnetSpotMarkets.find((v) => v.symbol === symbol);
if (!token) {
throw new Error("Drift doesn't have that market");
throw new Error(
`Drift doesn't have that market. Here's a list of available spot markets: ${MainnetSpotMarkets.map((v) => v.symbol).join(", ")}`,
);
}
return { marketIndex: token.marketIndex, marketType: MarketType.SPOT };
}
@@ -134,22 +138,22 @@ export async function createVault(
const { vaultClient, driftClient, cleanUp } = await initClients(agent);
const marketIndexAndType = getMarketIndexAndType(params.marketName);
if (!marketIndexAndType) {
throw new Error("Invalid market name");
}
const spotMarket = driftClient.getSpotMarketAccount(
marketIndexAndType.marketIndex,
);
if (!spotMarket) {
throw new Error("Market not found");
throw new Error(
`Market not found. Here's a list of available spot markets: ${MainnetSpotMarkets.map((v) => `${v.symbol}-SPOT`).join(", ")}`,
);
}
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
if (marketIndexAndType.marketType === MarketType.PERP) {
throw new Error("Only SPOT market names are supported");
throw new Error(
`Only SPOT market names are supported. Such as ${MainnetSpotMarkets.map((v) => `${v.symbol}-SPOT`).join(", ")}`,
);
}
const tx = await vaultClient.initializeVault({
@@ -239,7 +243,9 @@ export async function updateVault(
);
if (!spotMarket) {
throw new Error("Market not found");
throw new Error(
"Market not found. This vault's market is no longer supported",
);
}
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
@@ -370,7 +376,9 @@ export async function depositIntoVault(
);
if (!spotMarket) {
throw new Error("Market not found");
throw new Error(
"Market not found. This vaults market is no longer supported",
);
}
const spotPrecision = TEN.pow(new BN(spotMarket.decimals));
@@ -544,7 +552,7 @@ export async function tradeDriftVault(
if (!isOwned) {
throw new Error(
"This vault is owned by someone else, so you can't trade with it",
"This vault is owned/delegated to someone else, you can't trade with it",
);
}

33
src/tools/drift/types.ts Normal file
View File

@@ -0,0 +1,33 @@
import type { L2OrderBook, MarketType, OraclePriceData } from "@drift-labs/sdk";
export type L2WithOracle = L2OrderBook & { oracleData: OraclePriceData };
export type RawL2Output = {
marketIndex: number;
marketType: MarketType;
marketName: string;
asks: {
price: string;
size: string;
sources: {
[key: string]: string;
};
}[];
bids: {
price: string;
size: string;
sources: {
[key: string]: string;
};
}[];
oracleData: {
price: string;
slot: string;
confidence: string;
hasSufficientNumberOfDataPoints: boolean;
twap?: string;
twapConfidence?: string;
maxPrice?: string;
};
slot?: number;
};

View File

@@ -24,4 +24,6 @@ export * from "./3land";
export * from "./tiplink";
export * from "./lightprotocol";
export * from "./squads";
export * from "./meteora";
export * from "./helius";
export * from "./voltr";

View File

@@ -1 +1,3 @@
export * from "./lend";
export * from "./lulo_lend";
export * from "./lulo_withdraw";

View File

@@ -0,0 +1,66 @@
import { VersionedTransaction } from "@solana/web3.js";
import { SolanaAgentKit } from "../../index";
/**
* Lend tokens for yields using Lulo
* @param agent SolanaAgentKit instance
* @param mintAddress SPL Mint address
* @param amount Amount to lend
* @returns Transaction signature
*/
export async function luloLend(
agent: SolanaAgentKit,
mintAddress: string,
amount: number,
): Promise<string> {
try {
const response = await fetch(
`https://api.flexlend.fi/generate/account/deposit?priorityFee=50000`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-wallet-pubkey": agent.wallet.publicKey.toBase58(),
"x-api-key": process.env.FLEXLEND_API_KEY!,
},
body: JSON.stringify({
owner: agent.wallet.publicKey.toBase58(),
mintAddress: mintAddress,
depositAmount: amount.toString(),
}),
},
);
const {
data: { transactionMeta },
} = await response.json();
// Deserialize the transaction
const luloTxn = VersionedTransaction.deserialize(
Buffer.from(transactionMeta[0].transaction, "base64"),
);
// Get a recent blockhash and set it
const { blockhash } = await agent.connection.getLatestBlockhash();
luloTxn.message.recentBlockhash = blockhash;
// Sign and send transaction
luloTxn.sign([agent.wallet]);
const signature = await agent.connection.sendTransaction(luloTxn, {
preflightCommitment: "confirmed",
maxRetries: 3,
});
// Wait for confirmation using the latest strategy
const latestBlockhash = await agent.connection.getLatestBlockhash();
await agent.connection.confirmTransaction({
signature,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
});
return signature;
} catch (error: any) {
throw new Error(`Lending failed: ${error.message}`);
}
}

View File

@@ -0,0 +1,71 @@
import { VersionedTransaction } from "@solana/web3.js";
import { SolanaAgentKit } from "../../index";
/**
* Withdraw tokens for yields using Lulo
* @param agent SolanaAgentKit instance
* @param mintAddress SPL Mint address
* @param amount Amount to withdraw
* @returns Transaction signature
*/
export async function luloWithdraw(
agent: SolanaAgentKit,
mintAddress: string,
amount: number,
): Promise<string> {
try {
if (!agent.config.FLEXLEND_API_KEY) {
throw new Error("Lulo API key not found in agent configuration");
}
const response = await fetch(
`https://api.flexlend.fi/generate/account/withdraw?priorityFee=50000`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-wallet-pubkey": agent.wallet.publicKey.toBase58(),
"x-api-key": agent.config.FLEXLEND_API_KEY,
},
body: JSON.stringify({
owner: agent.wallet.publicKey.toBase58(),
mintAddress: mintAddress,
depositAmount: amount,
}),
},
);
const {
data: { transactionMeta },
} = await response.json();
// Deserialize the transaction
const luloTxn = VersionedTransaction.deserialize(
Buffer.from(transactionMeta[0].transaction, "base64"),
);
// Get a recent blockhash and set it
const { blockhash } = await agent.connection.getLatestBlockhash();
luloTxn.message.recentBlockhash = blockhash;
// Sign and send transaction
luloTxn.sign([agent.wallet]);
const signature = await agent.connection.sendTransaction(luloTxn, {
preflightCommitment: "confirmed",
maxRetries: 3,
});
// Wait for confirmation using the latest strategy
const latestBlockhash = await agent.connection.getLatestBlockhash();
await agent.connection.confirmTransaction({
signature,
blockhash: latestBlockhash.blockhash,
lastValidBlockHeight: latestBlockhash.lastValidBlockHeight,
});
return signature;
} catch (error: any) {
throw new Error(`Lending failed: ${error.message}`);
}
}

View File

@@ -0,0 +1,70 @@
import { SolanaAgentKit } from "../../agent";
import BN from "bn.js";
import { PublicKey } from "@solana/web3.js";
import DLMM, { ActivationType } from "@meteora-ag/dlmm";
import { getMint } from "@solana/spl-token";
import { sendTx } from "../../utils/send_tx";
/**
* Create Meteora DLMM pool
* @param agent SolanaAgentKit instance
* @param binStep DLMM pool bin step
* @param tokenAMint Token A mint
* @param tokenBMint Token B mint
* @param initialPrice Initial pool price in ratio tokenA / tokenB
* @param priceRoundingUp Whether to rounding up the initial pool price
* @param feeBps Pool trading fee in BPS
* @param activationType Pool activation type (ActivationType.Timestamp or ActivationType.Slot)
* @param hasAlphaVault Whether the pool has Meteora alpha vault or not
* @param activationPoint Activation point depending on activation type, or null if pool doesn't have an activation point
* @returns Transaction signature
*/
export async function createMeteoraDlmmPool(
agent: SolanaAgentKit,
binStep: number,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
initialPrice: number,
priceRoundingUp: boolean,
feeBps: number,
activationType: ActivationType,
hasAlphaVault: boolean,
activationPoint: BN | undefined,
): Promise<string> {
const tokenAMintInfo = await getMint(agent.connection, tokenAMint);
const tokenBMintInfo = await getMint(agent.connection, tokenBMint);
const initPrice = DLMM.getPricePerLamport(
tokenAMintInfo.decimals,
tokenBMintInfo.decimals,
initialPrice,
);
const activateBinId = DLMM.getBinIdFromPrice(
initPrice,
binStep,
!priceRoundingUp,
);
const initPoolTx = await DLMM.createCustomizablePermissionlessLbPair(
agent.connection,
new BN(binStep),
tokenAMint,
tokenBMint,
new BN(activateBinId.toString()),
new BN(feeBps),
activationType,
hasAlphaVault,
agent.wallet_address,
activationPoint,
{
cluster: "mainnet-beta",
},
);
const initPoolTxHash = await sendTx(agent, initPoolTx.instructions, [
agent.wallet,
]);
return initPoolTxHash;
}

View File

@@ -0,0 +1,47 @@
import AmmImpl from "@mercurial-finance/dynamic-amm-sdk";
import { SolanaAgentKit } from "../../agent";
import BN from "bn.js";
import { PublicKey } from "@solana/web3.js";
import { CustomizableParams } from "@mercurial-finance/dynamic-amm-sdk/dist/cjs/src/amm/types";
import { sendTx } from "../../utils/send_tx";
/**
* Create Meteora Dynamic AMM pool
* @param agent SolanaAgentKit instance
* @param tokenAMint Token A mint
* @param tokenBMint Token B mint
* @param tokenAAmount Token A amount in lamport units
* @param tokenBAmount Token B amount in lamport units
* @param customizableParams Parameters to create Dynamic AMM pool
* tradeFeeNumerator (number): Trade fee numerator, with default denominator is 100000
* activationType (enum): Should be ActivationType.Timestamp or ActivationType.Slot
* activationPoint (BN | null): Activation point depending on activation type, or null if pool doesn't have an activation point
* hasAlphaVault (boolean): Whether the pool has Meteora alpha vault or not
* padding (Array<number>): Should be set to value Array(90).fill(0)
* @returns Transaction signature
*/
export async function createMeteoraDynamicAMMPool(
agent: SolanaAgentKit,
tokenAMint: PublicKey,
tokenBMint: PublicKey,
tokenAAmount: BN,
tokenBAmount: BN,
customizableParams: CustomizableParams,
): Promise<string> {
const initPoolTx =
await AmmImpl.createCustomizablePermissionlessConstantProductPool(
agent.connection,
agent.wallet_address,
tokenAMint,
tokenBMint,
tokenAAmount,
tokenBAmount,
customizableParams,
);
const initPoolTxHash = await sendTx(agent, initPoolTx.instructions, [
agent.wallet,
]);
return initPoolTxHash;
}

View File

@@ -0,0 +1,2 @@
export * from "./create_meteora_dlmm_pool";
export * from "./create_meteora_dynamic_amm_pool";

3
src/tools/voltr/index.ts Normal file
View File

@@ -0,0 +1,3 @@
export * from "./voltr_deposit_strategy";
export * from "./voltr_withdraw_strategy";
export * from "./voltr_get_position_values";

View File

@@ -0,0 +1,99 @@
import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token";
import { SolanaAgentKit } from "../../agent";
import {
PublicKey,
sendAndConfirmTransaction,
Transaction,
} from "@solana/web3.js";
import { VoltrClient } from "@voltr/vault-sdk";
import BN from "bn.js";
/**
* Deposits assets into a Voltr strategy
* @param agent SolanaAgentKit instance
* @param depositAmount Amount to deposit in base units (BN)
* @param vault Public key of the target vault
* @param strategy Public key of the target strategy
* @returns Transaction signature for the deposit
*/
export async function voltrDepositStrategy(
agent: SolanaAgentKit,
depositAmount: BN,
vault: PublicKey,
strategy: PublicKey,
): Promise<string> {
const vc = new VoltrClient(agent.connection, agent.wallet);
const vaultAccount = await vc.fetchVaultAccount(vault);
const vaultAssetMint = vaultAccount.asset.mint;
const assetTokenProgram = await agent.connection
.getAccountInfo(new PublicKey(vaultAssetMint))
.then((account) => account?.owner);
if (
!assetTokenProgram ||
!(
assetTokenProgram.equals(TOKEN_PROGRAM_ID) ||
assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID)
)
) {
throw new Error("Invalid asset token program");
}
const response = await fetch(
`https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
},
},
);
const data = (await response.json()).data as {
instructionDiscriminator: number[] | null;
additionalArgs: number[] | null;
remainingAccounts:
| {
pubkey: string;
isSigner: boolean;
isWritable: boolean;
}[]
| null;
};
const additionalArgs = data.additionalArgs
? Buffer.from(data.additionalArgs)
: null;
const instructionDiscriminator = data.instructionDiscriminator
? Buffer.from(data.instructionDiscriminator)
: null;
const remainingAccounts =
data.remainingAccounts?.map((account) => ({
pubkey: new PublicKey(account.pubkey),
isSigner: account.isSigner,
isWritable: account.isWritable,
})) ?? [];
const depositIx = await vc.createDepositStrategyIx(
{
depositAmount,
additionalArgs,
instructionDiscriminator,
},
{
vault,
vaultAssetMint,
strategy: strategy,
assetTokenProgram,
remainingAccounts,
},
);
const transaction = new Transaction();
transaction.add(depositIx);
const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [
agent.wallet,
]);
return txSig;
}

Some files were not shown because too many files have changed in this diff Show More