diff --git a/.env.example b/.env.example index bd420ff..2960871 100644 --- a/.env.example +++ b/.env.example @@ -4,4 +4,5 @@ SOLANA_PRIVATE_KEY= JUPITER_REFERRAL_ACCOUNT= JUPITER_FEE_BPS= FLASH_PRIVILEGE= referral | nft | none -HELIUS_API_KEY= \ No newline at end of file +FLEXLEND_API_KEY= +HELIUS_API_KEY= diff --git a/README.md b/README.md index 6fdedb8..e1d0bab 100644 --- a/README.md +++ b/README.md @@ -134,10 +134,7 @@ console.log("Token Mint Address:", result.mint.toString()); ``` ### Create NFT Collection on 3Land ```typescript -const optionsWithBase58: StoreInitOptions = { - privateKey: "", - isMainnet: true, // if false, collection will be created on devnet 3.land (dev.3.land) -}; +const isDevnet = true; // (Optional) if not present TX takes place in Mainnet const collectionOpts: CreateCollectionOptions = { collectionName: "", @@ -147,18 +144,16 @@ const optionsWithBase58: StoreInitOptions = { }; const result = await agent.create3LandCollection( - optionsWithBase58, - collectionOpts + collectionOpts, + isDevnet, // (Optional) if not present TX takes place in Mainnet ); ``` ### Create NFT on 3Land When creating an NFT using 3Land's tool, it automatically goes for sale on 3.land website ```typescript -const optionsWithBase58: StoreInitOptions = { - privateKey: "", - isMainnet: true, // if false, listing will be on devnet 3.land (dev.3.land) -}; +const isDevnet = true; // (Optional) if not present TX takes place in Mainnet +const withPool = true; // (Optional) only present if NFT will be created with a Liquidity Pool for a specific SPL token const collectionAccount = ""; //hash for the collection const createItemOptions: CreateSingleOptions = { itemName: "", @@ -170,15 +165,15 @@ const createItemOptions: CreateSingleOptions = { { trait_type: "", value: "" }, ], price: 0, //100000000 == 0.1 sol, can be set to 0 for a free mint + splHash: "", //present if listing is on a specific SPL token, if not present sale will be on $SOL, must be present if "withPool" is true + poolName: "", // Only present if "withPool" is true mainImageUrl: "", - splHash: "", //present if listing is on a specific SPL token, if not present sale will be on $SOL }; -const isMainnet = true; const result = await agent.create3LandNft( - optionsWithBase58, collectionAccount, createItemOptions, - isMainnet + isDevnet, // (Optional) if not present TX takes place in Mainnet + withPool ); ``` @@ -471,6 +466,38 @@ Update the address a drift vault is delegated to. const signature = await agent.updateDriftVaultDelegate("41Y8C4oxk4zgJT1KXyQr35UhZcfsp5mP86Z2G7UUzojU", "new-address") ``` +### Get Voltr Vault Position Values + +Get the current position values and total value of assets in a Voltr vault. + +```typescript +const values = await agent.voltrGetPositionValues("7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K") +``` + +### Deposit into Voltr Strategy + +Deposit assets into a specific strategy within a Voltr vault. + +```typescript +const signature = await agent.voltrDepositStrategy( + new BN("1000000000"), // amount in base units (e.g., 1 USDC = 1000000) + "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", // vault + "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk" // strategy +) +``` + +### Withdraw from Voltr Strategy + +Withdraw assets from a specific strategy within a Voltr vault. + +```typescript +const signature = await agent.voltrWithdrawStrategy( + new BN("1000000000"), // amount in base units (e.g., 1 USDC = 1000000) + "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", // vault + "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk" // strategy +) +``` + ## Examples ### LangGraph Multi-Agent System diff --git a/package.json b/package.json index d62664b..26e2604 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "author": "sendaifun", "license": "Apache-2.0", "dependencies": { - "@3land/listings-sdk": "^0.0.4", + "@3land/listings-sdk": "^0.0.6", "@ai-sdk/openai": "^1.0.11", "@bonfida/spl-name-service": "^3.0.7", "@cks-systems/manifest-sdk": "0.1.59", @@ -52,6 +52,7 @@ "@sqds/multisig": "^2.1.3", "@tensor-oss/tensorswap-sdk": "^4.5.0", "@tiplink/api": "^0.3.1", + "@voltr/vault-sdk": "^0.1.1", "ai": "^4.0.22", "bn.js": "^5.2.1", "bs58": "^6.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31aed29..2b64324 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: '@3land/listings-sdk': - specifier: ^0.0.4 - version: 0.0.4(@types/node@22.10.5)(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) + specifier: ^0.0.6 + version: 0.0.6(@types/node@22.10.5)(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) '@ai-sdk/openai': specifier: ^1.0.11 version: 1.0.11(zod@3.24.1) @@ -95,6 +95,9 @@ importers: '@tiplink/api': specifier: ^0.3.1 version: 0.3.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(sodium-native@3.4.1)(utf-8-validate@5.0.10) + '@voltr/vault-sdk': + specifier: ^0.1.1 + version: 0.1.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) ai: specifier: ^4.0.22 version: 4.0.22(react@19.0.0)(zod@3.24.1) @@ -174,8 +177,8 @@ importers: packages: - '@3land/listings-sdk@0.0.4': - resolution: {integrity: sha512-Ljq8R4e7y+wl4m8BGhiInFPCHEzHZZFz1qghnbc8B3bLEKXWM9+2gZOCAa84rdUKuLfzenEdeS2LclTKhdKTFQ==} + '@3land/listings-sdk@0.0.6': + resolution: {integrity: sha512-1OG4qddbij7kLGcyRvwA9WUiif7DJi2gEWODHF4NnfgQHRl22yLSFHZeHPLlo9mE1T2LZnn0I6HtUxvUtCHCAQ==} '@ai-sdk/openai@1.0.11': resolution: {integrity: sha512-qI9s7Slma5i5bB4yYVlFdcG3PNDwdqivPT1Dr8adDX92nSSpILjgFIooS5yys9sXjvvcfOi/WXbDvVhLSRRlvg==} @@ -612,6 +615,12 @@ packages: engines: {node: '>=6'} hasBin: true + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1160,6 +1169,15 @@ packages: '@shikijs/vscode-textmate@10.0.1': resolution: {integrity: sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg==} + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + '@sindresorhus/is@4.6.0': resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} engines: {node: '>=10'} @@ -1304,6 +1322,10 @@ packages: resolution: {integrity: sha512-LZmYCKcPQDtJgecvWOgT/cnoIQPWjdH+QVyzPcFvyDUiT0DiRjZaam4aqNUyvchLFhzgunv3d9xOoyE34ofdoQ==} engines: {node: '>= 10'} + '@solana/spl-token@0.2.0': + resolution: {integrity: sha512-RWcn31OXtdqIxmkzQfB2R+WpsJOVS6rKuvpxJFjvik2LyODd+WN58ZP3Rpjpro03fscGAkzlFuP3r42doRJgyQ==} + engines: {node: '>= 14'} + '@solana/spl-token@0.3.11': resolution: {integrity: sha512-bvohO3rIMSVL24Pb+I4EYTJ6cL82eFpInEXD/I8K8upOGjpqHsKUoAempR/RnUlI1qSFNyFlWJfu6MNUgfbCQQ==} engines: {node: '>=16'} @@ -1411,6 +1433,9 @@ packages: resolution: {integrity: sha512-tuwHtoYzvqnahsMrecfNNkQceCYwgiY0qKS8RwqtaxvDEgjm0E+0bXwKz2eUD3ZFYifomJmRKDmSBx9yQzAeMQ==} engines: {node: '>=20.18.0'} + '@ts-morph/common@0.19.0': + resolution: {integrity: sha512-Unz/WHmd4pGax91rdIKWi51wnVUW11QttMEPpBiBgIewnc9UQIX7UDLxr5vRlqeByXCwhkF6VabSsI0raWcyAQ==} + '@tsconfig/node10@1.0.11': resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} @@ -1584,6 +1609,9 @@ packages: '@ungap/structured-clone@1.2.1': resolution: {integrity: sha512-fEzPV3hSkSMltkw152tJKNARhOupqbH96MZWyRjNaYZOMIzbrTeQDG+MTc6Mr2pgzFQzFxAfmhGDNP5QK++2ZA==} + '@voltr/vault-sdk@0.1.1': + resolution: {integrity: sha512-xh8bxPCwNpjVqEN32+Q40Xf08vdORAmQACDE6ru3T+9qrwNgraLcPEzvWeBNTE0FAMAZdNsYOxWbc2FSK0ZQww==} + '@wallet-standard/base@1.1.0': resolution: {integrity: sha512-DJDQhjKmSNVLKWItoKThJS+CsJQjR9AOBOirBVT1F9YpRyC9oYHE+ZnSf8y8bxUphtKqdQMPVQ2mHohYdRvDVQ==} engines: {node: '>=16'} @@ -1662,6 +1690,10 @@ packages: '@solana/web3.js': ^1.78.4 solana-bankrun: ^0.2.0 + anchor-client-gen@0.28.1: + resolution: {integrity: sha512-Gi205FuTSk1+haoYAGBDAA4h0X1xfmY0C++CQIWwtXIMCSy5+71XEaFMPgmjtYdvVJoAL021NqVrDiBHhNJ+fQ==} + hasBin: true + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -1710,6 +1742,9 @@ packages: arg@4.1.3: resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1814,6 +1849,9 @@ packages: bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + bn.js@4.11.6: resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} @@ -1914,6 +1952,10 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + camelcase@7.0.1: + resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==} + engines: {node: '>=14.16'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -1942,6 +1984,10 @@ packages: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} + check-more-types@2.24.0: + resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} + engines: {node: '>= 0.8.0'} + chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -1984,6 +2030,9 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + code-block-writer@12.0.0: + resolution: {integrity: sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w==} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -2095,6 +2144,15 @@ packages: supports-color: optional: true + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.0: resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==} engines: {node: '>=6.0'} @@ -2205,6 +2263,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -2379,6 +2440,9 @@ packages: resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} engines: {node: '>=6.5.0', npm: '>=3'} + event-stream@3.3.4: + resolution: {integrity: sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -2401,6 +2465,10 @@ packages: resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} engines: {node: '>=12.0.0'} + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -2550,6 +2618,9 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + from@0.1.7: + resolution: {integrity: sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g==} + fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -2587,6 +2658,10 @@ packages: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} engines: {node: '>=8'} + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} @@ -2702,6 +2777,10 @@ packages: resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} engines: {node: '>=10.19.0'} + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} @@ -2821,6 +2900,10 @@ packages: resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} engines: {node: '>=10'} + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2859,6 +2942,9 @@ packages: jito-ts@3.0.1: resolution: {integrity: sha512-TSofF7KqcwyaWGjPaSYC8RDoNBY1TPRNBHdrw24bdIi7mQ5bFEDdYK3D//llw/ml8YDvcZlgd644WxhjLTS9yg==} + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + js-base64@3.7.7: resolution: {integrity: sha512-7rCnleh0z2CkXhH67J8K1Ytz0b2Y+yxTPL+/KOJoa20hfnVQ/3/T6W/KflYI4bRHRagNeXeU2bkNGI3v1oS/lw==} @@ -2997,6 +3083,10 @@ packages: openai: optional: true + lazy-ass@1.6.0: + resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} + engines: {node: '> 0.8'} + levn@0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -3090,6 +3180,9 @@ packages: make-error@1.3.6: resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + map-stream@0.1.0: + resolution: {integrity: sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g==} + markdown-it@14.1.0: resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==} hasBin: true @@ -3205,6 +3298,10 @@ packages: minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + minimatch@9.0.5: resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} engines: {node: '>=16 || 14 >=14.17'} @@ -3223,9 +3320,17 @@ packages: mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + mkdirp@2.1.6: + resolution: {integrity: sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==} + engines: {node: '>=10'} + hasBin: true + ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -3318,6 +3423,10 @@ packages: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + npm-run-path@5.3.0: resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3433,6 +3542,9 @@ packages: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -3464,6 +3576,9 @@ packages: resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} engines: {node: '>= 14.16'} + pause-stream@0.0.11: + resolution: {integrity: sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A==} + pbkdf2@3.1.2: resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} engines: {node: '>=0.12'} @@ -3535,6 +3650,11 @@ packages: proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + ps-tree@1.2.0: + resolution: {integrity: sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA==} + engines: {node: '>= 0.10'} + hasBin: true + pump@3.0.2: resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} @@ -3815,9 +3935,17 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + split@0.3.3: + resolution: {integrity: sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA==} + spok@1.5.5: resolution: {integrity: sha512-IrJIXY54sCNFASyHPOY+jEirkiJ26JDqsGiI0Dvhwcnkl0PEWi1PSsrkYql0rzDw8LFVTcA7rdUCAJdE2HE+2Q==} + start-server-and-test@1.15.4: + resolution: {integrity: sha512-ucQtp5+UCr0m4aHlY+aEV2JSYNTiMZKdSKK/bsIr6AlmwAWDYDnV7uGlWWEtWa7T4XvRI5cPYcPcQgeLqpz+Tg==} + engines: {node: '>=6'} + hasBin: true + statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -3826,6 +3954,9 @@ packages: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} + stream-combiner@0.0.4: + resolution: {integrity: sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw==} + stream-transform@2.1.3: resolution: {integrity: sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ==} @@ -3866,6 +3997,10 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} @@ -3985,6 +4120,9 @@ packages: ts-log@2.2.7: resolution: {integrity: sha512-320x5Ggei84AxzlXp91QkIGSw5wgaLT6GeAH0KsqDmRZdVWW2OiSeVvElVoatk3f7nicwXlElXsoFkARiGE2yg==} + ts-morph@18.0.0: + resolution: {integrity: sha512-Kg5u0mk19PIIe4islUI/HWRvm9bC1lHejK4S0oh1zaZ77TMZAEmQC0sHQYiu2RgCQFZKXz1fMVi/7nOOeirznA==} + ts-node@10.9.2: resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true @@ -4173,6 +4311,11 @@ packages: vlq@2.0.4: resolution: {integrity: sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==} + wait-on@7.0.1: + resolution: {integrity: sha512-9AnJE9qTjRQOlTZIldAaf/da2eW0eSRSgcqq85mXQja/DW3MriHxkpODDSUEg+Gri/rKEcXUZHe+cevvYItaog==} + engines: {node: '>=12.0.0'} + hasBin: true + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -4314,17 +4457,20 @@ packages: snapshots: - '@3land/listings-sdk@0.0.4(@types/node@22.10.5)(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': + '@3land/listings-sdk@0.0.6(@types/node@22.10.5)(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': dependencies: '@coral-xyz/borsh': 0.30.1(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@irys/sdk': 0.2.11(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@metaplex-foundation/beet': 0.7.2 '@metaplex-foundation/mpl-token-metadata': 2.13.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) '@project-serum/anchor': 0.26.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + anchor-client-gen: 0.28.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) bn: 1.0.5 bn.js: 5.2.1 bs58: 6.0.0 + buffer-layout: 1.2.2 cyrb53: 1.0.0 fs: 0.0.1-security irys: 0.0.1 @@ -5165,6 +5311,12 @@ snapshots: protobufjs: 7.4.0 yargs: 17.7.2 + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -5188,6 +5340,16 @@ snapshots: '@humanwhocodes/retry@0.4.1': {} + '@irys/arweave@0.0.2': + dependencies: + asn1.js: 5.4.1 + async-retry: 1.3.3 + axios: 1.7.9 + base64-js: 1.5.1 + bignumber.js: 9.1.2 + transitivePeerDependencies: + - debug + '@irys/arweave@0.0.2(debug@4.4.0)': dependencies: asn1.js: 5.4.1 @@ -5208,7 +5370,7 @@ snapshots: '@irys/query@0.0.8': dependencies: async-retry: 1.3.3 - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 transitivePeerDependencies: - debug @@ -5263,7 +5425,7 @@ snapshots: algosdk: 1.24.1 arbundles: 0.11.2(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) async-retry: 1.3.3 - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 base64url: 3.0.1 bignumber.js: 9.1.2 bs58: 5.0.0 @@ -5468,7 +5630,7 @@ snapshots: '@metaplex-foundation/beet-solana@0.4.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@metaplex-foundation/beet': 0.7.1 + '@metaplex-foundation/beet': 0.7.2 '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) bs58: 5.0.0 debug: 4.4.0 @@ -5678,8 +5840,8 @@ snapshots: '@metaplex-foundation/mpl-token-metadata@2.13.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)': dependencies: - '@metaplex-foundation/beet': 0.7.1 - '@metaplex-foundation/beet-solana': 0.4.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/beet': 0.7.2 + '@metaplex-foundation/beet-solana': 0.4.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@metaplex-foundation/cusper': 0.0.2 '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -5695,8 +5857,8 @@ snapshots: '@metaplex-foundation/mpl-token-metadata@2.13.0(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': dependencies: - '@metaplex-foundation/beet': 0.7.1 - '@metaplex-foundation/beet-solana': 0.4.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/beet': 0.7.2 + '@metaplex-foundation/beet-solana': 0.4.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@metaplex-foundation/cusper': 0.0.2 '@solana/spl-token': 0.3.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -6150,7 +6312,7 @@ snapshots: dependencies: '@pythnetwork/price-service-sdk': 1.8.0 '@types/ws': 8.5.13 - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 axios-retry: 3.9.1 isomorphic-ws: 4.0.1(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) ts-log: 2.2.7 @@ -6204,7 +6366,7 @@ snapshots: '@solana/buffer-layout': 4.0.1 '@solana/spl-token': 0.4.9(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 big.js: 6.2.2 bn.js: 5.2.1 dayjs: 1.11.13 @@ -6293,6 +6455,14 @@ snapshots: '@shikijs/vscode-textmate@10.0.1': {} + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + '@sindresorhus/is@4.6.0': {} '@solana/buffer-layout-utils@0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': @@ -6685,6 +6855,18 @@ snapshots: - encoding - utf-8-validate + '@solana/spl-token@0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@solana/buffer-layout': 4.0.1 + '@solana/buffer-layout-utils': 0.2.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + start-server-and-test: 1.15.4 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + '@solana/spl-token@0.3.11(@solana/web3.js@1.92.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)': dependencies: '@solana/buffer-layout': 4.0.1 @@ -7024,7 +7206,7 @@ snapshots: '@switchboard-xyz/common@2.5.12(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 big.js: 6.2.2 bn.js: 5.2.1 bs58: 6.0.0 @@ -7047,7 +7229,7 @@ snapshots: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@solworks/soltoolkit-sdk': 0.0.23(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(utf-8-validate@5.0.10) '@switchboard-xyz/common': 2.5.12(bufferutil@4.0.9)(utf-8-validate@5.0.10) - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 big.js: 6.2.2 bs58: 5.0.0 js-yaml: 4.1.0 @@ -7137,6 +7319,13 @@ snapshots: dependencies: '@grpc/grpc-js': 1.12.5 + '@ts-morph/common@0.19.0': + dependencies: + fast-glob: 3.3.2 + minimatch: 7.4.6 + mkdirp: 2.1.6 + path-browserify: 1.0.1 + '@tsconfig/node10@1.0.11': {} '@tsconfig/node12@1.0.11': {} @@ -7352,6 +7541,18 @@ snapshots: '@ungap/structured-clone@1.2.1': {} + '@voltr/vault-sdk@0.1.1(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': + dependencies: + '@coral-xyz/anchor': 0.30.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@solana/spl-token': 0.4.9(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + '@wallet-standard/base@1.1.0': {} '@wallet-standard/features@1.1.0': @@ -7360,7 +7561,7 @@ snapshots: '@zodios/core@10.9.6(axios@1.7.9)(zod@3.24.1)': dependencies: - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 zod: 3.24.1 JSONStream@1.3.5: @@ -7436,6 +7637,23 @@ snapshots: '@solana/web3.js': 1.92.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) solana-bankrun: 0.3.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + anchor-client-gen@0.28.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@coral-xyz/anchor': 0.28.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@coral-xyz/borsh': 0.28.0(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + bn.js: 5.2.1 + camelcase: 7.0.1 + commander: 10.0.1 + js-sha256: 0.9.0 + prettier: 2.8.8 + snake-case: 3.0.4 + ts-morph: 18.0.0 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -7503,7 +7721,7 @@ snapshots: '@ethersproject/signing-key': 5.7.0 '@ethersproject/transactions': 5.7.0 '@ethersproject/wallet': 5.7.0 - '@irys/arweave': 0.0.2(debug@4.4.0) + '@irys/arweave': 0.0.2 '@noble/ed25519': 1.7.3 base64url: 3.0.1 bs58: 4.0.1 @@ -7529,6 +7747,8 @@ snapshots: arg@4.1.3: {} + arg@5.0.2: {} + argparse@2.0.1: {} array-flatten@1.1.1: {} @@ -7579,6 +7799,13 @@ snapshots: '@babel/runtime': 7.26.0 is-retry-allowed: 2.2.0 + axios@0.27.2(debug@4.3.4): + dependencies: + follow-redirects: 1.15.9(debug@4.3.4) + form-data: 4.0.1 + transitivePeerDependencies: + - debug + axios@0.27.2(debug@4.4.0): dependencies: follow-redirects: 1.15.9(debug@4.4.0) @@ -7588,7 +7815,7 @@ snapshots: axios@0.28.1: dependencies: - follow-redirects: 1.15.9(debug@4.4.0) + follow-redirects: 1.15.9 form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -7596,7 +7823,15 @@ snapshots: axios@1.7.4: dependencies: - follow-redirects: 1.15.9(debug@4.4.0) + follow-redirects: 1.15.9 + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + axios@1.7.9: + dependencies: + follow-redirects: 1.15.9 form-data: 4.0.1 proxy-from-env: 1.1.0 transitivePeerDependencies: @@ -7662,6 +7897,8 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + bluebird@3.7.2: {} + bn.js@4.11.6: {} bn.js@4.12.1: {} @@ -7780,6 +8017,8 @@ snapshots: camelcase@6.3.0: {} + camelcase@7.0.1: {} + ccount@2.0.1: {} chai@5.1.2: @@ -7805,6 +8044,8 @@ snapshots: check-error@2.1.1: {} + check-more-types@2.24.0: {} + chownr@1.1.4: {} cipher-base@1.0.6: @@ -7843,6 +8084,8 @@ snapshots: clone@2.1.2: {} + code-block-writer@12.0.0: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 @@ -7939,6 +8182,10 @@ snapshots: dependencies: ms: 2.0.0 + debug@4.3.4: + dependencies: + ms: 2.1.2 + debug@4.4.0: dependencies: ms: 2.1.3 @@ -8020,6 +8267,8 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexer@0.1.2: {} + eastasianwidth@0.2.0: {} ee-first@1.1.1: {} @@ -8266,6 +8515,16 @@ snapshots: bn.js: 4.11.6 number-to-bn: 1.7.0 + event-stream@3.3.4: + dependencies: + duplexer: 0.1.2 + from: 0.1.7 + map-stream: 0.1.0 + pause-stream: 0.0.11 + split: 0.3.3 + stream-combiner: 0.0.4 + through: 2.3.8 + event-target-shim@5.0.1: {} eventemitter3@4.0.7: {} @@ -8278,6 +8537,18 @@ snapshots: eventsource@2.0.2: {} + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -8470,6 +8741,12 @@ snapshots: flatted@3.3.2: {} + follow-redirects@1.15.9: {} + + follow-redirects@1.15.9(debug@4.3.4): + optionalDependencies: + debug: 4.3.4 + follow-redirects@1.15.9(debug@4.4.0): optionalDependencies: debug: 4.4.0 @@ -8510,6 +8787,8 @@ snapshots: fresh@0.5.2: {} + from@0.1.7: {} + fs-constants@1.0.0: {} fs.realpath@1.0.0: {} @@ -8547,6 +8826,8 @@ snapshots: dependencies: pump: 3.0.2 + get-stream@6.0.1: {} + get-stream@8.0.1: {} get-tsconfig@4.8.1: @@ -8713,6 +8994,8 @@ snapshots: quick-lru: 5.1.1 resolve-alpn: 1.2.1 + human-signals@2.1.0: {} + human-signals@5.0.0: {} humanize-ms@1.2.1: @@ -8823,6 +9106,8 @@ snapshots: is-retry-allowed@2.2.0: {} + is-stream@2.0.1: {} + is-stream@3.0.0: {} is-typed-array@1.1.15: @@ -8886,6 +9171,14 @@ snapshots: - encoding - utf-8-validate + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + js-base64@3.7.7: {} js-sha256@0.11.0: {} @@ -8975,7 +9268,7 @@ snapshots: zod-to-json-schema: 3.24.1(zod@3.24.1) optionalDependencies: '@langchain/groq': 0.1.2(@langchain/core@0.3.27(openai@4.77.3(zod@3.24.1))) - axios: 1.7.9(debug@4.4.0) + axios: 1.7.9 transitivePeerDependencies: - encoding - openai @@ -8991,6 +9284,8 @@ snapshots: optionalDependencies: openai: 4.77.3(zod@3.24.1) + lazy-ass@1.6.0: {} + levn@0.4.1: dependencies: prelude-ls: 1.2.1 @@ -9089,6 +9384,8 @@ snapshots: make-error@1.3.6: {} + map-stream@0.1.0: {} + markdown-it@14.1.0: dependencies: argparse: 2.0.1 @@ -9196,6 +9493,10 @@ snapshots: dependencies: brace-expansion: 1.1.11 + minimatch@7.4.6: + dependencies: + brace-expansion: 2.0.1 + minimatch@9.0.5: dependencies: brace-expansion: 2.0.1 @@ -9208,8 +9509,12 @@ snapshots: mkdirp-classic@0.5.3: {} + mkdirp@2.1.6: {} + ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} multistream@4.1.0: @@ -9288,6 +9593,10 @@ snapshots: normalize-url@6.1.0: {} + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + npm-run-path@5.3.0: dependencies: path-key: 4.0.0 @@ -9418,6 +9727,8 @@ snapshots: parseurl@1.3.3: {} + path-browserify@1.0.1: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -9440,6 +9751,10 @@ snapshots: pathval@2.0.0: {} + pause-stream@0.0.11: + dependencies: + through: 2.3.8 + pbkdf2@3.1.2: dependencies: create-hash: 1.2.0 @@ -9521,6 +9836,10 @@ snapshots: proxy-from-env@1.1.0: {} + ps-tree@1.2.0: + dependencies: + event-stream: 3.3.4 + pump@3.0.2: dependencies: end-of-stream: 1.4.4 @@ -9857,6 +10176,10 @@ snapshots: space-separated-tokens@2.0.2: {} + split@0.3.3: + dependencies: + through: 2.3.8 + spok@1.5.5: dependencies: ansicolors: 0.3.2 @@ -9865,10 +10188,27 @@ snapshots: - jiti - supports-color + start-server-and-test@1.15.4: + dependencies: + arg: 5.0.2 + bluebird: 3.7.2 + check-more-types: 2.24.0 + debug: 4.3.4 + execa: 5.1.1 + lazy-ass: 1.6.0 + ps-tree: 1.2.0 + wait-on: 7.0.1(debug@4.3.4) + transitivePeerDependencies: + - supports-color + statuses@1.5.0: {} statuses@2.0.1: {} + stream-combiner@0.0.4: + dependencies: + duplexer: 0.1.2 + stream-transform@2.1.3: dependencies: mixme: 0.5.10 @@ -9914,6 +10254,8 @@ snapshots: strip-bom@3.0.0: {} + strip-final-newline@2.0.0: {} + strip-final-newline@3.0.0: {} strip-hex-prefix@1.0.0: @@ -10014,6 +10356,11 @@ snapshots: ts-log@2.2.7: {} + ts-morph@18.0.0: + dependencies: + '@ts-morph/common': 0.19.0 + code-block-writer: 12.0.0 + ts-node@10.9.2(@types/node@20.17.11)(typescript@5.7.2): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -10233,6 +10580,16 @@ snapshots: vlq@2.0.4: {} + wait-on@7.0.1(debug@4.3.4): + dependencies: + axios: 0.27.2(debug@4.3.4) + joi: 17.13.3 + lodash: 4.17.21 + minimist: 1.2.8 + rxjs: 7.8.1 + transitivePeerDependencies: + - debug + wcwidth@1.0.1: dependencies: defaults: 1.0.4 diff --git a/src/actions/index.ts b/src/actions/index.ts index 03a5b83..5fca366 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -14,6 +14,8 @@ import stakeWithJupAction from "./jupiter/stakeWithJup"; import stakeWithSolayerAction from "./solayer/stakeWithSolayer"; import registerDomainAction from "./sns/registerDomain"; import lendAssetAction from "./lulo/lendAsset"; +import luloLendAction from "./lulo/luloLend"; +import luloWithdrawAction from "./lulo/luloWithdraw"; import createGibworkTaskAction from "./gibwork/createGibworkTask"; import resolveSolDomainAction from "./sns/resolveSolDomain"; import pythFetchPriceAction from "./pyth/pythFetchPrice"; @@ -67,6 +69,9 @@ import driftSpotTokenSwapAction from "./drift/swapSpotToken"; import perpMarktetFundingRateAction from "./drift/perpMarketFundingRate"; import entryQuoteOfPerpTradeAction from "./drift/entryQuoteOfPerpTrade"; import lendAndBorrowAPYAction from "./drift/getLendAndBorrowAPY"; +import getVoltrPositionValuesAction from "./voltr/getPositionValues"; +import depositVoltrStrategyAction from "./voltr/depositStrategy"; +import withdrawVoltrStrategyAction from "./voltr/withdrawStrategy"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, @@ -86,6 +91,8 @@ export const ACTIONS = { STAKE_WITH_SOLAYER_ACTION: stakeWithSolayerAction, REGISTER_DOMAIN_ACTION: registerDomainAction, LEND_ASSET_ACTION: lendAssetAction, + LULO_LEND_ACTION: luloLendAction, + LULO_WITHDRAW_ACTION: luloWithdrawAction, CREATE_GIBWORK_TASK_ACTION: createGibworkTaskAction, RESOLVE_SOL_DOMAIN_ACTION: resolveSolDomainAction, PYTH_FETCH_PRICE_ACTION: pythFetchPriceAction, @@ -140,6 +147,9 @@ export const ACTIONS = { DRIFT_PERP_MARKET_FUNDING_RATE_ACTION: perpMarktetFundingRateAction, DRIFT_GET_ENTRY_QUOTE_OF_PERP_TRADE_ACTION: entryQuoteOfPerpTradeAction, DRIFT_GET_LEND_AND_BORROW_APY_ACTION: lendAndBorrowAPYAction, + GET_VOLTR_POSITION_VALUES_ACTION: getVoltrPositionValuesAction, + DEPOSIT_VOLTR_STRATEGY_ACTION: depositVoltrStrategyAction, + WITHDRAW_VOLTR_STRATEGY_ACTION: withdrawVoltrStrategyAction, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/actions/lulo/luloLend.ts b/src/actions/lulo/luloLend.ts new file mode 100644 index 0000000..937930c --- /dev/null +++ b/src/actions/lulo/luloLend.ts @@ -0,0 +1,62 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { luloLend } from "../../tools/lulo"; + +const luloLendAction: Action = { + name: "LULO_LEND", + similes: [ + "lend USDC with lulo", + "lend PYUSD with lulo", + "lend USDS with lulo", + "lend USDT with lulo", + "lend SQL with lulo", + "lend jitoSQL with lulo", + "lend bSQL with lulo", + "lend mSQL with lulo", + "lend BONK with lulo", + "lend JUP with lulo", + ], + description: "Lend SPL tokens using Lulo protocol", + examples: [ + [ + { + input: { + mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + amount: 100, + }, + output: { + status: "success", + signature: "4xKpN2...", + message: "Successfully lend 100 USDC", + }, + explanation: "Lend 100 USDC on Lulo", + }, + ], + ], + schema: z.object({ + mintAddress: z.string().describe("SPL Mint address"), + amount: z.number().positive().describe("Amount to lend"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const mintAddress = input.mintAddress as string; + const amount = input.amount as number; + + const response = await luloLend(agent, mintAddress, amount); + + return { + status: "success", + signature: response, + message: `Successfully lend ${amount} of token ${mintAddress}`, + }; + } catch (error: any) { + return { + status: "error", + message: `Lend failed: ${error.message}`, + }; + } + }, +}; + +export default luloLendAction; diff --git a/src/actions/lulo/luloWithdraw.ts b/src/actions/lulo/luloWithdraw.ts new file mode 100644 index 0000000..6c70933 --- /dev/null +++ b/src/actions/lulo/luloWithdraw.ts @@ -0,0 +1,62 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { luloWithdraw } from "../../tools/lulo"; + +const luloWithdrawAction: Action = { + name: "LULO_WITHDRAW", + similes: [ + "withdraw USDC with lulo", + "withdraw PYUSD with lulo", + "withdraw USDS with lulo", + "withdraw USDT with lulo", + "withdraw SQL with lulo", + "withdraw jitoSQL with lulo", + "withdraw bSQL with lulo", + "withdraw mSQL with lulo", + "withdraw BONK with lulo", + "withdraw JUP with lulo", + ], + description: "Withdraw SPL tokens using Lulo protocol", + examples: [ + [ + { + input: { + mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + amount: 100, + }, + output: { + status: "success", + signature: "4xKpN2...", + message: "Successfully withdraw 100 USDC", + }, + explanation: "Withdraw 100 USDC on Lulo", + }, + ], + ], + schema: z.object({ + mintAddress: z.string().describe("SPL Mint address"), + amount: z.number().positive().describe("Amount to lend"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const mintAddress = input.mintAddress as string; + const amount = input.amount as number; + + const response = await luloWithdraw(agent, mintAddress, amount); + + return { + status: "success", + signature: response, + message: `Successfully withdraw ${amount} of token ${mintAddress}`, + }; + } catch (error: any) { + return { + status: "error", + message: `Withdraw failed: ${error.message}`, + }; + } + }, +}; + +export default luloWithdrawAction; diff --git a/src/actions/voltr/depositStrategy.ts b/src/actions/voltr/depositStrategy.ts new file mode 100644 index 0000000..d1305c9 --- /dev/null +++ b/src/actions/voltr/depositStrategy.ts @@ -0,0 +1,83 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { PublicKey } from "@solana/web3.js"; +import { BN } from "bn.js"; + +const depositVoltrStrategyAction: Action = { + name: "DEPOSIT_VOLTR_STRATEGY", + similes: [ + "deposit to voltr strategy", + "add funds to voltr vault strategy", + "invest in voltr strategy", + "deposit assets to voltr", + "contribute to voltr vault", + "fund voltr strategy", + ], + description: "Deposit assets into a specific strategy within a Voltr vault", + examples: [ + [ + { + input: { + depositAmount: "1000000000", // 1 USDC with 6 decimals + vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", + strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk", + }, + output: { + status: "success", + vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", + strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk", + signature: "2ZE7Rz...", + message: "Successfully deposited 1000000000 into strategy", + }, + explanation: "Deposit 1 USDC into a Voltr vault strategy", + }, + ], + ], + schema: z.object({ + depositAmount: z + .string() + .min(1) + .describe("The amount to deposit (in base units including decimals)"), + vault: z + .string() + .min(1) + .describe( + "The public key of the Voltr source vault to take assets from, e.g., 'Ga27...'", + ), + strategy: z + .string() + .min(1) + .describe( + "The public key of the initialized target strategy to deposit into, e.g., 'Jheh...'", + ), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const depositAmount = new BN(input.depositAmount); + const vault = new PublicKey(input.vault); + const strategy = new PublicKey(input.strategy); + + const signature = await agent.voltrDepositStrategy( + depositAmount, + vault, + strategy, + ); + + return { + status: "success", + vault: vault.toBase58(), + strategy: strategy.toBase58(), + signature, + message: `Successfully deposited ${input.depositAmount} into strategy`, + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to deposit into strategy: ${error.message}`, + }; + } + }, +}; + +export default depositVoltrStrategyAction; diff --git a/src/actions/voltr/getPositionValues.ts b/src/actions/voltr/getPositionValues.ts new file mode 100644 index 0000000..a98424e --- /dev/null +++ b/src/actions/voltr/getPositionValues.ts @@ -0,0 +1,74 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { PublicKey } from "@solana/web3.js"; + +const getVoltrPositionValuesAction: Action = { + name: "GET_VOLTR_POSITION_VALUES", + similes: [ + "get voltr vault value", + "check voltr position", + "get voltr vault assets", + "view voltr holdings", + "check voltr portfolio", + "get voltr vault breakdown", + ], + description: + "Get the current position values and total assets for a Voltr vault", + examples: [ + [ + { + input: { + vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", + }, + output: { + status: "success", + data: { + totalValue: 1000000, + positions: [ + { + strategy: "4JHtgXyMb9gFJ1hGd2sh645jrZcxurSG3QP7Le3aTMTx", + value: 600000, + }, + { + strategy: "4i9kzGr1UkxBCCUkQUQ4vsF51fjdt2knKxrwM1h1NW4g", + value: 400000, + }, + ], + }, + message: "Successfully retrieved Voltr vault position values", + }, + explanation: + "Get position values for a Voltr vault showing total value and value per strategy", + }, + ], + ], + schema: z.object({ + vault: z + .string() + .min(1) + .describe("The public key of the Voltr vault to query, e.g., 'Ga27...'"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const vault = new PublicKey(input.vault); + + const result = await agent.voltrGetPositionValues(vault); + const positionData = JSON.parse(result); + + return { + status: "success", + vault: vault.toBase58(), + data: positionData, + message: "Successfully retrieved Voltr vault position values", + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to get vault position values: ${error.message}`, + }; + } + }, +}; + +export default getVoltrPositionValuesAction; diff --git a/src/actions/voltr/withdrawStrategy.ts b/src/actions/voltr/withdrawStrategy.ts new file mode 100644 index 0000000..784207e --- /dev/null +++ b/src/actions/voltr/withdrawStrategy.ts @@ -0,0 +1,83 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { PublicKey } from "@solana/web3.js"; +import { BN } from "bn.js"; + +const withdrawVoltrStrategyAction: Action = { + name: "WITHDRAW_VOLTR_STRATEGY", + similes: [ + "withdraw from voltr strategy", + "remove funds from voltr vault strategy", + "take out from voltr strategy", + "withdraw assets from voltr", + "pull from voltr vault", + "redeem from voltr strategy", + ], + description: "Withdraw assets from a specific strategy within a Voltr vault", + examples: [ + [ + { + input: { + withdrawAmount: "1000000000", // 1 USDC with 6 decimals + vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", + strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk", + }, + output: { + status: "success", + vault: "7opUkqYtxmQRriZvwZkPcg6LqmGjAh1RSEsVrdsGDx5K", + strategy: "9ZQQYvr4x7AMqd6abVa1f5duGjti5wk1MHsX6hogPsLk", + signature: "2ZE7Rz...", + message: "Successfully withdrew 1000000000 from strategy", + }, + explanation: "Withdraw 1 USDC from a Voltr vault strategy", + }, + ], + ], + schema: z.object({ + withdrawAmount: z + .string() + .min(1) + .describe("The amount to withdraw (in base units including decimals)"), + vault: z + .string() + .min(1) + .describe( + "The public key of the Voltr source vault to deposit assets into, e.g., 'Ga27...'", + ), + strategy: z + .string() + .min(1) + .describe( + "The public key of the initialized target strategy to withdraw from, e.g., 'Jheh...'", + ), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const withdrawAmount = new BN(input.withdrawAmount); + const vault = new PublicKey(input.vault); + const strategy = new PublicKey(input.strategy); + + const signature = await agent.voltrWithdrawStrategy( + withdrawAmount, + vault, + strategy, + ); + + return { + status: "success", + vault: vault.toBase58(), + strategy: strategy.toBase58(), + signature, + message: `Successfully withdrew ${input.withdrawAmount} from strategy`, + }; + } catch (error: any) { + return { + status: "error", + message: `Failed to withdraw from strategy: ${error.message}`, + }; + } + }, +}; + +export default withdrawVoltrStrategyAction; diff --git a/src/agent/index.ts b/src/agent/index.ts index 52add58..8d82a9b 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -18,6 +18,8 @@ import { getPrimaryDomain, launchPumpFunToken, lendAsset, + luloLend, + luloWithdraw, mintCollectionNFT, openbookCreateMarket, manifestCreateMarket, @@ -107,6 +109,9 @@ import { calculatePerpMarketFundingRate, getEntryQuoteOfPerpTrade, getLendingAndBorrowAPY, + voltrGetPositionValues, + voltrDepositStrategy, + voltrWithdrawStrategy, } from "../tools"; import { Config, @@ -320,6 +325,14 @@ export class SolanaAgentKit { return lendAsset(this, amount); } + async luloLend(mintAddress: string, amount: number): Promise { + return luloLend(this, mintAddress, amount); + } + + async luloWithdraw(mintAddress: string, amount: number): Promise { + return luloWithdraw(this, mintAddress, amount); + } + async getTPS(): Promise { return getTPS(this); } @@ -640,24 +653,43 @@ export class SolanaAgentKit { } async create3LandCollection( - optionsWithBase58: StoreInitOptions, collectionOpts: CreateCollectionOptions, + isDevnet: boolean = false, ): Promise { + let optionsWithBase58: StoreInitOptions = { + privateKey: this.wallet.secretKey, + }; + if (isDevnet) { + optionsWithBase58.isMainnet = false; + } else { + optionsWithBase58.isMainnet = true; + } + const tx = await createCollection(optionsWithBase58, collectionOpts); return `Transaction: ${tx}`; } async create3LandNft( - optionsWithBase58: StoreInitOptions, collectionAccount: string, createItemOptions: CreateSingleOptions, - isMainnet: boolean, + isDevnet: boolean = false, + withPool: boolean = false, ): Promise { + let optionsWithBase58: StoreInitOptions = { + privateKey: this.wallet.secretKey, + }; + if (isDevnet) { + optionsWithBase58.isMainnet = false; + } else { + optionsWithBase58.isMainnet = true; + } + const tx = await createSingle( optionsWithBase58, collectionAccount, createItemOptions, - isMainnet, + !isDevnet, + withPool, ); return `Transaction: ${tx}`; } @@ -736,6 +768,7 @@ export class SolanaAgentKit { async createDriftUserAccount(depositAmount: number, depositSymbol: string) { return await createDriftUserAccount(this, depositAmount, depositSymbol); } + async createDriftVault(params: { name: string; marketName: `${string}-${string}`; @@ -749,6 +782,7 @@ export class SolanaAgentKit { }) { return await createVault(this, params); } + async depositIntoDriftVault(amount: number, vault: string) { return await depositIntoVault(this, amount, vault); } @@ -830,6 +864,7 @@ export class SolanaAgentKit { async updateDriftVaultDelegate(vaultAddress: string, delegate: string) { return await updateVaultDelegate(this, vaultAddress, delegate); } + getAvailableDriftMarkets(type?: "spot" | "perp") { switch (type) { case "spot": @@ -889,5 +924,24 @@ export class SolanaAgentKit { } async getLendAndBorrowAPY(symbol: string) { return getLendingAndBorrowAPY(this, symbol); + + async voltrDepositStrategy( + depositAmount: BN, + vault: PublicKey, + strategy: PublicKey, + ): Promise { + return voltrDepositStrategy(this, depositAmount, vault, strategy); + } + + async voltrWithdrawStrategy( + withdrawAmount: BN, + vault: PublicKey, + strategy: PublicKey, + ): Promise { + return voltrWithdrawStrategy(this, withdrawAmount, vault, strategy); + } + + async voltrGetPositionValues(vault: PublicKey): Promise { + return voltrGetPositionValues(this, vault); } } diff --git a/src/langchain/3land/create_collection.ts b/src/langchain/3land/create_collection.ts index 111dd4c..490ab27 100644 --- a/src/langchain/3land/create_collection.ts +++ b/src/langchain/3land/create_collection.ts @@ -10,7 +10,6 @@ export class Solana3LandCreateCollection extends Tool { description = `Creates an NFT Collection that you can visit on 3.land's website (3.land/collection/{collectionAccount}) Inputs: - privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string isMainnet (required): defines is the tx takes places in mainnet collectionSymbol (required): the symbol of the collection collectionName (required): the name of the collection @@ -26,14 +25,8 @@ export class Solana3LandCreateCollection extends Tool { protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); - const privateKey = inputFormat.privateKey; const isMainnet = inputFormat.isMainnet; - const optionsWithBase58: StoreInitOptions = { - ...(privateKey && { privateKey }), - ...(isMainnet && { isMainnet }), - }; - const collectionSymbol = inputFormat?.collectionSymbol; const collectionName = inputFormat?.collectionName; const collectionDescription = inputFormat?.collectionDescription; @@ -49,8 +42,8 @@ export class Solana3LandCreateCollection extends Tool { }; const tx = await this.solanaKit.create3LandCollection( - optionsWithBase58, collectionOpts, + !isMainnet, ); return JSON.stringify({ status: "success", diff --git a/src/langchain/3land/create_single.ts b/src/langchain/3land/create_single.ts index 25db42e..13ec429 100644 --- a/src/langchain/3land/create_single.ts +++ b/src/langchain/3land/create_single.ts @@ -10,7 +10,6 @@ export class Solana3LandCreateSingle extends Tool { description = `Creates an NFT and lists it on 3.land's website Inputs: - privateKey (required): represents the privateKey of the wallet - can be an array of numbers, Uint8Array or base58 string collectionAccount (optional): represents the account for the nft collection itemName (required): the name of the NFT sellerFee (required): the fee of the seller @@ -21,7 +20,9 @@ export class Solana3LandCreateSingle extends Tool { mainImageUrl (required): the main image of the NFT coverImageUrl (optional): the cover image of the NFT splHash (optional): the hash of the spl token, if not provided listing will be in $SOL - isMainnet (required): defines is the tx takes places in mainnet + poolName (optional): the name of the pool + isMainnet (required): defines if the tx takes places in mainnet + withPool (optional): defines if minted edition will be tied to a liquidity pool `; constructor(private solanaKit: SolanaAgentKit) { @@ -31,13 +32,9 @@ export class Solana3LandCreateSingle extends Tool { protected async _call(input: string): Promise { try { const inputFormat = JSON.parse(input); - const privateKey = inputFormat.privateKey; const isMainnet = inputFormat.isMainnet; - - const optionsWithBase58: StoreInitOptions = { - ...(privateKey && { privateKey }), - ...(isMainnet && { isMainnet }), - }; + const withPool = inputFormat.withPool; + const poolName = inputFormat.poolName; const collectionAccount = inputFormat.collectionAccount; @@ -52,6 +49,15 @@ export class Solana3LandCreateSingle extends Tool { const coverImageUrl = inputFormat?.coverImageUrl; const splHash = inputFormat?.splHash; + if (withPool) { + if (!poolName) { + throw new Error("poolName is required when withPool is true"); + } + if (!splHash) { + throw new Error("splHash is required when withPool is true"); + } + } + const createItemOptions: CreateSingleOptions = { ...(itemName && { itemName }), ...(sellerFee && { sellerFee }), @@ -63,6 +69,7 @@ export class Solana3LandCreateSingle extends Tool { ...(mainImageUrl && { mainImageUrl }), ...(coverImageUrl && { coverImageUrl }), ...(splHash && { splHash }), + ...(poolName && { poolName }), }; if (!collectionAccount) { @@ -70,10 +77,10 @@ export class Solana3LandCreateSingle extends Tool { } const tx = await this.solanaKit.create3LandNft( - optionsWithBase58, collectionAccount, createItemOptions, - isMainnet, + !isMainnet, + withPool, ); return JSON.stringify({ status: "success", diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 7fe40e3..788a834 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -26,6 +26,7 @@ export * from "./lightprotocol"; export * from "./squads"; export * from "./helius"; export * from "./drift"; +export * from "./voltr"; import type { SolanaAgentKit } from "../agent"; import { @@ -42,6 +43,8 @@ import { SolanaPumpfunTokenLaunchTool, SolanaCreateImageTool, SolanaLendAssetTool, + SolanaLuloLendTool, + SolanaLuloWithdrawTool, SolanaTPSCalculatorTool, SolanaStakeTool, SolanaRestakeTool, @@ -121,6 +124,9 @@ import { SolanaRequestUnstakeFromDriftInsuranceFundTool, SolanaStakeToDriftInsuranceFundTool, SolanaUnstakeFromDriftInsuranceFundTool, + SolanaVoltrGetPositionValues, + SolanaVoltrDepositStrategy, + SolanaVoltrWithdrawStrategy, } from "./index"; export function createSolanaTools(solanaKit: SolanaAgentKit) { @@ -138,6 +144,8 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaPumpfunTokenLaunchTool(solanaKit), new SolanaCreateImageTool(solanaKit), new SolanaLendAssetTool(solanaKit), + new SolanaLuloLendTool(solanaKit), + new SolanaLuloWithdrawTool(solanaKit), new SolanaTPSCalculatorTool(solanaKit), new SolanaStakeTool(solanaKit), new SolanaRestakeTool(solanaKit), @@ -222,5 +230,8 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaDriftLendAndBorrowAPYTool(solanaKit), new SolanaDriftEntryQuoteOfPerpTradeTool(solanaKit), new SolanaDriftPerpMarketFundingRateTool(solanaKit), + new SolanaVoltrGetPositionValues(solanaKit), + new SolanaVoltrDepositStrategy(solanaKit), + new SolanaVoltrWithdrawStrategy(solanaKit), ]; } diff --git a/src/langchain/lulo/index.ts b/src/langchain/lulo/index.ts index f4ecf39..e31add1 100644 --- a/src/langchain/lulo/index.ts +++ b/src/langchain/lulo/index.ts @@ -1 +1,3 @@ export * from "./lend_asset"; +export * from "./lulo_lend"; +export * from "./lulo_withdraw"; diff --git a/src/langchain/lulo/lulo_lend.ts b/src/langchain/lulo/lulo_lend.ts new file mode 100644 index 0000000..0d5371e --- /dev/null +++ b/src/langchain/lulo/lulo_lend.ts @@ -0,0 +1,37 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaLuloLendTool extends Tool { + name = "solana_lulo_lend"; + description = `Lend token for yield using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP) + Inputs: + mintAddress: string, eg "So11111111111111111111111111111111111111112" (required) + amount: number, eg 1, 0.01 (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + const mintAddress = parsedInput.mintAddress + const amount = parsedInput.amount; + + const tx = await this.solanaKit.luloLend(mintAddress, amount); + + return JSON.stringify({ + status: "success", + message: "Asset lent successfully", + transaction: tx, + amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } + } \ No newline at end of file diff --git a/src/langchain/lulo/lulo_withdraw.ts b/src/langchain/lulo/lulo_withdraw.ts new file mode 100644 index 0000000..fe2671d --- /dev/null +++ b/src/langchain/lulo/lulo_withdraw.ts @@ -0,0 +1,37 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaLuloWithdrawTool extends Tool { + name = "solana_lulo_withdraw"; + description = `Withdraw token USDC using Lulo. (support USDC/PYUSD/USDS/USDT/SOL/jitoSOL/bSOL/mSOL/BONK/JUP) + Inputs (input is a json string): + mintAddress: string, eg "So11111111111111111111111111111111111111112" (required) + amount: number, eg 1, 0.01 (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + const mintAddress = parsedInput.mintAddress + const amount = parsedInput.amount; + + const tx = await this.solanaKit.luloWithdraw(mintAddress, amount); + + return JSON.stringify({ + status: "success", + message: "Asset withdraw successfully", + transaction: tx, + amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } + } \ No newline at end of file diff --git a/src/langchain/voltr/deposit_strategy.ts b/src/langchain/voltr/deposit_strategy.ts new file mode 100644 index 0000000..7342391 --- /dev/null +++ b/src/langchain/voltr/deposit_strategy.ts @@ -0,0 +1,39 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; +import { BN } from "bn.js"; + +export class SolanaVoltrDepositStrategy extends Tool { + name = "solana_voltr_deposit_strategy"; + description = `Deposit amount into a strategy for Voltr's vaults + + Inputs (input is a json string): + depositAmount: number (required) + vault: string (required) + strategy: string (required) + `; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + const tx = await this.solanaKit.voltrDepositStrategy( + new BN(inputFormat.depositAmount), + new PublicKey(inputFormat.vault), + new PublicKey(inputFormat.strategy), + ); + return JSON.stringify({ + status: "success", + message: `Deposited ${inputFormat.depositAmount} into strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`, + transaction: tx, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/voltr/get_position_values.ts b/src/langchain/voltr/get_position_values.ts new file mode 100644 index 0000000..697614f --- /dev/null +++ b/src/langchain/voltr/get_position_values.ts @@ -0,0 +1,18 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; + +export class SolanaVoltrGetPositionValues extends Tool { + name = "solana_voltr_get_position_values"; + description = `Get the total asset value and current value for each strategy of a given Voltr vault + + Inputs: + vault: string (required) + `; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { + return this.solanaKit.voltrGetPositionValues(new PublicKey(input)); + } +} diff --git a/src/langchain/voltr/index.ts b/src/langchain/voltr/index.ts new file mode 100644 index 0000000..b1e2a6e --- /dev/null +++ b/src/langchain/voltr/index.ts @@ -0,0 +1,3 @@ +export * from "./deposit_strategy"; +export * from "./withdraw_strategy"; +export * from "./get_position_values"; diff --git a/src/langchain/voltr/withdraw_strategy.ts b/src/langchain/voltr/withdraw_strategy.ts new file mode 100644 index 0000000..b8545b7 --- /dev/null +++ b/src/langchain/voltr/withdraw_strategy.ts @@ -0,0 +1,39 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; +import { BN } from "bn.js"; + +export class SolanaVoltrWithdrawStrategy extends Tool { + name = "solana_voltr_withdraw_strategy"; + description = `Withdraw amount from a strategy for Voltr's vaults + + Inputs (input is a json string): + withdrawAmount: number (required) + vault: string (required) + strategy: string (required) + `; + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + async _call(input: string): Promise { + try { + const inputFormat = JSON.parse(input); + const tx = await this.solanaKit.voltrWithdrawStrategy( + new BN(inputFormat.withdrawAmount), + new PublicKey(inputFormat.vault), + new PublicKey(inputFormat.strategy), + ); + return JSON.stringify({ + status: "success", + message: `Withdrew ${inputFormat.withdrawAmount} from strategy ${inputFormat.strategy} of vault ${inputFormat.vault} successfully`, + transaction: tx, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/tools/3land/create_3land_collectible.ts b/src/tools/3land/create_3land_collectible.ts index 29295ab..1a45b85 100644 --- a/src/tools/3land/create_3land_collectible.ts +++ b/src/tools/3land/create_3land_collectible.ts @@ -37,7 +37,8 @@ export async function createSingle( optionsWithBase58: StoreInitOptions, collectionAccount: string, createItemOptions: CreateSingleOptions, - isMainnet: boolean, + isMainnet: boolean = false, + withPool: boolean = false, ) { try { const landStore = isMainnet @@ -49,6 +50,8 @@ export async function createSingle( landStore, collectionAccount, createItemOptions, + true, //isAI + withPool, ); return singleEditionTx; } catch (error: any) { diff --git a/src/tools/index.ts b/src/tools/index.ts index e5646ad..b02c01c 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -25,3 +25,4 @@ export * from "./tiplink"; export * from "./lightprotocol"; export * from "./squads"; export * from "./helius"; +export * from "./voltr"; diff --git a/src/tools/lulo/index.ts b/src/tools/lulo/index.ts index a28ed36..2a9ad20 100644 --- a/src/tools/lulo/index.ts +++ b/src/tools/lulo/index.ts @@ -1 +1,3 @@ export * from "./lend"; +export * from "./lulo_lend"; +export * from "./lulo_withdraw"; diff --git a/src/tools/lulo/lulo_lend.ts b/src/tools/lulo/lulo_lend.ts new file mode 100644 index 0000000..ab4610c --- /dev/null +++ b/src/tools/lulo/lulo_lend.ts @@ -0,0 +1,64 @@ +import { VersionedTransaction } from "@solana/web3.js"; +import { SolanaAgentKit } from "../../index"; + +/** + * Lend tokens for yields using Lulo + * @param agent SolanaAgentKit instance + * @param mintAddress SPL Mint address + * @param amount Amount to lend + * @returns Transaction signature + */ +export async function luloLend( + agent: SolanaAgentKit, + mintAddress: string, + amount: number, +): Promise { + try { + const response = await fetch( + `https://api.flexlend.fi/generate/account/deposit?priorityFee=50000`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-wallet-pubkey": agent.wallet.publicKey.toBase58(), + "x-api-key": process.env.FLEXLEND_API_KEY! + }, + body: JSON.stringify({ + owner: agent.wallet.publicKey.toBase58(), + mintAddress: mintAddress, + depositAmount: amount.toString(), + }), + }, + ); + const { data: { transactionMeta } } = await response.json() + + // Deserialize the transaction + const luloTxn = VersionedTransaction.deserialize( + Buffer.from(transactionMeta[0].transaction, "base64"), + ); + + // Get a recent blockhash and set it + const { blockhash } = await agent.connection.getLatestBlockhash(); + luloTxn.message.recentBlockhash = blockhash; + + // Sign and send transaction + luloTxn.sign([agent.wallet]); + + const signature = await agent.connection.sendTransaction(luloTxn, { + preflightCommitment: "confirmed", + maxRetries: 3, + }); + + // Wait for confirmation using the latest strategy + const latestBlockhash = await agent.connection.getLatestBlockhash(); + await agent.connection.confirmTransaction({ + signature, + blockhash: latestBlockhash.blockhash, + lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, + }); + + return signature; + } catch (error: any) { + throw new Error(`Lending failed: ${error.message}`); + } +} diff --git a/src/tools/lulo/lulo_withdraw.ts b/src/tools/lulo/lulo_withdraw.ts new file mode 100644 index 0000000..cfc88b2 --- /dev/null +++ b/src/tools/lulo/lulo_withdraw.ts @@ -0,0 +1,69 @@ +import { VersionedTransaction } from "@solana/web3.js"; +import { SolanaAgentKit } from "../../index"; + +/** + * Withdraw tokens for yields using Lulo + * @param agent SolanaAgentKit instance + * @param mintAddress SPL Mint address + * @param amount Amount to withdraw + * @returns Transaction signature + */ +export async function luloWithdraw( + agent: SolanaAgentKit, + mintAddress: string, + amount: number, +): Promise { + try { + if (!agent.config.FLEXLEND_API_KEY) { + throw new Error("Lulo API key not found in agent configuration"); + } + + const response = await fetch( + `https://api.flexlend.fi/generate/account/withdraw?priorityFee=50000`, + { + method: "POST", + headers: { + "Content-Type": "application/json", + "x-wallet-pubkey": agent.wallet.publicKey.toBase58(), + "x-api-key": agent.config.FLEXLEND_API_KEY + }, + body: JSON.stringify({ + owner: agent.wallet.publicKey.toBase58(), + mintAddress: mintAddress, + depositAmount: amount, + }), + }, + ); + + const { data: { transactionMeta } } = await response.json() + + // Deserialize the transaction + const luloTxn = VersionedTransaction.deserialize( + Buffer.from(transactionMeta[0].transaction, "base64"), + ); + + // Get a recent blockhash and set it + const { blockhash } = await agent.connection.getLatestBlockhash(); + luloTxn.message.recentBlockhash = blockhash; + + // Sign and send transaction + luloTxn.sign([agent.wallet]); + + const signature = await agent.connection.sendTransaction(luloTxn, { + preflightCommitment: "confirmed", + maxRetries: 3, + }); + + // Wait for confirmation using the latest strategy + const latestBlockhash = await agent.connection.getLatestBlockhash(); + await agent.connection.confirmTransaction({ + signature, + blockhash: latestBlockhash.blockhash, + lastValidBlockHeight: latestBlockhash.lastValidBlockHeight, + }); + + return signature; + } catch (error: any) { + throw new Error(`Lending failed: ${error.message}`); + } +} diff --git a/src/tools/voltr/index.ts b/src/tools/voltr/index.ts new file mode 100644 index 0000000..328d565 --- /dev/null +++ b/src/tools/voltr/index.ts @@ -0,0 +1,3 @@ +export * from "./voltr_deposit_strategy"; +export * from "./voltr_withdraw_strategy"; +export * from "./voltr_get_position_values"; diff --git a/src/tools/voltr/voltr_deposit_strategy.ts b/src/tools/voltr/voltr_deposit_strategy.ts new file mode 100644 index 0000000..4da97ee --- /dev/null +++ b/src/tools/voltr/voltr_deposit_strategy.ts @@ -0,0 +1,99 @@ +import { TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID } from "@solana/spl-token"; +import { SolanaAgentKit } from "../../agent"; +import { + PublicKey, + sendAndConfirmTransaction, + Transaction, +} from "@solana/web3.js"; +import { VoltrClient } from "@voltr/vault-sdk"; +import BN from "bn.js"; + +/** + * Deposits assets into a Voltr strategy + * @param agent SolanaAgentKit instance + * @param depositAmount Amount to deposit in base units (BN) + * @param vault Public key of the target vault + * @param strategy Public key of the target strategy + * @returns Transaction signature for the deposit + */ +export async function voltrDepositStrategy( + agent: SolanaAgentKit, + depositAmount: BN, + vault: PublicKey, + strategy: PublicKey, +): Promise { + const vc = new VoltrClient(agent.connection, agent.wallet); + const vaultAccount = await vc.fetchVaultAccount(vault); + const vaultAssetMint = vaultAccount.asset.mint; + const assetTokenProgram = await agent.connection + .getAccountInfo(new PublicKey(vaultAssetMint)) + .then((account) => account?.owner); + + if ( + !assetTokenProgram || + !( + assetTokenProgram.equals(TOKEN_PROGRAM_ID) || + assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID) + ) + ) { + throw new Error("Invalid asset token program"); + } + + const response = await fetch( + `https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }, + ); + + const data = (await response.json()).data as { + instructionDiscriminator: number[] | null; + additionalArgs: number[] | null; + remainingAccounts: + | { + pubkey: string; + isSigner: boolean; + isWritable: boolean; + }[] + | null; + }; + + const additionalArgs = data.additionalArgs + ? Buffer.from(data.additionalArgs) + : null; + const instructionDiscriminator = data.instructionDiscriminator + ? Buffer.from(data.instructionDiscriminator) + : null; + const remainingAccounts = + data.remainingAccounts?.map((account) => ({ + pubkey: new PublicKey(account.pubkey), + isSigner: account.isSigner, + isWritable: account.isWritable, + })) ?? []; + + const depositIx = await vc.createDepositStrategyIx( + { + depositAmount, + additionalArgs, + instructionDiscriminator, + }, + { + vault, + vaultAssetMint, + strategy: strategy, + assetTokenProgram, + remainingAccounts, + }, + ); + + const transaction = new Transaction(); + transaction.add(depositIx); + + const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [ + agent.wallet, + ]); + return txSig; +} diff --git a/src/tools/voltr/voltr_get_position_values.ts b/src/tools/voltr/voltr_get_position_values.ts new file mode 100644 index 0000000..ca474da --- /dev/null +++ b/src/tools/voltr/voltr_get_position_values.ts @@ -0,0 +1,20 @@ +import { SolanaAgentKit } from "../../agent"; +import { PublicKey } from "@solana/web3.js"; +import { VoltrClient } from "@voltr/vault-sdk"; + +/** + * Gets the value of assets in a Voltr vault + * @param agent SolanaAgentKit instance + * @param vault Public key of the target vault + * @returns Position and total values for the vault + */ +export async function voltrGetPositionValues( + agent: SolanaAgentKit, + vault: PublicKey, +): Promise { + const vc = new VoltrClient(agent.connection, agent.wallet); + const positionAndTotalValues = + await vc.getPositionAndTotalValuesForVault(vault); + + return JSON.stringify(positionAndTotalValues); +} diff --git a/src/tools/voltr/voltr_withdraw_strategy.ts b/src/tools/voltr/voltr_withdraw_strategy.ts new file mode 100644 index 0000000..bcc4fc7 --- /dev/null +++ b/src/tools/voltr/voltr_withdraw_strategy.ts @@ -0,0 +1,99 @@ +import { SolanaAgentKit } from "../../agent"; +import { + PublicKey, + sendAndConfirmTransaction, + Transaction, +} from "@solana/web3.js"; +import BN from "bn.js"; +import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from "@solana/spl-token"; +import { VoltrClient } from "@voltr/vault-sdk"; + +/** + * Withdraws assets from a Voltr strategy + * @param agent SolanaAgentKit instance + * @param withdrawAmount Amount to withdraw in base units (BN) + * @param vault Public key of the target vault + * @param strategy Public key of the target strategy + * @returns Transaction signature for the deposit + */ +export async function voltrWithdrawStrategy( + agent: SolanaAgentKit, + withdrawAmount: BN, + vault: PublicKey, + strategy: PublicKey, +): Promise { + const vc = new VoltrClient(agent.connection, agent.wallet); + const vaultAccount = await vc.fetchVaultAccount(vault); + const vaultAssetMint = vaultAccount.asset.mint; + const assetTokenProgram = await agent.connection + .getAccountInfo(new PublicKey(vaultAssetMint)) + .then((account) => account?.owner); + + if ( + !assetTokenProgram || + !( + assetTokenProgram.equals(TOKEN_PROGRAM_ID) || + assetTokenProgram.equals(TOKEN_2022_PROGRAM_ID) + ) + ) { + throw new Error("Invalid asset token program"); + } + + const response = await fetch( + `https://voltr.xyz/api/remaining-accounts/deposit-strategy?vault=${vault.toBase58()}&strategy=${strategy.toBase58()}`, + { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }, + ); + + const data = (await response.json()).data as { + instructionDiscriminator: number[] | null; + additionalArgs: number[] | null; + remainingAccounts: + | { + pubkey: string; + isSigner: boolean; + isWritable: boolean; + }[] + | null; + }; + + const additionalArgs = data.additionalArgs + ? Buffer.from(data.additionalArgs) + : null; + const instructionDiscriminator = data.instructionDiscriminator + ? Buffer.from(data.instructionDiscriminator) + : null; + const remainingAccounts = + data.remainingAccounts?.map((account) => ({ + pubkey: new PublicKey(account.pubkey), + isSigner: account.isSigner, + isWritable: account.isWritable, + })) ?? []; + + const withdrawIx = await vc.createWithdrawStrategyIx( + { + withdrawAmount, + additionalArgs, + instructionDiscriminator, + }, + { + vault, + vaultAssetMint, + strategy, + assetTokenProgram, + remainingAccounts, + }, + ); + + const transaction = new Transaction(); + transaction.add(withdrawIx); + + const txSig = await sendAndConfirmTransaction(agent.connection, transaction, [ + agent.wallet, + ]); + return txSig; +} diff --git a/src/types/index.ts b/src/types/index.ts index 2c0a54c..a2a07bd 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -7,6 +7,7 @@ export interface Config { JUPITER_REFERRAL_ACCOUNT?: string; JUPITER_FEE_BPS?: number; FLASH_PRIVILEGE?: string; + FLEXLEND_API_KEY?: string; HELIUS_API_KEY?: string; } diff --git a/test/tools/3land.ts b/test/tools/3land.ts index aadc634..3e4c0f7 100644 --- a/test/tools/3land.ts +++ b/test/tools/3land.ts @@ -13,10 +13,7 @@ const agent = new SolanaAgentKit( { OPENAI_API_KEY: process.env.OPENAI_API_KEY! }, ); -const optionsWithBase58: StoreInitOptions = { - privateKey: process.env.SOLANA_PRIVATE_KEY!, - isMainnet: false, -}; +const isDevnet = true; /****************************** CREATING COLLECTION ******************************** */ @@ -29,8 +26,8 @@ const collectionOpts: CreateCollectionOptions = { (async () => { const collection = await agent.create3LandCollection( - optionsWithBase58, collectionOpts, + isDevnet, ); console.log("collection: ", collection); @@ -41,21 +38,24 @@ const collectionAccount = ""; const createItemOptions: CreateSingleOptions = { itemName: "", sellerFee: 500, //5% - itemAmount: 100, + itemAmount: 333, itemSymbol: "", itemDescription: "", traits: [{ trait_type: "", value: "" }], - price: 0, //100000000 == 0.1 sol + price: 100000000, //100000000 == 0.1 sol, + splHash: "", + poolName: "", mainImageUrl: "", }; -const isMainnet = false; +const withPool = true; + (async () => { const result = agent.create3LandNft( - optionsWithBase58, collectionAccount, createItemOptions, - isMainnet, + isDevnet, + withPool, ); console.log("result: ", result); })();