Merge branch 'main' into feat/squads_multisig

This commit is contained in:
A91y
2025-01-08 22:58:50 +05:30
65 changed files with 10161 additions and 320 deletions

View File

@@ -2,4 +2,5 @@ OPENAI_API_KEY=
RPC_URL=
SOLANA_PRIVATE_KEY=
JUPITER_REFERRAL_ACCOUNT=
JUPITER_FEE_BPS=
JUPITER_FEE_BPS=
FLASH_PRIVILEGE= referral | nft | none

View File

@@ -1 +1 @@
pnpm run docs && git add docs/ && tsc && lint-staged
tsc && lint-staged

View File

@@ -1,6 +1,5 @@
{
"**/*.+(js|jsx|css|less|scss|ts|tsx|md)": [
"prettier --write",
"eslint --fix"
"**/*.+(ts|tsx)": [
"eslint . --ext .ts --fix"
]
}
}

View File

@@ -4,7 +4,6 @@
![Solana Agent Kit Cover 1 (3)](https://github.com/user-attachments/assets/cfa380f6-79d9-474d-9852-3e1976c6de70)
![NPM Downloads](https://img.shields.io/npm/dm/solana-agent-kit?style=for-the-badge)
![GitHub forks](https://img.shields.io/github/forks/sendaifun/solana-agent-kit?style=for-the-badge)
![GitHub License](https://img.shields.io/github/license/sendaifun/solana-agent-kit?style=for-the-badge)
@@ -23,7 +22,6 @@ An open-source toolkit for connecting AI agents to Solana protocols. Now, any ag
Anyone - whether an SF-based AI researcher or a crypto-native builder - can bring their AI agents trained with any model and seamlessly integrate with Solana.
[![Run on Repl.it](https://replit.com/badge/github/sendaifun/solana-agent-kit)](https://replit.com/@sendaifun/Solana-Agent-Kit)
> Replit template created by [Arpit Singh](https://github.com/The-x-35)
@@ -35,7 +33,10 @@ Anyone - whether an SF-based AI researcher or a crypto-native builder - can brin
- Balance checks
- Stake SOL
- Zk compressed Airdrop by Light Protocol and Helius
- **NFTs on 3.Land**
- Create your own collection
- NFT creation and automatic listing on 3.land
- List your NFT for sale in any SPL token
- **NFT Management via Metaplex**
- Collection deployment
- NFT minting
@@ -90,6 +91,9 @@ Anyone - whether an SF-based AI researcher or a crypto-native builder - can brin
- Price feed integration for market analysis
- Automated decision-making capabilities
## 📃 Documentation
You can view the full documentation of the kit at [docs.solanaagentkit.xyz](https://docs.solanaagentkit.xyz)
## 📦 Installation
```bash
@@ -127,6 +131,57 @@ const result = await agent.deployToken(
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 collectionOpts: CreateCollectionOptions = {
collectionName: "",
collectionSymbol: "",
collectionDescription: "",
mainImageUrl: ""
};
const result = await agent.create3LandCollection(
optionsWithBase58,
collectionOpts
);
```
### 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 collectionAccount = ""; //hash for the collection
const createItemOptions: CreateSingleOptions = {
itemName: "",
sellerFee: 500, //5%
itemAmount: 100, //total items to be created
itemSymbol: "",
itemDescription: "",
traits: [
{ trait_type: "", value: "" },
],
price: 0, //100000000 == 0.1 sol, can be set to 0 for a free mint
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
);
```
### Create NFT Collection
@@ -247,6 +302,13 @@ const signature = await agent.closePerpTradeLong({
});
```
### Close Empty Token Accounts
``` typescript
const { signature } = await agent.closeEmptyTokenAccounts();
```
## Examples
### LangGraph Multi-Agent System
@@ -287,7 +349,6 @@ Refer to [CONTRIBUTING.md](CONTRIBUTING.md) for detailed guidelines on how to co
<img src="https://contrib.rocks/image?repo=sendaifun/solana-agent-kit" />
</a>
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=sendaifun/solana-agent-kit&type=Date)](https://star-history.com/#sendaifun/solana-agent-kit&Date)
@@ -304,4 +365,4 @@ Solana Network : EKHTbXpsm6YDgJzMkFxNU1LNXeWcUW7Ezf8mjUNQQ4Pa
## Security
This toolkit handles private keys and transactions. Always ensure you're using it in a secure environment and never share your private keys.
This toolkit handles private keys and transactions. Always ensure you're using it in a secure environment and never share your private keys.

View File

@@ -1 +1 @@
window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzytWsqqurQUAmx4Kpg=="
window.hierarchyData = "eJyrVirKzy8pVrKKjtVRKkpNy0lNLsnMzwMKVNfWAgCbHgqm"

View File

@@ -1 +1 @@
window.navigationData = "eJyNlcFu2zAMQP9F52Bps7XdcsuSZU3XNUFr7DLswMp0LFiWDIneEgz79yFOUNuxTOfig/n4KEuU+fOvINyRmIoXq8HAbIuGvikSI1EApWIqpAbv0Y/b8Xcp5VqMRKZMLKbXk4//Rm+mmSRlTW1QhtAlINGPj6F28uTmtpP8ZQd5oZFxnAhO9RlIpmsXo9sAEbrwkjoUp5xbrbGqv8BC232OhoLWEHiZeF0cnn7AeqJ4pUnUtsdzCLHJDoGsC2cfY1z6EkmmG6ckPqMvrPHho+xinPSrev1jXVaVxwh89oz96j6YK/BQForQRTZDswCCoPgc4oSPpbYzKW1paIEESnt2O/pxrsh3ZahujKdlxNbopbkSp+vhIA/3ZSPOaTZlXiSleYTSyJRdZZAcUi9LU50Kd4MCHKvdU3phL4fRIXkFLxHj1WJFmPeaz7iLtMPCIVW1TfMUZRb01GFOcg8m1tj4ldC+QD8+vT7LvPp0d30zac6DebRaP73U2b/BKXjVh0FwDLUN75vJsrr9x8kVWasbPZGUproBftyB2sLbDx3hD3QS9Ww1oGxhjBR3KEvC87FZ61oAI0qUifstdZRRbJFa8zX4eR2oI/z1H/fI5D8="
window.navigationData = "eJyNlsFy0zAQQP/F5w6lKS3QW0gIBEqTaT1cOhy28ibWWJY80hqSYfh3FCdT27G89iUH7du3ykob5flvRLij6C56Mgo0TLeo6buk6CIqgFK/LhQ4h+6yHX+TUq48lEmdRHdXkw//Ll5NU0HS6NogNaHdgPCSY6idPLm57SR/3kFeKGQcJ4JTfQIS6comaNdAPj28pQ7FKWdGKazqz7FQZp/7bgStIXCceFUcPt2A9UTxSr2R2x7PIcQmWwQyNpx9jHHpC/RNXVsp8BFd4TcaPsouxkr9TUxnyjiMLSS4Bgt5uE9BclA9yjpS+EW+/DE2q1qFMbjsEfvb0AdzBb6VhfSC2GSo50AQFJ9DnPC+VGYqhCk1zZFAKsceXT/OFfnhDfUlfljEbI1emitxGuXeU2zEOc26zItNqe+h1CJldxkkh9SLUlenwk17gGO1e0pHzl0YHZJX8AIxWc6XhHmv+YwbpR0WDqmqNs1SFFnQU4c5yVfQicLGzx7tC598Wj7LfPvx/dXNpPl2zeLl6uGpzv4NVsKLOjxax1DbcN1MFtX0H1/Z2BjVuBP+dlUT4C47UFt4+64j/IlWoJouB5QtjJHiDkVJeP7E17oWwIg2fqnfUkcZxRap9V8g+PU6UEf46z+zhSAU"

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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/utils/actionExecutor.ts#L20">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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/utils/actionExecutor.ts#L20">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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/utils/actionExecutor.ts#L8">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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/utils/actionExecutor.ts#L8">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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/utils/actionExecutor.ts#L58">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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/utils/actionExecutor.ts#L58">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>

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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L125">types/index.ts:125</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L126">types/index.ts:126</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L139">types/index.ts:139</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L140">types/index.ts:140</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L145">types/index.ts:145</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L155">types/index.ts:155</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L129">types/index.ts:129</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L150">types/index.ts:150</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/A91y/solana-agent-kit/blob/6e0b575324bb648f63caa3aed66872cac8cf1788/src/types/index.ts#L134">types/index.ts:134</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L146">types/index.ts:146</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L156">types/index.ts:156</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L130">types/index.ts:130</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L151">types/index.ts:151</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/UjjwalGupta49/solana-agent-kit/blob/f77cada52ac7e1627f9218cc72a2789f712a4532/src/types/index.ts#L135">types/index.ts:135</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

View File

@@ -3,7 +3,7 @@ import { SolanaAgentKit, createSolanaTools } from "solana-agent-kit";
export const agentKit = new SolanaAgentKit(
process.env.SOLANA_PRIVATE_KEY!,
process.env.RPC_URL!,
process.env.OPENAI_API_KEY!,
{ OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
);
export const solanaTools = createSolanaTools(agentKit);

View File

@@ -0,0 +1,3 @@
OPENAI_API_KEY=
RPC_URL=
SOLANA_PRIVATE_KEY=

View File

@@ -0,0 +1,50 @@
# AI Guided Market Making Agent
This agent showcases an ai guided market maker on Manifest, Solana's CLOB DEX. The agent guides the user to setup basic two-sided quotes on Manifest markets.
[Reference](https://github.com/CKS-Systems/manifest)
## Key Features
- **Automated Quoting**: The agent automatically refreshes quotes on an interval.
- **Reducing Complexity**: Designed to abstract away parameters for setting up market making.
- **Random Model**: The market making introduces randomness to prevent front running or other negative botting behavoirs.
## Example
=== Market Maker Configuration ===
Enter the market ID: 2Uj8277fkaVBtTU6Wp2GPRbQC86SkSdgQ2mp1Q5N2LHc
Enter the base token symbol (e.g., SEND): SEND
Enter the quote token symbol (e.g., USDC): USDC
=== Quote Parameters (applies to both buy and sell sides) ===
Enter number of quotes to place on each side: 4
Enter minimum quote depth (% distance from mid price): 0.1
Enter maximum quote depth (% distance from mid price): 2
=== Token Allowances ===
Enter total SEND allowance: 2
Enter total USDC allowance: 3
Enter update interval in seconds: 20
=== Configuration Summary ===
{
"marketId": "2Uj8277fkaVBtTU6Wp2GPRbQC86SkSdgQ2mp1Q5N2LHc",
"baseToken": "SEND",
"quoteToken": "USDC",
"quoteParams": {
"number": 4,
"minDepth": 0.1,
"maxDepth": 2
},
"allowance": {
"base": 2,
"quote": 3
},
"intervalSeconds": 20
}
Is this configuration correct? (yes/no): yes
Starting market maker mode for SEND/USDC...

View File

@@ -0,0 +1,389 @@
import { HumanMessage } from "@langchain/core/messages";
import { MemorySaver } from "@langchain/langgraph";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { ChatOpenAI } from "@langchain/openai";
import * as dotenv from "dotenv";
import * as fs from "fs";
import * as readline from "readline";
import { createSolanaTools, SolanaAgentKit } from "../../src";
dotenv.config();
function validateEnvironment(): void {
const missingVars: string[] = [];
const requiredVars = ["OPENAI_API_KEY", "RPC_URL", "SOLANA_PRIVATE_KEY"];
requiredVars.forEach((varName) => {
if (!process.env[varName]) {
missingVars.push(varName);
}
});
if (missingVars.length > 0) {
console.error("Error: Required environment variables are not set");
missingVars.forEach((varName) => {
console.error(`${varName}=your_${varName.toLowerCase()}_here`);
});
process.exit(1);
}
}
validateEnvironment();
const WALLET_DATA_FILE = "wallet_data.txt";
async function initializeAgent() {
try {
const llm = new ChatOpenAI({
modelName: "gpt-4o-mini",
temperature: 0.3,
});
let walletDataStr: string | null = null;
if (fs.existsSync(WALLET_DATA_FILE)) {
try {
walletDataStr = fs.readFileSync(WALLET_DATA_FILE, "utf8");
} catch (error) {
console.error("Error reading wallet data:", error);
}
}
const solanaAgent = new SolanaAgentKit(
process.env.SOLANA_PRIVATE_KEY!,
process.env.RPC_URL!,
{
OPENAI_API_KEY: process.env.OPENAI_API_KEY!,
},
);
const tools = createSolanaTools(solanaAgent);
const memory = new MemorySaver();
const config = { configurable: { thread_id: "Solana Agent Kit!" } };
const agent = createReactAgent({
llm,
tools,
checkpointSaver: memory,
messageModifier: `
You are a helpful agent that can interact onchain using the Solana Agent Kit. You are
empowered to interact onchain using your tools. If you ever need funds, you can request them from the
faucet. If not, you can provide your wallet details and request funds from the user. If there is a 5XX
(internal) HTTP error code, ask the user to try again later. If someone asks you to do something you
can't do with your currently available tools, you must say so, and encourage them to implement it
themselves using the Solana Agent Kit, recommend they go to https://www.solanaagentkit.xyz for more information. Be
concise and helpful with your responses. Refrain from restating your tools' descriptions unless it is explicitly requested.
`,
});
if (walletDataStr) {
fs.writeFileSync(WALLET_DATA_FILE, walletDataStr);
}
return { agent, config };
} catch (error) {
console.error("Failed to initialize agent:", error);
throw error;
}
}
async function runAutonomousMode(agent: any, config: any, interval = 10) {
console.log("Starting autonomous mode...");
while (true) {
try {
const thought =
"Be creative and do something interesting on the blockchain. " +
"Choose an action or set of actions and execute it that highlights your abilities.";
const stream = await agent.stream(
{ messages: [new HumanMessage(thought)] },
config,
);
for await (const chunk of stream) {
if ("agent" in chunk) {
console.log(chunk.agent.messages[0].content);
} else if ("tools" in chunk) {
console.log(chunk.tools.messages[0].content);
}
console.log("-------------------");
}
await new Promise((resolve) => setTimeout(resolve, interval * 1000));
} catch (error) {
if (error instanceof Error) {
console.error("Error:", error.message);
}
process.exit(1);
}
}
}
async function runChatMode(agent: any, config: any) {
console.log("Starting chat mode... Type 'exit' to end.");
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const question = (prompt: string): Promise<string> =>
new Promise((resolve) => rl.question(prompt, resolve));
try {
while (true) {
const userInput = await question("\nPrompt: ");
if (userInput.toLowerCase() === "exit") {
break;
}
const stream = await agent.stream(
{ messages: [new HumanMessage(userInput)] },
config,
);
for await (const chunk of stream) {
if ("agent" in chunk) {
console.log(chunk.agent.messages[0].content);
} else if ("tools" in chunk) {
console.log(chunk.tools.messages[0].content);
}
console.log("-------------------");
}
}
} catch (error) {
if (error instanceof Error) {
console.error("Error:", error.message);
}
process.exit(1);
} finally {
rl.close();
}
}
interface MarketMakerConfig {
marketId: string;
baseToken: string;
quoteToken: string;
quoteParams: {
number: number; // Number of quotes on each side
minDepth: number; // Minimum distance from mid (%)
maxDepth: number; // Maximum distance from mid (%)
};
allowance: {
base: number;
quote: number;
};
intervalSeconds: number;
}
function createReadlineInterface() {
return readline.createInterface({
input: process.stdin,
output: process.stdout,
});
}
async function askQuestion(
rl: readline.Interface,
question: string,
): Promise<string> {
return new Promise((resolve) => {
rl.question(question, (answer) => {
resolve(answer);
});
});
}
async function configureMarketMaker(): Promise<MarketMakerConfig> {
const rl = createReadlineInterface();
try {
console.log("\n=== Market Maker Configuration ===\n");
// Basic market information
const marketId = await askQuestion(rl, "Enter the market ID: ");
const baseToken = await askQuestion(
rl,
"Enter the base token symbol (e.g., SEND): ",
);
const quoteToken = await askQuestion(
rl,
"Enter the quote token symbol (e.g., USDC): ",
);
// Quote parameters
console.log(
"\n=== Quote Parameters (applies to both buy and sell sides) ===",
);
const quoteNumber = parseInt(
await askQuestion(rl, "Enter number of quotes to place on each side: "),
);
const minDepth = parseFloat(
await askQuestion(
rl,
"Enter minimum quote depth (% distance from mid price): ",
),
);
const maxDepth = parseFloat(
await askQuestion(
rl,
"Enter maximum quote depth (% distance from mid price): ",
),
);
// Token allowances
console.log("\n=== Token Allowances ===");
const baseAllowance = parseFloat(
await askQuestion(rl, `Enter total ${baseToken} allowance: `),
);
const quoteAllowance = parseFloat(
await askQuestion(rl, `Enter total ${quoteToken} allowance: `),
);
// Update interval
const interval = parseInt(
await askQuestion(rl, "\nEnter update interval in seconds: "),
);
const config: MarketMakerConfig = {
marketId,
baseToken,
quoteToken,
quoteParams: {
number: quoteNumber,
minDepth: minDepth,
maxDepth: maxDepth,
},
allowance: {
base: baseAllowance,
quote: quoteAllowance,
},
intervalSeconds: interval,
};
// Display summary
console.log("\n=== Configuration Summary ===");
console.log(JSON.stringify(config, null, 2));
const confirm = await askQuestion(
rl,
"\nIs this configuration correct? (yes/no): ",
);
if (confirm.toLowerCase() !== "yes") {
throw new Error("Configuration cancelled by user");
}
return config;
} finally {
rl.close();
}
}
async function runMarketMakerMode(agent: any, config: any) {
try {
const marketMakerConfig = await configureMarketMaker();
console.log(
`\nStarting market maker mode for ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken}...`,
);
while (true) {
try {
const thought = `You are an on-chain Solana market maker for the ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken} Manifest market, ${marketMakerConfig.marketId}.
Find the ${marketMakerConfig.baseToken}/${marketMakerConfig.quoteToken} live price by checking Jupiter.
Use solana_batch_order to provide ${marketMakerConfig.quoteParams.number} buys at different prices between -${marketMakerConfig.quoteParams.minDepth}% to -${marketMakerConfig.quoteParams.maxDepth}% and ${marketMakerConfig.quoteParams.number} sells at different prices between +${marketMakerConfig.quoteParams.minDepth}% to +${marketMakerConfig.quoteParams.maxDepth}% with increasing quantities further from the live price.
You have an allowance of ${marketMakerConfig.allowance.base} ${marketMakerConfig.baseToken} and ${marketMakerConfig.allowance.quote} ${marketMakerConfig.quoteToken}.
Important! Only send 1 transaction, buy and sells can be combined into a single solana_batch_order.`;
const stream = await agent.stream(
{ messages: [new HumanMessage(thought)] },
config,
);
for await (const chunk of stream) {
if ("agent" in chunk) {
console.log(chunk.agent.messages[0].content);
} else if ("tools" in chunk) {
console.log(chunk.tools.messages[0].content);
}
console.log("-------------------");
}
await new Promise((resolve) =>
setTimeout(resolve, marketMakerConfig.intervalSeconds * 1000),
);
} catch (error) {
if (error instanceof Error) {
console.error("Error:", error);
}
process.exit(1);
}
}
} catch (error) {
console.error("Configuration error:", error);
process.exit(1);
}
}
async function chooseMode(): Promise<"chat" | "auto" | "mm"> {
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
const question = (prompt: string): Promise<string> =>
new Promise((resolve) => rl.question(prompt, resolve));
while (true) {
console.log("\nAvailable modes:");
console.log("1. chat - Interactive chat mode");
console.log("2. auto - Autonomous action mode");
console.log("3. mm - AI guided market making");
const choice = (await question("\nChoose a mode (enter number or name): "))
.toLowerCase()
.trim();
rl.close();
if (choice === "1" || choice === "chat") {
return "chat";
} else if (choice === "2" || choice === "auto") {
return "auto";
} else if (choice === "3" || choice === "mm") {
return "mm";
}
console.log("Invalid choice. Please try again.");
}
}
async function main() {
try {
console.log("Starting Agent...");
const { agent, config } = await initializeAgent();
const mode = await chooseMode();
if (mode === "chat") {
await runChatMode(agent, config);
} else if (mode === "auto") {
await runAutonomousMode(agent, config);
} else {
await runMarketMakerMode(agent, config);
}
} catch (error) {
if (error instanceof Error) {
console.error("Error:", error.message);
}
process.exit(1);
}
}
if (require.main === module) {
main().catch((error) => {
console.error("Fatal error:", error);
process.exit(1);
});
}

View File

@@ -0,0 +1,16 @@
{
"name": "market-making-agent",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"main": "ts-node index.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@langchain/langgraph-checkpoint-postgres": "^0.0.2",
"solana-agent-kit": "^1.3.6"
}
}

6000
examples/market-making-agent/pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -23,6 +23,7 @@
"author": "sendaifun",
"license": "Apache-2.0",
"dependencies": {
"@3land/listings-sdk": "^0.0.4",
"@ai-sdk/openai": "^1.0.11",
"@bonfida/spl-name-service": "^3.0.7",
"@cks-systems/manifest-sdk": "0.1.59",
@@ -42,6 +43,7 @@
"@onsol/tldparser": "^0.6.7",
"@orca-so/common-sdk": "0.6.4",
"@orca-so/whirlpools-sdk": "^0.13.12",
"@pythnetwork/hermes-client": "^1.3.0",
"@raydium-io/raydium-sdk-v2": "0.1.95-alpha",
"@solana/spl-token": "^0.4.9",
"@solana/web3.js": "^1.98.0",
@@ -54,6 +56,7 @@
"chai": "^5.1.2",
"decimal.js": "^10.4.3",
"dotenv": "^16.4.7",
"flash-sdk": "^2.24.3",
"form-data": "^4.0.1",
"langchain": "^0.3.8",
"openai": "^4.77.0",

1933
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
import { Action } from "../types/action";
import { SolanaAgentKit } from "../agent";
import { z } from "zod";
import { closeEmptyTokenAccounts } from "../tools";
const closeEmptyTokenAccountsAction: Action = {
name: "CLOSE_EMPTY_TOKEN_ACCOUNTS",
similes: [
"close token accounts",
"remove empty accounts",
"clean up token accounts",
"close SPL token accounts",
"clean wallet",
],
description: `Close empty SPL Token accounts associated with your wallet to reclaim rent.
This action will close both regular SPL Token accounts and Token-2022 accounts that have zero balance. `,
examples: [
[
{
input: {},
output: {
status: "success",
signature:
"3KmPyiZvJQk8CfBVVaz8nf3c2crb6iqjQVDqNxknnusyb1FTFpXqD8zVSCBAd1X3rUcD8WiG1bdSjFbeHsmcYGXY",
accountsClosed: 10,
},
explanation: "Closed 10 empty token accounts successfully.",
},
],
[
{
input: {},
output: {
status: "success",
signature: "",
accountsClosed: 0,
},
explanation: "No empty token accounts were found to close.",
},
],
],
schema: z.object({}),
handler: async (agent: SolanaAgentKit) => {
try {
const result = await closeEmptyTokenAccounts(agent);
if (result.size === 0) {
return {
status: "success",
signature: "",
accountsClosed: 0,
message: "No empty token accounts found to close",
};
}
return {
status: "success",
signature: result.signature,
accountsClosed: result.size,
message: `Successfully closed ${result.size} empty token accounts`,
};
} catch (error: any) {
return {
status: "error",
message: `Failed to close empty token accounts: ${error.message}`,
};
}
},
};
export default closeEmptyTokenAccountsAction;

View File

@@ -0,0 +1,68 @@
import { Action } from "../types/action";
import { SolanaAgentKit } from "../agent";
import { z } from "zod";
import { flashCloseTrade } from "../tools";
const flashCloseTradeAction: Action = {
name: "FLASH_CLOSE_TRADE",
similes: [
"close trade",
"close leveraged trade",
"exit position",
"close position",
"exit trade",
"close long",
"close short",
"take profit",
"stop loss",
],
description:
"Close an existing leveraged trading position on Flash.Trade protocol",
examples: [
[
{
input: {
token: "SOL",
side: "long",
},
output: {
status: "success",
signature: "4xKpN2...",
message: "Successfully closed long position on SOL",
},
explanation: "Close an existing long position on SOL",
},
],
],
schema: z.object({
token: z
.string()
.describe("Token symbol of the position to close (e.g. SOL, ETH)"),
side: z
.enum(["long", "short"])
.describe("Position side to close - long or short"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const params = {
token: input.token as string,
side: input.side as "long" | "short",
};
const response = await flashCloseTrade(agent, params);
return {
status: "success",
signature: response,
message: `Successfully closed ${params.side} position on ${params.token}`,
};
} catch (error: any) {
return {
status: "error",
message: `Flash trade close failed: ${error.message}`,
};
}
},
};
export default flashCloseTradeAction;

View File

@@ -0,0 +1,78 @@
import { Action } from "../types/action";
import { SolanaAgentKit } from "../agent";
import { z } from "zod";
import { flashOpenTrade } from "../tools";
const flashOpenTradeAction: Action = {
name: "FLASH_OPEN_TRADE",
similes: [
"open trade",
"open leveraged trade",
"start trading position",
"open position",
"long position",
"short position",
"leverage trade",
"margin trade",
],
description: "Open a leveraged trading position on Flash.Trade protocol",
examples: [
[
{
input: {
token: "SOL",
side: "long",
collateralUsd: 100,
leverage: 5,
},
output: {
status: "success",
signature: "4xKpN2...",
message:
"Successfully opened 5x long position on SOL with $100 collateral",
},
explanation:
"Open a 5x leveraged long position on SOL using $100 as collateral",
},
],
],
schema: z.object({
token: z.string().describe("Token symbol to trade (e.g. SOL, ETH)"),
side: z
.enum(["long", "short"])
.describe("Trading direction - long or short"),
collateralUsd: z
.number()
.positive()
.describe("Amount of collateral in USD"),
leverage: z
.number()
.positive()
.describe("Leverage multiplier for the trade"),
}),
handler: async (agent: SolanaAgentKit, input: Record<string, any>) => {
try {
const params = {
token: input.token as string,
side: input.side as "long" | "short",
collateralUsd: input.collateralUsd as number,
leverage: input.leverage as number,
};
const response = await flashOpenTrade(agent, params);
return {
status: "success",
signature: response,
message: `Successfully opened ${params.leverage}x ${params.side} position on ${params.token} with $${params.collateralUsd} collateral`,
};
} catch (error: any) {
return {
status: "error",
message: `Flash trade failed: ${error.message}`,
};
}
},
};
export default flashOpenTradeAction;

View File

@@ -28,6 +28,8 @@ import raydiumCreateAmmV4Action from "./raydiumCreateAmmV4";
import createOrcaSingleSidedWhirlpoolAction from "./createOrcaSingleSidedWhirlpool";
import launchPumpfunTokenAction from "./launchPumpfunToken";
import getWalletAddressAction from "./getWalletAddress";
import flashOpenTradeAction from "./flashOpenTrade";
import flashCloseTradeAction from "./flashCloseTrade";
export const ACTIONS = {
WALLET_ADDRESS_ACTION: getWalletAddressAction,
@@ -61,6 +63,8 @@ export const ACTIONS = {
CREATE_ORCA_SINGLE_SIDED_WHIRLPOOL_ACTION:
createOrcaSingleSidedWhirlpoolAction,
LAUNCH_PUMPFUN_TOKEN_ACTION: launchPumpfunTokenAction,
FLASH_OPEN_TRADE_ACTION: flashOpenTradeAction,
FLASH_CLOSE_TRADE_ACTION: flashCloseTradeAction,
};
export type { Action, ActionExample, Handler } from "../types/action";

View File

@@ -56,10 +56,13 @@ import {
create_TipLink,
listNFTForSale,
cancelListing,
closeEmptyTokenAccounts,
fetchTokenReportSummary,
fetchTokenDetailedReport,
fetchPythPrice,
fetchPythPriceFeedID,
flashOpenTrade,
flashCloseTrade,
} from "../tools";
import {
CollectionDeployment,
@@ -70,7 +73,18 @@ import {
PumpfunLaunchResponse,
PumpFunTokenOptions,
OrderParams,
FlashTradeParams,
FlashCloseTradeParams,
} from "../types";
import {
createCollection,
createSingle,
} from "../tools/create_3land_collectible";
import {
CreateCollectionOptions,
CreateSingleOptions,
StoreInitOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
import { create_squads_multisig } from "../tools/squads_multisig/create_multisig";
import { deposit_to_multisig } from "../tools/squads_multisig/deposit_to_multisig";
import { transfer_from_multisig } from "../tools/squads_multisig/transfer_from_multisig";
@@ -541,6 +555,13 @@ export class SolanaAgentKit {
return cancelListing(this, nftMint);
}
async closeEmptyTokenAccounts(): Promise<{
signature: string;
size: number;
}> {
return closeEmptyTokenAccounts(this);
}
async fetchTokenReportSummary(mint: string): Promise<TokenCheck> {
return fetchTokenReportSummary(mint);
}
@@ -549,6 +570,47 @@ export class SolanaAgentKit {
return fetchTokenDetailedReport(mint);
}
/**
* Opens a new trading position on Flash.Trade
* @param params Flash trade parameters including market, side, collateral, leverage, and pool name
* @returns Transaction signature
*/
async flashOpenTrade(params: FlashTradeParams): Promise<string> {
return flashOpenTrade(this, params);
}
/**
* Closes an existing trading position on Flash.Trade
* @param params Flash trade close parameters
* @returns Transaction signature
*/
async flashCloseTrade(params: FlashCloseTradeParams): Promise<string> {
return flashCloseTrade(this, params);
}
async create3LandCollection(
optionsWithBase58: StoreInitOptions,
collectionOpts: CreateCollectionOptions,
): Promise<string> {
const tx = await createCollection(optionsWithBase58, collectionOpts);
return `Transaction: ${tx}`;
}
async create3LandNft(
optionsWithBase58: StoreInitOptions,
collectionAccount: string,
createItemOptions: CreateSingleOptions,
isMainnet: boolean,
): Promise<string> {
const tx = await createSingle(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet,
);
return `Transaction: ${tx}`;
}
async createSquadsMultisig(creator: PublicKey): Promise<string> {
return create_squads_multisig(this, creator);
}

View File

@@ -9,6 +9,12 @@ import {
SolanaAgentKit,
} from "../index";
import { create_image, FEE_TIERS, generateOrdersfromPattern } from "../tools";
import { marketTokenMap } from "../utils/flashUtils";
import {
CreateCollectionOptions,
CreateSingleOptions,
StoreInitOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
export class SolanaBalanceTool extends Tool {
name = "solana_balance";
@@ -774,6 +780,135 @@ export class SolanaGetWalletAddressTool extends Tool {
}
}
export class SolanaFlashOpenTrade extends Tool {
name = "solana_flash_open_trade";
description = `This tool can be used to open a new leveraged trading position on Flash.Trade exchange.
Inputs ( input is a JSON string ):
token: string, eg "SOL", "BTC", "ETH" (required)
type: string, eg "long", "short" (required)
collateral: number, eg 10, 100, 1000 (required)
leverage: number, eg 5, 10, 20 (required)
Example prompt is Open a 20x leveraged trade for SOL on long side using flash trade with 500 USD as collateral`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
// Validate input parameters
if (!parsedInput.token) {
throw new Error("Token is required, received: " + parsedInput.token);
}
if (!Object.keys(marketTokenMap).includes(parsedInput.token)) {
throw new Error(
"Token must be one of " +
Object.keys(marketTokenMap).join(", ") +
", received: " +
parsedInput.token +
"\n" +
"Please check https://beast.flash.trade/ for the list of supported tokens",
);
}
if (!["long", "short"].includes(parsedInput.type)) {
throw new Error(
'Type must be either "long" or "short", received: ' +
parsedInput.type,
);
}
if (!parsedInput.collateral || parsedInput.collateral <= 0) {
throw new Error(
"Collateral amount must be positive, received: " +
parsedInput.collateral,
);
}
if (!parsedInput.leverage || parsedInput.leverage <= 0) {
throw new Error(
"Leverage must be positive, received: " + parsedInput.leverage,
);
}
const tx = await this.solanaKit.flashOpenTrade({
token: parsedInput.token,
side: parsedInput.type,
collateralUsd: parsedInput.collateral,
leverage: parsedInput.leverage,
});
return JSON.stringify({
status: "success",
message: "Flash trade position opened successfully",
transaction: tx,
token: parsedInput.token,
side: parsedInput.type,
collateral: parsedInput.collateral,
leverage: parsedInput.leverage,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
export class SolanaFlashCloseTrade extends Tool {
name = "solana_flash_close_trade";
description = `Close an existing leveraged trading position on Flash.Trade exchange.
Inputs ( input is a JSON string ):
token: string, eg "SOL", "BTC", "ETH" (required)
side: string, eg "long", "short" (required)
Example prompt is Close a 20x leveraged trade for SOL on long side`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(input: string): Promise<string> {
try {
const parsedInput = JSON.parse(input);
// Validate input parameters
if (!parsedInput.token) {
throw new Error("Token is required");
}
if (!["SOL", "BTC", "ETH"].includes(parsedInput.token)) {
throw new Error('Token must be one of ["SOL", "BTC", "ETH"]');
}
if (!["long", "short"].includes(parsedInput.side)) {
throw new Error('Side must be either "long" or "short"');
}
const tx = await this.solanaKit.flashCloseTrade({
token: parsedInput.token,
side: parsedInput.side,
});
return JSON.stringify({
status: "success",
message: "Flash trade position closed successfully",
transaction: tx,
token: parsedInput.token,
side: parsedInput.side,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
export class SolanaPumpfunTokenLaunchTool extends Tool {
name = "solana_launch_pumpfun_token";
@@ -2125,6 +2260,181 @@ export class SolanaFetchTokenDetailedReportTool extends Tool {
}
}
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
itemAmount (required): the amount of the NFTs that can be minted
itemDescription (required): the description of the NFT
traits (required): the traits of the NFT [{trait_type: string, value: string}]
price (required): the price of the item, if is 0 the listing will be free
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
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
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 collectionAccount = inputFormat.collectionAccount;
const itemName = inputFormat?.itemName;
const sellerFee = inputFormat?.sellerFee;
const itemAmount = inputFormat?.itemAmount;
const itemSymbol = inputFormat?.itemSymbol;
const itemDescription = inputFormat?.itemDescription;
const traits = inputFormat?.traits;
const price = inputFormat?.price;
const mainImageUrl = inputFormat?.mainImageUrl;
const coverImageUrl = inputFormat?.coverImageUrl;
const splHash = inputFormat?.splHash;
const createItemOptions: CreateSingleOptions = {
...(itemName && { itemName }),
...(sellerFee && { sellerFee }),
...(itemAmount && { itemAmount }),
...(itemSymbol && { itemSymbol }),
...(itemDescription && { itemDescription }),
...(traits && { traits }),
...(price && { price }),
...(mainImageUrl && { mainImageUrl }),
...(coverImageUrl && { coverImageUrl }),
...(splHash && { splHash }),
};
if (!collectionAccount) {
throw new Error("Collection account is required");
}
const tx = await this.solanaKit.create3LandNft(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet,
);
return JSON.stringify({
status: "success",
message: `Created listing successfully ${tx}`,
transaction: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
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
collectionDescription (required): the description of the collection
mainImageUrl (required): the image of the collection
coverImageUrl (optional): the cover image of the collection
`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
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;
const mainImageUrl = inputFormat?.mainImageUrl;
const coverImageUrl = inputFormat?.coverImageUrl;
const collectionOpts: CreateCollectionOptions = {
...(collectionSymbol && { collectionSymbol }),
...(collectionName && { collectionName }),
...(collectionDescription && { collectionDescription }),
...(mainImageUrl && { mainImageUrl }),
...(coverImageUrl && { coverImageUrl }),
};
const tx = await this.solanaKit.create3LandCollection(
optionsWithBase58,
collectionOpts,
);
return JSON.stringify({
status: "success",
message: `Created Collection successfully ${tx}`,
transaction: tx,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
export class SolanaCloseEmptyTokenAccounts extends Tool {
name = "close_empty_token_accounts";
description = `Close all empty spl-token accounts and reclaim the rent`;
constructor(private solanaKit: SolanaAgentKit) {
super();
}
protected async _call(): Promise<string> {
try {
const { signature, size } =
await this.solanaKit.closeEmptyTokenAccounts();
return JSON.stringify({
status: "success",
message: `${size} accounts closed successfully. ${size === 48 ? "48 accounts can be closed in a single transaction try again to close more accounts" : ""}`,
signature,
});
} catch (error: any) {
return JSON.stringify({
status: "error",
message: error.message,
code: error.code || "UNKNOWN_ERROR",
});
}
}
}
export class SolanaCreate2by2Multisig extends Tool {
name = "create_2by2_multisig";
description = `Create a 2-of-2 multisig account on Solana with the user and the agent, where both approvals will be required to run the transactions.
@@ -2428,10 +2738,16 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) {
new SolanaTipLinkTool(solanaKit),
new SolanaListNFTForSaleTool(solanaKit),
new SolanaCancelNFTListingTool(solanaKit),
new SolanaCloseEmptyTokenAccounts(solanaKit),
new SolanaFetchTokenReportSummaryTool(solanaKit),
new SolanaFetchTokenDetailedReportTool(solanaKit),
new Solana3LandCreateSingle(solanaKit),
new Solana3LandCreateCollection(solanaKit),
new SolanaPerpOpenTradeTool(solanaKit),
new SolanaPerpCloseTradeTool(solanaKit),
new SolanaFlashOpenTrade(solanaKit),
new SolanaFlashCloseTrade(solanaKit),
new Solana3LandCreateSingle(solanaKit),
new SolanaCreate2by2Multisig(solanaKit),
new SolanaDepositTo2by2Multisig(solanaKit),
new SolanaTransferFrom2by2Multisig(solanaKit),

View File

@@ -1,37 +0,0 @@
import {
PublicKey,
sendAndConfirmTransaction,
Transaction,
} from "@solana/web3.js";
import { SolanaAgentKit } from "../index";
import { ManifestClient } from "@cks-systems/manifest-sdk";
/**
* Cancels all orders from Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @returns Transaction signature
*/
export async function cancelAllOrders(
agent: SolanaAgentKit,
marketId: PublicKey,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const cancelAllOrdersIx = await mfxClient.cancelAllIx();
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(cancelAllOrdersIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Cancel all orders failed: ${error.message}`);
}
}

View File

@@ -0,0 +1,103 @@
import {
PublicKey,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
import { SolanaAgentKit } from "../agent";
import {
AccountLayout,
createCloseAccountInstruction,
TOKEN_2022_PROGRAM_ID,
TOKEN_PROGRAM_ID,
} from "@solana/spl-token";
/**
* Close Empty SPL Token accounts of the agent
* @param agent SolanaAgentKit instance
* @returns transaction signature and total number of accounts closed
*/
export async function closeEmptyTokenAccounts(
agent: SolanaAgentKit,
): Promise<{ signature: string; size: number }> {
try {
const spl_token = await create_close_instruction(agent, TOKEN_PROGRAM_ID);
const token_2022 = await create_close_instruction(
agent,
TOKEN_2022_PROGRAM_ID,
);
const transaction = new Transaction();
const MAX_INSTRUCTIONS = 40; // 40 instructions can be processed in a single transaction without failing
spl_token
.slice(0, Math.min(MAX_INSTRUCTIONS, spl_token.length))
.forEach((instruction) => transaction.add(instruction));
token_2022
.slice(0, Math.max(0, MAX_INSTRUCTIONS - spl_token.length))
.forEach((instruction) => transaction.add(instruction));
const size = spl_token.length + token_2022.length;
if (size === 0) {
return {
signature: "",
size: 0,
};
}
const signature = await agent.connection.sendTransaction(transaction, [
agent.wallet,
]);
return { signature, size };
} catch (error) {
throw new Error(`Error closing empty token accounts: ${error}`);
}
}
/**
* creates the close instuctions of a spl token account
* @param agnet SolanaAgentKit instance
* @param token_program Token Program Id
* @returns close instuction array
*/
async function create_close_instruction(
agent: SolanaAgentKit,
token_program: PublicKey,
): Promise<TransactionInstruction[]> {
const instructions = [];
const ata_accounts = await agent.connection.getTokenAccountsByOwner(
agent.wallet_address,
{ programId: token_program },
"confirmed",
);
const tokens = ata_accounts.value;
const accountExceptions = [
"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", // USDC
];
for (let i = 0; i < tokens.length; i++) {
const token_data = AccountLayout.decode(tokens[i].account.data);
if (
token_data.amount === BigInt(0) &&
!accountExceptions.includes(token_data.mint.toString())
) {
const closeInstruction = createCloseAccountInstruction(
ata_accounts.value[i].pubkey,
agent.wallet_address,
agent.wallet_address,
[],
token_program,
);
instructions.push(closeInstruction);
}
}
return instructions;
}

View File

@@ -0,0 +1,69 @@
import { createCollectionImp, createSingleImp } from "@3land/listings-sdk";
import {
StoreInitOptions,
CreateCollectionOptions,
CreateSingleOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
/**
* Create a collection on 3Land
* @param optionsWithBase58 represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
* @param collectionOpts represents the options for the collection creation
* @returns
*/
export async function createCollection(
optionsWithBase58: StoreInitOptions,
collectionOpts: CreateCollectionOptions,
) {
try {
const collection = await createCollectionImp(
optionsWithBase58,
collectionOpts,
);
return collection;
} catch (error: any) {
throw new Error(`Collection creation failed: ${error.message}`);
}
}
/**
* Create a single edition on 3Land
* @param optionsWithBase58 represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string
* @param collectionAccount represents the account for the nft collection
* @param createItemOptions the options for the creation of the single NFT listing
* @returns
*/
export async function createSingle(
optionsWithBase58: StoreInitOptions,
collectionAccount: string,
createItemOptions: CreateSingleOptions,
isMainnet: boolean,
) {
try {
const landStore = isMainnet
? "AmQNs2kgw4LvS9sm6yE9JJ4Hs3JpVu65eyx9pxMG2xA"
: "GyPCu89S63P9NcCQAtuSJesiefhhgpGWrNVJs4bF2cSK";
const singleEditionTx = await createSingleImp(
optionsWithBase58,
landStore,
collectionAccount,
createItemOptions,
);
return singleEditionTx;
} catch (error: any) {
throw new Error(`Single edition creation failed: ${error.message}`);
}
}
/**
* Buy a single edition on 3Land
* @param
* @returns
*/
// export async function buySingle() {
// try {
// } catch (error: any) {
// throw new Error(`Buying single edition failed: ${error.message}`);
// }
// }

View File

@@ -0,0 +1,118 @@
import { ComputeBudgetProgram } from "@solana/web3.js";
import { PoolConfig, Side } from "flash-sdk";
import { BN } from "@coral-xyz/anchor";
import { SolanaAgentKit } from "../index";
import {
CLOSE_POSITION_CU,
marketSdkInfo,
marketTokenMap,
getNftTradingAccountInfo,
fetchOraclePrice,
createPerpClient,
get_flash_privilege,
} from "../utils/flashUtils";
import { FlashCloseTradeParams } from "../types";
/**
* Closes an existing position on Flash.Trade
* @param agent SolanaAgentKit instance
* @param params Trade parameters
* @returns Transaction signature
*/
export async function flashCloseTrade(
agent: SolanaAgentKit,
params: FlashCloseTradeParams,
): Promise<string> {
try {
const { token, side } = params;
// Get market ID from token and side using marketTokenMap
const tokenMarkets = marketTokenMap[token];
if (!tokenMarkets) {
throw new Error(`Token ${token} not supported for trading`);
}
const sideEntry = tokenMarkets[side];
if (!sideEntry) {
throw new Error(`${side} side not available for ${token}`);
}
const market = sideEntry.marketID;
// Validate market data using marketSdkInfo
const marketData = marketSdkInfo[market];
if (!marketData) {
throw new Error(`Invalid market configuration for ${token}/${side}`);
}
// Get token information
const [targetSymbol, collateralSymbol] = marketData.tokenPair.split("/");
// Fetch oracle prices
const [targetPrice] = await Promise.all([
fetchOraclePrice(targetSymbol),
fetchOraclePrice(collateralSymbol),
]);
// Initialize pool configuration and perpClient
const poolConfig = PoolConfig.fromIdsByName(
marketData.pool,
"mainnet-beta",
);
const perpClient = createPerpClient(agent.connection, agent.wallet);
// Calculate price after slippage
const slippageBpsBN = new BN(100); // 1% slippage
const sideEnum = side === "long" ? Side.Long : Side.Short;
const priceWithSlippage = perpClient.getPriceAfterSlippage(
false, // isEntry = false for closing position
slippageBpsBN,
targetPrice.price,
sideEnum,
);
// Get NFT trading account info
const tradingAccounts = await getNftTradingAccountInfo(
agent.wallet_address,
perpClient,
poolConfig,
collateralSymbol,
);
if (
!tradingAccounts.nftTradingAccountPk ||
!tradingAccounts.nftReferralAccountPK ||
!tradingAccounts.nftOwnerRebateTokenAccountPk
) {
throw new Error("Required NFT trading accounts not found");
}
// Build and send transaction
const { instructions, additionalSigners } = await perpClient.closePosition(
targetSymbol,
collateralSymbol,
priceWithSlippage,
sideEnum,
poolConfig,
get_flash_privilege(agent),
tradingAccounts.nftTradingAccountPk,
tradingAccounts.nftReferralAccountPK,
tradingAccounts.nftOwnerRebateTokenAccountPk,
);
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({
units: CLOSE_POSITION_CU,
});
return await perpClient.sendTransaction(
[computeBudgetIx, ...instructions],
{
additionalSigners: additionalSigners,
alts: perpClient.addressLookupTables,
prioritizationFee: 5000000,
},
);
} catch (error) {
throw new Error(`Flash trade close failed: ${error}`);
}
}

View File

@@ -0,0 +1,251 @@
import { ComputeBudgetProgram } from "@solana/web3.js";
import {
PerpetualsClient,
OraclePrice,
PoolConfig,
Side,
CustodyAccount,
Custody,
} from "flash-sdk";
import { BN } from "@coral-xyz/anchor";
import { SolanaAgentKit } from "../index";
import {
ALL_TOKENS,
marketSdkInfo,
marketTokenMap,
getNftTradingAccountInfo,
OPEN_POSITION_CU,
fetchOraclePrice,
createPerpClient,
get_flash_privilege,
} from "../utils/flashUtils";
import { FlashTradeParams } from "../types";
/**
* Opens a new position on Flash.Trade
* @param agent SolanaAgentKit instance
* @param params Trade parameters
* @returns Transaction signature
*/
export async function flashOpenTrade(
agent: SolanaAgentKit,
params: FlashTradeParams,
): Promise<string> {
try {
const { token, side, collateralUsd, leverage } = params;
// Get market ID from token and side using marketTokenMap
const tokenMarkets = marketTokenMap[token];
if (!tokenMarkets) {
throw new Error(`Token ${token} not supported for trading`);
}
const sideEntry = tokenMarkets[side];
if (!sideEntry) {
throw new Error(`${side} side not available for ${token}`);
}
const market = sideEntry.marketID;
// Validate market data using marketSdkInfo
const marketData = marketSdkInfo[market];
if (!marketData) {
throw new Error(`Invalid market configuration for ${token}/${side}`);
}
// Get token information
const [targetSymbol, collateralSymbol] = marketData.tokenPair.split("/");
const targetToken = ALL_TOKENS.find((t) => t.symbol === targetSymbol);
const collateralToken = ALL_TOKENS.find(
(t) => t.symbol === collateralSymbol,
);
if (!targetToken || !collateralToken) {
throw new Error(`Token not found for pair ${marketData.tokenPair}`);
}
// Fetch oracle prices
const [targetPrice, collateralPrice] = await Promise.all([
fetchOraclePrice(targetSymbol),
fetchOraclePrice(collateralSymbol),
]);
// Initialize pool configuration and perpClient
const poolConfig = PoolConfig.fromIdsByName(
marketData.pool,
"mainnet-beta",
);
const perpClient = createPerpClient(agent.connection, agent.wallet);
// Calculate position parameters
const leverageBN = new BN(leverage);
const collateralTokenPrice = convertPriceToNumber(collateralPrice.price);
const collateralAmount = calculateCollateralAmount(
collateralUsd,
collateralTokenPrice,
collateralToken.decimals,
);
// Get custody accounts
const { targetCustody, collateralCustody } = await fetchCustodyAccounts(
perpClient,
poolConfig,
targetSymbol,
collateralSymbol,
);
// Calculate position size
const positionSize = calculatePositionSize(
perpClient,
collateralAmount,
leverageBN,
targetToken,
collateralToken,
side,
targetPrice.price,
collateralPrice.price,
targetCustody,
collateralCustody,
);
// Get NFT trading account info
const tradingAccounts = await getNftTradingAccountInfo(
agent.wallet_address,
perpClient,
poolConfig,
collateralSymbol,
);
if (
!tradingAccounts.nftTradingAccountPk ||
!tradingAccounts.nftReferralAccountPK
) {
throw new Error("Required NFT trading accounts not found");
}
// Prepare transaction
const slippageBps = new BN(1000);
const priceWithSlippage = perpClient.getPriceAfterSlippage(
true,
slippageBps,
targetPrice.price,
side === "long" ? Side.Long : Side.Short,
);
// Build and send transaction
const { instructions, additionalSigners } = await perpClient.openPosition(
targetSymbol,
collateralSymbol,
priceWithSlippage,
collateralAmount,
positionSize,
side === "long" ? Side.Long : Side.Short,
poolConfig,
get_flash_privilege(agent),
tradingAccounts.nftTradingAccountPk,
tradingAccounts.nftReferralAccountPK,
tradingAccounts.nftOwnerRebateTokenAccountPk!,
false,
);
const computeBudgetIx = ComputeBudgetProgram.setComputeUnitLimit({
units: OPEN_POSITION_CU,
});
return await perpClient.sendTransaction(
[computeBudgetIx, ...instructions],
{
additionalSigners: additionalSigners,
alts: perpClient.addressLookupTables,
prioritizationFee: 5000000,
},
);
} catch (error) {
throw new Error(`Flash trade failed: ${error}`);
}
}
// Helper functions
function convertPriceToNumber(oraclePrice: OraclePrice): number {
const price = parseInt(oraclePrice.price.toString("hex"), 16);
const exponent = parseInt(oraclePrice.exponent.toString("hex"), 16);
return price * Math.pow(10, exponent);
}
function calculateCollateralAmount(
usdAmount: number,
tokenPrice: number,
decimals: number,
): BN {
return new BN((usdAmount / tokenPrice) * Math.pow(10, decimals));
}
async function fetchCustodyAccounts(
perpClient: PerpetualsClient,
poolConfig: PoolConfig,
targetSymbol: string,
collateralSymbol: string,
) {
const targetConfig = poolConfig.custodies.find(
(c) => c.symbol === targetSymbol,
);
const collateralConfig = poolConfig.custodies.find(
(c) => c.symbol === collateralSymbol,
);
if (!targetConfig || !collateralConfig) {
throw new Error("Custody configuration not found");
}
const accounts = await perpClient.provider.connection.getMultipleAccountsInfo(
[targetConfig.custodyAccount, collateralConfig.custodyAccount],
);
if (!accounts[0] || !accounts[1]) {
throw new Error("Failed to fetch custody accounts");
}
return {
targetCustody: CustodyAccount.from(
targetConfig.custodyAccount,
perpClient.program.coder.accounts.decode<Custody>(
"custody",
accounts[0].data,
),
),
collateralCustody: CustodyAccount.from(
collateralConfig.custodyAccount,
perpClient.program.coder.accounts.decode<Custody>(
"custody",
accounts[1].data,
),
),
};
}
function calculatePositionSize(
perpClient: PerpetualsClient,
collateralAmount: BN,
leverage: BN,
targetToken: any,
collateralToken: any,
side: "long" | "short",
targetPrice: OraclePrice,
collateralPrice: OraclePrice,
targetCustody: CustodyAccount,
collateralCustody: CustodyAccount,
): BN {
return perpClient.getSizeAmountFromLeverageAndCollateral(
collateralAmount,
leverage.toString(),
targetToken,
collateralToken,
side === "long" ? Side.Long : Side.Short,
targetPrice,
targetPrice,
targetCustody,
collateralPrice,
collateralPrice,
collateralCustody,
);
}

View File

@@ -1,6 +1,4 @@
export * from "./adrena_perp_trading";
export * from "./batch_order";
export * from "./cancel_all_orders";
export * from "./create_gibwork_task";
export * from "./create_image";
export * from "./create_tiplinks";
@@ -20,8 +18,7 @@ export * from "./get_tps";
export * from "./get_wallet_address";
export * from "./launch_pumpfun_token";
export * from "./lend";
export * from "./limit_order";
export * from "./manifest_create_market";
export * from "./manifest_trade";
export * from "./mint_nft";
export * from "./openbook_create_market";
export * from "./orca_close_position";
@@ -44,6 +41,12 @@ export * from "./send_compressed_airdrop";
export * from "./stake_with_jup";
export * from "./stake_with_solayer";
export * from "./tensor_trade";
export * from "./close_empty_token_accounts";
export * from "./trade";
export * from "./transfer";
export * from "./withdraw_all";
export * from "./flash_open_trade";
export * from "./flash_close_trade";
export * from "./create_3land_collectible";

View File

@@ -1,61 +0,0 @@
import {
PublicKey,
Transaction,
sendAndConfirmTransaction,
TransactionInstruction,
} from "@solana/web3.js";
import { SolanaAgentKit } from "../index";
import {
ManifestClient,
WrapperPlaceOrderParamsExternal,
OrderType,
} from "@cks-systems/manifest-sdk";
/**
* Place limit orders using Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @param quantity Amount to trade in tokens
* @param side Buy or Sell
* @param price Price in tokens ie. SOL/USDC
* @returns Transaction signature
*/
export async function limitOrder(
agent: SolanaAgentKit,
marketId: PublicKey,
quantity: number,
side: string,
price: number,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const orderParams: WrapperPlaceOrderParamsExternal = {
numBaseTokens: quantity,
tokenPrice: price,
isBid: side === "Buy",
lastValidSlot: 0,
orderType: OrderType.Limit,
clientOrderId: Number(Math.random() * 1000),
};
const depositPlaceOrderIx: TransactionInstruction[] =
await mfxClient.placeOrderWithRequiredDepositIx(
agent.wallet.publicKey,
orderParams,
);
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(...depositPlaceOrderIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Limit Order failed: ${error.message}`);
}
}

View File

@@ -1,43 +0,0 @@
import { ManifestClient } from "@cks-systems/manifest-sdk";
import {
Keypair,
PublicKey,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
import { SolanaAgentKit } from "../index";
export async function manifestCreateMarket(
agent: SolanaAgentKit,
baseMint: PublicKey,
quoteMint: PublicKey,
): Promise<string[]> {
const marketKeypair: Keypair = Keypair.generate();
const FIXED_MANIFEST_HEADER_SIZE: number = 256;
const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
fromPubkey: agent.wallet.publicKey,
newAccountPubkey: marketKeypair.publicKey,
space: FIXED_MANIFEST_HEADER_SIZE,
lamports: await agent.connection.getMinimumBalanceForRentExemption(
FIXED_MANIFEST_HEADER_SIZE,
),
programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
});
const createMarketIx = ManifestClient["createMarketIx"](
agent.wallet.publicKey,
baseMint,
quoteMint,
marketKeypair.publicKey,
);
const tx: Transaction = new Transaction();
tx.add(createAccountIx);
tx.add(createMarketIx);
const signature = await sendAndConfirmTransaction(agent.connection, tx, [
agent.wallet,
marketKeypair,
]);
return [signature, marketKeypair.publicKey.toBase58()];
}

View File

@@ -1,16 +1,159 @@
import {
PublicKey,
Transaction,
sendAndConfirmTransaction,
TransactionInstruction,
} from "@solana/web3.js";
import {
ManifestClient,
WrapperPlaceOrderParamsExternal,
OrderType,
WrapperPlaceOrderParamsExternal,
} from "@cks-systems/manifest-sdk";
import { SolanaAgentKit } from "../index";
import { BatchOrderPattern, OrderParams } from "../types";
import {
Keypair,
PublicKey,
sendAndConfirmTransaction,
SystemProgram,
Transaction,
TransactionInstruction,
} from "@solana/web3.js";
import { BatchOrderPattern, OrderParams, SolanaAgentKit } from "../index";
export async function manifestCreateMarket(
agent: SolanaAgentKit,
baseMint: PublicKey,
quoteMint: PublicKey,
): Promise<string[]> {
const marketKeypair: Keypair = Keypair.generate();
const FIXED_MANIFEST_HEADER_SIZE: number = 256;
const createAccountIx: TransactionInstruction = SystemProgram.createAccount({
fromPubkey: agent.wallet.publicKey,
newAccountPubkey: marketKeypair.publicKey,
space: FIXED_MANIFEST_HEADER_SIZE,
lamports: await agent.connection.getMinimumBalanceForRentExemption(
FIXED_MANIFEST_HEADER_SIZE,
),
programId: new PublicKey("MNFSTqtC93rEfYHB6hF82sKdZpUDFWkViLByLd1k1Ms"),
});
const createMarketIx = ManifestClient["createMarketIx"](
agent.wallet.publicKey,
baseMint,
quoteMint,
marketKeypair.publicKey,
);
const tx: Transaction = new Transaction();
tx.add(createAccountIx);
tx.add(createMarketIx);
const signature = await sendAndConfirmTransaction(agent.connection, tx, [
agent.wallet,
marketKeypair,
]);
return [signature, marketKeypair.publicKey.toBase58()];
}
/**
* Place limit orders using Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @param quantity Amount to trade in tokens
* @param side Buy or Sell
* @param price Price in tokens ie. SOL/USDC
* @returns Transaction signature
*/
export async function limitOrder(
agent: SolanaAgentKit,
marketId: PublicKey,
quantity: number,
side: string,
price: number,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const orderParams: WrapperPlaceOrderParamsExternal = {
numBaseTokens: quantity,
tokenPrice: price,
isBid: side === "Buy",
lastValidSlot: 0,
orderType: OrderType.Limit,
clientOrderId: Number(Math.random() * 1000),
};
const depositPlaceOrderIx: TransactionInstruction[] =
await mfxClient.placeOrderWithRequiredDepositIx(
agent.wallet.publicKey,
orderParams,
);
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(...depositPlaceOrderIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Limit Order failed: ${error.message}`);
}
}
/**
* Cancels all orders from Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @returns Transaction signature
*/
export async function cancelAllOrders(
agent: SolanaAgentKit,
marketId: PublicKey,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const cancelAllOrdersIx = await mfxClient.cancelAllIx();
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(cancelAllOrdersIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Cancel all orders failed: ${error.message}`);
}
}
/**
* Withdraws all funds from Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @returns Transaction signature
*/
export async function withdrawAll(
agent: SolanaAgentKit,
marketId: PublicKey,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const withdrawAllIx = await mfxClient.withdrawAllIx();
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(...withdrawAllIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Withdraw all failed: ${error.message}`);
}
}
/**
* Generates an array of orders based on the specified pattern

View File

@@ -1,37 +0,0 @@
import {
PublicKey,
sendAndConfirmTransaction,
Transaction,
} from "@solana/web3.js";
import { SolanaAgentKit } from "../index";
import { ManifestClient } from "@cks-systems/manifest-sdk";
/**
* Withdraws all funds from Manifest
* @param agent SolanaAgentKit instance
* @param marketId Public key for the manifest market
* @returns Transaction signature
*/
export async function withdrawAll(
agent: SolanaAgentKit,
marketId: PublicKey,
): Promise<string> {
try {
const mfxClient = await ManifestClient.getClientForMarket(
agent.connection,
marketId,
agent.wallet,
);
const withdrawAllIx = await mfxClient.withdrawAllIx();
const signature = await sendAndConfirmTransaction(
agent.connection,
new Transaction().add(...withdrawAllIx),
[agent.wallet],
);
return signature;
} catch (error: any) {
throw new Error(`Withdraw all failed: ${error.message}`);
}
}

View File

@@ -6,6 +6,7 @@ export interface Config {
OPENAI_API_KEY?: string;
JUPITER_REFERRAL_ACCOUNT?: string;
JUPITER_FEE_BPS?: number;
FLASH_PRIVILEGE?: string;
}
export interface Creator {
@@ -224,3 +225,15 @@ export interface BatchOrderPattern {
numberOfOrders?: number;
individualQuantity?: number;
}
export interface FlashTradeParams {
token: string;
side: "long" | "short";
collateralUsd: number;
leverage: number;
}
export interface FlashCloseTradeParams {
token: string;
side: "long" | "short";
}

300
src/utils/flashUtils.ts Normal file
View File

@@ -0,0 +1,300 @@
import { HermesClient } from "@pythnetwork/hermes-client";
import { OraclePrice } from "flash-sdk";
import { AnchorProvider, BN, Wallet } from "@coral-xyz/anchor";
import {
PoolConfig,
Token,
Referral,
PerpetualsClient,
Privilege,
} from "flash-sdk";
import { Cluster, PublicKey, Connection, Keypair } from "@solana/web3.js";
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
import { SolanaAgentKit } from "../index";
const POOL_NAMES = [
"Crypto.1",
"Virtual.1",
"Governance.1",
"Community.1",
"Community.2",
"Community.3",
];
const DEFAULT_CLUSTER: Cluster = "mainnet-beta";
export const POOL_CONFIGS = POOL_NAMES.map((f) =>
PoolConfig.fromIdsByName(f, DEFAULT_CLUSTER),
);
const DUPLICATE_TOKENS = POOL_CONFIGS.map((f) => f.tokens).flat();
const tokenMap = new Map();
for (const token of DUPLICATE_TOKENS) {
tokenMap.set(token.symbol, token);
}
export const ALL_TOKENS: Token[] = Array.from(tokenMap.values());
export const ALL_CUSTODIES = POOL_CONFIGS.map((f) => f.custodies).flat();
const PROGRAM_ID = POOL_CONFIGS[0].programId;
// CU for trade instructions
export const OPEN_POSITION_CU = 150_000;
export const CLOSE_POSITION_CU = 180_000;
const HERMES_URL = "https://hermes.pyth.network"; // Replace with the actual Hermes URL if different
// Create a map of symbol to Pyth price ID
const PRICE_FEED_IDS = ALL_TOKENS.reduce(
(acc, token) => {
acc[token.symbol] = token.pythPriceId;
return acc;
},
{} as { [key: string]: string },
);
const hermesClient = new HermesClient(HERMES_URL, {});
export interface PythPriceEntry {
price: OraclePrice;
emaPrice: OraclePrice;
isStale: boolean;
status: PriceStatus;
}
export enum PriceStatus {
Trading,
Unknown,
Halted,
Auction,
}
export const fetchOraclePrice = async (
symbol: string,
): Promise<PythPriceEntry> => {
const priceFeedId = PRICE_FEED_IDS[symbol];
if (!priceFeedId) {
throw new Error(`Price feed ID not found for symbol: ${symbol}`);
}
try {
const hermesPriceFeed = await hermesClient.getPriceFeeds({
query: symbol,
filter: "crypto",
});
if (!hermesPriceFeed || hermesPriceFeed.length === 0) {
throw new Error(`No price feed received for ${symbol}`);
}
const hemrmesPriceUdpate = await hermesClient.getLatestPriceUpdates(
[priceFeedId],
{
encoding: "hex",
parsed: true,
},
);
if (!hemrmesPriceUdpate.parsed) {
throw new Error(`No price feed received for ${symbol}`);
}
const hermesEma = hemrmesPriceUdpate.parsed[0].ema_price;
const hermesPrice = hemrmesPriceUdpate.parsed[0].price;
const hermesPriceOracle = new OraclePrice({
price: new BN(hermesPrice.price),
exponent: new BN(hermesPrice.expo),
confidence: new BN(hermesPrice.conf),
timestamp: new BN(hermesPrice.publish_time),
});
const hermesEmaOracle = new OraclePrice({
price: new BN(hermesEma.price),
exponent: new BN(hermesEma.expo),
confidence: new BN(hermesEma.conf),
timestamp: new BN(hermesEma.publish_time),
});
const token = ALL_TOKENS.find((t) => t.pythPriceId === priceFeedId);
if (!token) {
throw new Error(`Token not found for price feed ID: ${priceFeedId}`);
}
const status = !token.isVirtual ? PriceStatus.Trading : PriceStatus.Unknown;
const pythPriceEntry: PythPriceEntry = {
price: hermesPriceOracle,
emaPrice: hermesEmaOracle,
isStale: false,
status: status,
};
return pythPriceEntry;
} catch (error) {
console.error(`Error in fetchOraclePrice for ${symbol}:`, error);
throw error;
}
};
export interface MarketInfo {
[key: string]: {
tokenPair: string;
token: string;
side: string;
pool: string;
};
}
const marketSdkInfo: MarketInfo = {};
// Loop through POOL_CONFIGS to process each market
POOL_CONFIGS.forEach((poolConfig) => {
poolConfig.markets.forEach((market) => {
const targetToken = ALL_TOKENS.find(
(token) => token.mintKey.toString() === market.targetMint.toString(),
);
// Find collateral token by matching mintKey
const collateralToken = ALL_TOKENS.find(
(token) => token.mintKey.toString() === market.collateralMint.toString(),
);
if (targetToken?.symbol && collateralToken?.symbol) {
marketSdkInfo[market.marketAccount.toString()] = {
tokenPair: `${targetToken.symbol}/${collateralToken.symbol}`,
token: targetToken.symbol,
side: Object.keys(market.side)[0],
pool: poolConfig.poolName,
};
}
});
});
export { marketSdkInfo };
export interface MarketTokenSides {
[token: string]: {
long?: { marketID: string };
short?: { marketID: string };
};
}
const marketTokenMap: MarketTokenSides = {};
// Convert marketSdkInfo into marketTokenMap
Object.entries(marketSdkInfo).forEach(([marketID, info]) => {
if (!marketTokenMap[info.token]) {
marketTokenMap[info.token] = {};
}
marketTokenMap[info.token][info.side.toLowerCase() as "long" | "short"] = {
marketID,
};
});
export { marketTokenMap };
interface TradingAccountResult {
nftReferralAccountPK: PublicKey | null;
nftTradingAccountPk: PublicKey | null;
nftOwnerRebateTokenAccountPk: PublicKey | null;
}
export async function getNftTradingAccountInfo(
userPublicKey: PublicKey,
perpClient: PerpetualsClient,
poolConfig: PoolConfig,
collateralCustodySymbol: string,
): Promise<TradingAccountResult> {
const getNFTReferralAccountPK = (publicKey: PublicKey) => {
return PublicKey.findProgramAddressSync(
[Buffer.from("referral"), publicKey.toBuffer()],
PROGRAM_ID,
)[0];
};
const nftReferralAccountPK = getNFTReferralAccountPK(userPublicKey);
const nftReferralAccountInfo =
await perpClient.provider.connection.getAccountInfo(nftReferralAccountPK);
let nftTradingAccountPk: PublicKey | null = null;
let nftOwnerRebateTokenAccountPk: PublicKey | null = null;
if (nftReferralAccountInfo) {
const nftReferralAccountData = perpClient.program.coder.accounts.decode(
"referral",
nftReferralAccountInfo.data,
) as Referral;
nftTradingAccountPk = nftReferralAccountData.refererTradingAccount;
if (nftTradingAccountPk) {
const nftTradingAccountInfo =
await perpClient.provider.connection.getAccountInfo(
nftTradingAccountPk,
);
if (nftTradingAccountInfo) {
const nftTradingAccount = perpClient.program.coder.accounts.decode(
"trading",
nftTradingAccountInfo.data,
) as { owner: PublicKey };
nftOwnerRebateTokenAccountPk = getAssociatedTokenAddressSync(
poolConfig.getTokenFromSymbol(collateralCustodySymbol).mintKey,
nftTradingAccount.owner,
);
// Check if the account exists
const accountExists =
await perpClient.provider.connection.getAccountInfo(
nftOwnerRebateTokenAccountPk,
);
if (!accountExists) {
console.error(
"NFT owner rebate token account does not exist and may need to be created",
);
}
}
}
}
return {
nftReferralAccountPK,
nftTradingAccountPk,
nftOwnerRebateTokenAccountPk,
};
}
/**
* Creates a new PerpetualsClient instance with the given connection and wallet
* @param connection Solana connection
* @param wallet Solana wallet
* @returns PerpetualsClient instance
*/
export function createPerpClient(
connection: Connection,
wallet: Keypair,
): PerpetualsClient {
const provider = new AnchorProvider(connection, new Wallet(wallet), {
commitment: "confirmed",
preflightCommitment: "confirmed",
skipPreflight: true,
});
return new PerpetualsClient(
provider,
POOL_CONFIGS[0].programId,
POOL_CONFIGS[0].perpComposibilityProgramId,
POOL_CONFIGS[0].fbNftRewardProgramId,
POOL_CONFIGS[0].rewardDistributionProgram.programId,
{},
);
}
export function get_flash_privilege(agent: SolanaAgentKit): Privilege {
const FLASH_PRIVILEGE = agent.config.FLASH_PRIVILEGE || "None";
switch (FLASH_PRIVILEGE.toLowerCase()) {
case "referral":
return Privilege.Referral;
case "nft":
return Privilege.NFT;
default:
return Privilege.None;
}
}

63
test/tools/3land.ts Normal file
View File

@@ -0,0 +1,63 @@
import {
CreateCollectionOptions,
CreateSingleOptions,
StoreInitOptions,
} from "@3land/listings-sdk/dist/types/implementation/implementationTypes";
import "dotenv/config";
import { SolanaAgentKit, createSolanaTools } from "../../src";
const agent = new SolanaAgentKit(
process.env.SOLANA_PRIVATE_KEY!,
process.env.RPC_URL!,
{ OPENAI_API_KEY: process.env.OPENAI_API_KEY! },
);
const optionsWithBase58: StoreInitOptions = {
privateKey: process.env.SOLANA_PRIVATE_KEY!,
isMainnet: false,
};
/****************************** CREATING COLLECTION ******************************** */
const collectionOpts: CreateCollectionOptions = {
collectionName: "",
collectionSymbol: "",
collectionDescription: "",
mainImageUrl: "",
};
(async () => {
const collection = await agent.create3LandCollection(
optionsWithBase58,
collectionOpts,
);
console.log("collection: ", collection);
})();
/****************************** CREATING NFT ******************************** */
const collectionAccount = "";
const createItemOptions: CreateSingleOptions = {
itemName: "",
sellerFee: 500, //5%
itemAmount: 100,
itemSymbol: "",
itemDescription: "",
traits: [{ trait_type: "", value: "" }],
price: 0, //100000000 == 0.1 sol
mainImageUrl: "",
};
const isMainnet = false;
(async () => {
const result = agent.create3LandNft(
optionsWithBase58,
collectionAccount,
createItemOptions,
isMainnet,
);
console.log("result: ", result);
})();
export { SolanaAgentKit, createSolanaTools };

View File

@@ -22,7 +22,6 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"skipLibCheck": true,
"resolveJsonModule": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts"]