diff --git a/package.json b/package.json index c6216969..6f21db8b 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,8 @@ "@metaplex-foundation/mpl-toolbox": "^0.9.4", "@metaplex-foundation/umi": "^0.9.2", "@metaplex-foundation/umi-bundle-defaults": "^0.9.2", + "@metaplex-foundation/umi-options": "^1.0.0", + "@metaplex-foundation/umi-uploader-irys": "^1.0.0", "@metaplex-foundation/umi-web3js-adapters": "^0.9.2", "@meteora-ag/alpha-vault": "^1.1.7", "@meteora-ag/dlmm": "^1.3.0", @@ -63,6 +65,7 @@ "@pythnetwork/hermes-client": "^1.3.0", "@raydium-io/raydium-sdk-v2": "0.1.95-alpha", "@solana/spl-token": "^0.4.9", + "@solana/spl-token-metadata": "^0.1.6", "@solana/web3.js": "^1.98.0", "@solutiofi/sdk": "^1.0.2", "@sqds/multisig": "^2.1.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7a16a5de..a5fa3206 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -74,6 +74,12 @@ importers: '@metaplex-foundation/umi-bundle-defaults': specifier: ^0.9.2 version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metaplex-foundation/umi-options': + specifier: ^1.0.0 + version: 1.0.0 + '@metaplex-foundation/umi-uploader-irys': + specifier: ^1.0.0 + version: 1.0.0(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) '@metaplex-foundation/umi-web3js-adapters': specifier: ^0.9.2 version: 0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -104,6 +110,9 @@ importers: '@solana/spl-token': specifier: ^0.4.9 version: 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/spl-token-metadata': + specifier: ^0.1.6 + version: 0.1.6(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2) '@solana/web3.js': specifier: ^1.98.0 version: 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) @@ -693,6 +702,9 @@ packages: '@irys/arweave@0.0.2': resolution: {integrity: sha512-ddE5h4qXbl0xfGlxrtBIwzflaxZUDlDs43TuT0u1OMfyobHul4AA1VEX72Rpzw2bOh4vzoytSqA1jCM7x9YtHg==} + '@irys/bundles@0.0.1': + resolution: {integrity: sha512-yeQNzElERksFbfbNxJQsMkhtkI3+tNqIMZ/Wwxh76NVBmCnCP5huefOv7ET0MOO7TEQL+TqvKSqmFklYSvTyHw==} + '@irys/query@0.0.1': resolution: {integrity: sha512-7TCyR+Qn+F54IQQx5PlERgqNwgIQik8hY55iZl/silTHhCo1MI2pvx5BozqPUVCc8/KqRsc2nZd8Bc29XGUjRQ==} engines: {node: '>=16.10.0'} @@ -701,6 +713,10 @@ packages: resolution: {integrity: sha512-J8zCZDos2vFogSbroCJHZJq5gnPZEal01Iy3duXAotjIMgrI2ElDANiqEbaP1JAImR1jdUo1ChJnZB7MRLN9Hw==} engines: {node: '>=16.10.0'} + '@irys/query@0.0.9': + resolution: {integrity: sha512-uBIy8qeOQupUSBzR+1KU02JJXFp5Ue9l810PIbBF/ylUB8RTreUFkyyABZ7J3FUaOIXFYrT7WVFSJSzXM7P+8w==} + engines: {node: '>=16.10.0'} + '@irys/sdk@0.0.2': resolution: {integrity: sha512-un/e/CmTpgT042gDwCN3AtISrR9OYGMY6V+442pFmSWKrwrsDoIXZ8VlLiYKnrtTm+yquGhjfYy0LDqGWq41pA==} engines: {node: '>=16.10.0'} @@ -713,6 +729,21 @@ packages: deprecated: 'Arweave support is deprecated - We recommend migrating to the Irys datachain: https://migrate-to.irys.xyz/' hasBin: true + '@irys/upload-core@0.0.9': + resolution: {integrity: sha512-Ha4pX8jgYBA3dg5KHDPk+Am0QO+SmvnmgCwKa6uiDXZKuVr0neSx4V1OAHoP+As+j7yYgfChdsdrvsNzZGGehA==} + + '@irys/upload-solana@0.1.7': + resolution: {integrity: sha512-gHrEA6fCN2cEpBLM+urHRd0SeHcx6aOpNHPPeDS64tHXORrz4dU8F+OxWyy9wsCQNQd/wzrZldu/qncvcqkv6g==} + + '@irys/upload@0.0.14': + resolution: {integrity: sha512-6XdkyS5cVINcPjv1MzA6jDsawfG7Bw6sq5wilNx5B4X7nNotBPC3SuRrZs06G/0BTUj15W+TRO/tZTDWRUfZzA==} + + '@irys/web-upload-solana@0.1.7': + resolution: {integrity: sha512-LNNhdSdz4u/MXNxkXHS6iPuMB4wqgVBQwK3sKbJPXUMLrb961FNwyJ3S6N2BJmf8jpsQvjd0QoMRp8isxKizSg==} + + '@irys/web-upload@0.0.14': + resolution: {integrity: sha512-vBIslG2KSGyeJjZNTbSvLmGO/bbHS1jcDkD0A1aLgx7xkiTpfdbXOrn4hznPkzQhPtluX4aL44On0GXrEcD8eQ==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -930,6 +961,9 @@ packages: '@metaplex-foundation/umi-options@0.8.9': resolution: {integrity: sha512-jSQ61sZMPSAk/TXn8v8fPqtz3x8d0/blVZXLLbpVbo2/T5XobiI6/MfmlUosAjAUaQl6bHRF8aIIqZEFkJiy4A==} + '@metaplex-foundation/umi-options@1.0.0': + resolution: {integrity: sha512-DhfwrXTsvOrDwPGT5FpzC7VooLGMRjUSBV8W9xkp+WMxkzbNXeUV+bFmoTNx+0ynLhINp6Ij76W/Rl+4dIwU0w==} + '@metaplex-foundation/umi-program-repository@0.9.2': resolution: {integrity: sha512-g3+FPqXEmYsBa8eETtUE2gb2Oe3mqac0z3/Ur1TvAg5TtIy3mzRzOy/nza+sgzejnfcxcVg835rmpBaxpBnjDA==} peerDependencies: @@ -972,12 +1006,24 @@ packages: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-uploader-irys@1.0.0': + resolution: {integrity: sha512-EMTjAdA78ng3/urO3A27jWjMuK5Isohs+6eovgHypeQ8pHmtDH6634m8fonsENVFW/VDuGIzBZ6GKJcBUdI+Jg==} + peerDependencies: + '@metaplex-foundation/umi': ^1.0.0 + '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-web3js-adapters@0.9.2': resolution: {integrity: sha512-RQqUTtHYY9fmEMnq7s3Hiv/81flGaoI0ZVVoafnFVaQLnxU6QBKxtboRZHk43XtD9CiFh5f9izrMJX7iK7KlOA==} peerDependencies: '@metaplex-foundation/umi': ^0.9.2 '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi-web3js-adapters@1.0.0': + resolution: {integrity: sha512-daAuxorWSwF3cOWz9UjlYKlgGVM6eTw7cbLKyj8Sk90umxv5sfMZR5CjmaILHsXz5uaYIcjoivabSngucp4xNA==} + peerDependencies: + '@metaplex-foundation/umi': ^1.0.0 + '@solana/web3.js': ^1.72.0 + '@metaplex-foundation/umi@0.9.2': resolution: {integrity: sha512-9i4Acm4pruQfJcpRrc2EauPBwkfDN0I9QTvJyZocIlKgoZwD6A6wH0PViH1AjOVG5CQCd1YI3tJd5XjYE1ElBw==} @@ -2262,9 +2308,15 @@ packages: csv-parse@4.16.3: resolution: {integrity: sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg==} + csv-parse@5.6.0: + resolution: {integrity: sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==} + csv-stringify@5.6.5: resolution: {integrity: sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A==} + csv-stringify@6.5.2: + resolution: {integrity: sha512-RFPahj0sXcmUyjrObAK+DOWtMvMIFV328n4qZJhgX3x2RqkQgOTU2mCUmiFR0CzM6AzChlRSUErjiJeEt8BaQA==} + csv@5.5.3: resolution: {integrity: sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g==} engines: {node: '>= 0.1.90'} @@ -5770,6 +5822,33 @@ snapshots: transitivePeerDependencies: - debug + '@irys/bundles@0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/providers': 5.7.2(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wallet': 5.7.0 + '@irys/arweave': 0.0.2 + '@noble/ed25519': 1.7.3 + base64url: 3.0.1 + bs58: 4.0.1 + keccak: 3.0.4 + secp256k1: 5.0.1 + optionalDependencies: + '@randlabs/myalgo-connect': 1.4.2 + algosdk: 1.24.1 + arweave-stream-tx: 1.2.2(arweave@1.15.5) + multistream: 4.1.0 + tmp-promise: 3.0.3 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - utf-8-validate + '@irys/query@0.0.1(debug@4.4.0)': dependencies: async-retry: 1.3.3 @@ -5784,6 +5863,13 @@ snapshots: transitivePeerDependencies: - debug + '@irys/query@0.0.9': + dependencies: + async-retry: 1.3.3 + axios: 1.7.9 + transitivePeerDependencies: + - debug + '@irys/sdk@0.0.2(arweave@1.15.5)(bufferutil@4.0.9)(debug@4.4.0)(utf-8-validate@5.0.10)': dependencies: '@ethersproject/bignumber': 5.7.0 @@ -5853,6 +5939,97 @@ snapshots: - encoding - utf-8-validate + '@irys/upload-core@0.0.9(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@irys/bundles': 0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/query': 0.0.9 + '@supercharge/promise-pool': 3.2.0 + async-retry: 1.3.3 + axios: 1.7.9 + base64url: 3.0.1 + bignumber.js: 9.1.2 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - utf-8-validate + + '@irys/upload-solana@0.1.7(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': + dependencies: + '@irys/bundles': 0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload': 0.0.14(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload-core': 0.0.9(arweave@1.15.5)(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) + async-retry: 1.3.3 + bignumber.js: 9.1.2 + bs58: 5.0.0 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + '@irys/upload@0.0.14(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@irys/bundles': 0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload-core': 0.0.9(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + async-retry: 1.3.3 + axios: 1.7.9 + base64url: 3.0.1 + bignumber.js: 9.1.2 + csv-parse: 5.6.0 + csv-stringify: 6.5.2 + inquirer: 8.2.6 + mime-types: 2.1.35 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - utf-8-validate + + '@irys/web-upload-solana@0.1.7(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': + dependencies: + '@irys/bundles': 0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload-core': 0.0.9(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/web-upload': 0.0.14(arweave@1.15.5)(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) + async-retry: 1.3.3 + bignumber.js: 9.1.2 + bs58: 5.0.0 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + + '@irys/web-upload@0.0.14(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@irys/bundles': 0.0.1(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload-core': 0.0.9(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + async-retry: 1.3.3 + axios: 1.7.9 + base64url: 3.0.1 + bignumber.js: 9.1.2 + mime-types: 2.1.35 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - utf-8-validate + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -6452,6 +6629,8 @@ snapshots: '@metaplex-foundation/umi-options@0.8.9': {} + '@metaplex-foundation/umi-options@1.0.0': {} + '@metaplex-foundation/umi-program-repository@0.9.2(@metaplex-foundation/umi@0.9.2)': dependencies: '@metaplex-foundation/umi': 0.9.2 @@ -6498,12 +6677,39 @@ snapshots: '@metaplex-foundation/umi-web3js-adapters': 0.9.2(@metaplex-foundation/umi@0.9.2)(@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) + '@metaplex-foundation/umi-uploader-irys@1.0.0(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10)': + dependencies: + '@irys/upload': 0.0.14(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/upload-solana': 0.1.7(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) + '@irys/web-upload': 0.0.14(arweave@1.15.5)(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@irys/web-upload-solana': 0.1.7(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.7.2)(utf-8-validate@5.0.10) + '@metaplex-foundation/umi': 0.9.2 + '@metaplex-foundation/umi-web3js-adapters': 1.0.0(@metaplex-foundation/umi@0.9.2)(@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) + '@supercharge/promise-pool': 3.2.0 + bignumber.js: 9.1.2 + buffer: 6.0.3 + transitivePeerDependencies: + - arweave + - bufferutil + - debug + - encoding + - fastestsmallesttextencoderdecoder + - typescript + - utf-8-validate + '@metaplex-foundation/umi-web3js-adapters@0.9.2(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: '@metaplex-foundation/umi': 0.9.2 '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) buffer: 6.0.3 + '@metaplex-foundation/umi-web3js-adapters@1.0.0(@metaplex-foundation/umi@0.9.2)(@solana/web3.js@1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@metaplex-foundation/umi': 0.9.2 + '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + buffer: 6.0.3 + '@metaplex-foundation/umi@0.9.2': dependencies: '@metaplex-foundation/umi-options': 0.8.9 @@ -8860,8 +9066,12 @@ snapshots: csv-parse@4.16.3: {} + csv-parse@5.6.0: {} + csv-stringify@5.6.5: {} + csv-stringify@6.5.2: {} + csv@5.5.3: dependencies: csv-generate: 3.4.3 diff --git a/src/actions/fluxbeam/createPool.ts b/src/actions/fluxbeam/createPool.ts new file mode 100644 index 00000000..c1816739 --- /dev/null +++ b/src/actions/fluxbeam/createPool.ts @@ -0,0 +1,120 @@ +import { PublicKey } from "@solana/web3.js"; +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { fluxBeamCreatePool } from "../../tools"; + +const fluxbeamCreatePoolAction: Action = { + name: "FLUXBEAM_CREATE_POOL_ACTION", + similes: [ + "create fluxbeam liquidity pool", + "start fluxbeam pool", + "initialize pool", + "create new fluxbeam trading pool", + "setup fluxbeam token pool", + "add new pool to fluxbeam", + "create token pair pool on fluxbeam", + ], + description: `Creates a new liquidity pool on Fluxbeam with two tokens. + Specify the token addresses and initial amounts to provide liquidity.`, + examples: [ + [ + { + input: { + token_a: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + token_a_amount: 5, + token_b: "So11111111111111111111111111111111111111112", + token_b_amount: 5000, + }, + output: { + status: "success", + message: "Pool created successfully on FluxBeam", + transaction: + "4KvgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7", + token_a: "SOL", + token_a_amount: 5, + token_b: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + token_b_amount: 5000, + }, + explanation: "Create a new USDC-SOL pool with 5 SOL and 5000 USDC", + }, + ], + [ + { + input: { + tokenA: "USDC", + tokenAamount: 5, + tokenB: "SOL", + tokenBamount: 5000, + }, + output: { + status: "success", + message: "Pool created successfully on FluxBeam", + transaction: + "4KvgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7", + tokenA: "SOL", + tokenAamount: 5, + tokenB: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + tokenBamount: 5000, + }, + explanation: "Create a new USDC-SOL pool with 5 SOL and 5000 USDC", + }, + ], + [ + { + input: { + token_a: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + token_a_amount: 5, + token_b: "So11111111111111111111111111111111111111112", + token_b_amount: 5000, + }, + output: { + status: "success", + message: "Pool created successfully on FluxBeam", + transaction: + "4KvgJ5vVZxUxefDGqzqkVLHzHxVTyYH9StYyHKgvHYmXJgqJKxEqy9k4Rz9LpXrHF9kUZB7", + token_a: "SOL", + token_a_amount: 5, + token_b: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", + token_b_amount: 5000, + }, + explanation: "Create a new USDC-SOL pool with 5 SOL and 5000 USDC", + }, + ], + ], + schema: z.object({ + tokenA: z.string(), + tokenAamount: z.number().positive("Token A amount must be positive"), + tokenB: z.string(), + tokenBamount: z.number().positive("Token B amount must be positive"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + try { + const txSignature = await fluxBeamCreatePool( + agent, + new PublicKey(input.tokenA), + input.token_a_amount, + new PublicKey(input.tokenB), + input.token_b_amount, + ); + + return { + status: "success", + message: "Pool created successfully on FluxBeam", + tx: txSignature, + token_a: input.token_a, + token_a_amount: input.token_a_amount, + token_b: input.token_b, + token_b_amount: input.token_b_amount, + }; + } catch (error: any) { + return { + status: "error", + message: `FluxBeam pool creation failed: ${error.message}`, + error: error.message, + }; + } + }, +}; + +export default fluxbeamCreatePoolAction; diff --git a/src/actions/index.ts b/src/actions/index.ts index 13496e6e..899f4f54 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -33,6 +33,7 @@ import launchPumpfunTokenAction from "./pumpfun/launchPumpfunToken"; import getWalletAddressAction from "./agent/getWalletAddress"; import flashOpenTradeAction from "./flash/flashOpenTrade"; import flashCloseTradeAction from "./flash/flashCloseTrade"; +import fluxbeamCreatePoolAction from "./fluxbeam/createPool"; import createMultisigAction from "./squads/createMultisig"; import approveMultisigProposalAction from "./squads/approveMultisigProposal"; import createMultisigProposalAction from "./squads/createMultisigProposal"; @@ -135,6 +136,7 @@ export const ACTIONS = { LAUNCH_PUMPFUN_TOKEN_ACTION: launchPumpfunTokenAction, FLASH_OPEN_TRADE_ACTION: flashOpenTradeAction, FLASH_CLOSE_TRADE_ACTION: flashCloseTradeAction, + FLUXBEAM_CREATE_POOL_ACTION: fluxbeamCreatePoolAction, CREATE_MULTISIG_ACTION: createMultisigAction, DEPOSIT_TO_MULTISIG_ACTION: depositToMultisigAction, TRANSFER_FROM_MULTISIG_ACTION: transferFromMultisigAction, diff --git a/src/agent/index.ts b/src/agent/index.ts index c8fc50f7..96813b8e 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -126,10 +126,10 @@ import { burnTokens, mergeTokens, spreadToken, - AssetType, PriorityFee, TargetTokenStruct, InputAssetStruct, + fluxBeamCreatePool, } from "../tools"; import { Config, @@ -152,7 +152,6 @@ import { DasApiAssetList, GetAssetsByAuthorityRpcInput, GetAssetsByCreatorRpcInput, - SearchAssetsRpcInput, } from "@metaplex-foundation/digital-asset-standard-api"; import { AlloraInference, AlloraTopic } from "@alloralabs/allora-sdk"; @@ -1107,4 +1106,18 @@ export class SolanaAgentKit { ): Promise { return simulate_switchboard_feed(this, feed, crossbarUrl); } + async fluxbeamCreatePool( + token_a: PublicKey, + token_a_amount: number, + token_b: PublicKey, + token_b_amount: number, + ): Promise { + return fluxBeamCreatePool( + this, + token_a, + token_a_amount, + token_b, + token_b_amount, + ); + } } diff --git a/src/constants/index.ts b/src/constants/index.ts index a961e611..0185ec0b 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -53,3 +53,15 @@ export const MINIMUM_COMPUTE_PRICE_FOR_COMPLEX_ACTIONS = * https://docs.switchboard.xyz/docs/switchboard/crossbar-and-task-runner */ export const SWITCHBOARD_DEFAULT_CROSSBAR = "https://crossbar.switchboard.xyz"; +/** + * Fluxbeam constants + */ +// fluxbeam fee account +export const FEE_ACCOUNT = new PublicKey( + "FLUXR4McuD2iXyP3wpP4XTjSWmB86ppMiyoA52UA9bKb", +); + +export const FLUXBEAM_BASE_URI = "https://api.fluxbeam.xyz/v1"; +export const FLUXBEAM_SWAP_PROGRAM_ID = new PublicKey( + "FLUXubRmkEi2q6K3Y9kBPg9248ggaZVsoSFhtJHSrm1X", +); diff --git a/src/langchain/fluxbeam/create_pool.ts b/src/langchain/fluxbeam/create_pool.ts new file mode 100644 index 00000000..aa408b94 --- /dev/null +++ b/src/langchain/fluxbeam/create_pool.ts @@ -0,0 +1,47 @@ +import { PublicKey } from "@solana/web3.js"; +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaFluxbeamCreatePoolTool extends Tool { + name = "fluxbeam_create_pool"; + description = `This tool can be used to create a new token pool using FluxBeam. + + Inputs (input is a JSON string): + token_a: string, eg "So11111111111111111111111111111111111111112" (required) + token_a_amount: number, eg 100 or 0.1 (required) + token_b: string, eg "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263" (required) + token_b_amount: number, eg 200 or 0.2 (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const signature = await this.solanaKit.fluxbeamCreatePool( + new PublicKey(parsedInput.token_a), + parsedInput.token_a_amount, + new PublicKey(parsedInput.token_b), + parsedInput.token_b_amount, + ); + + return JSON.stringify({ + status: "success", + message: "Token pool created successfully", + transaction: signature, + token_a: parsedInput.token_a, + token_a_amount: parsedInput.token_a_amount, + token_b: parsedInput.token_b, + token_b_amount: parsedInput.token_b_amount, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/fluxbeam/index.ts b/src/langchain/fluxbeam/index.ts new file mode 100644 index 00000000..108b29fd --- /dev/null +++ b/src/langchain/fluxbeam/index.ts @@ -0,0 +1 @@ +export * from "./create_pool"; diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 798de7f3..b2f85b6a 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -32,7 +32,7 @@ export * from "./mayan"; export * from "./allora"; export * from "./solutiofi"; export * from "./switchboard"; - +export * from "./fluxbeam"; import type { SolanaAgentKit } from "../agent"; import { SolanaBalanceTool, @@ -147,6 +147,7 @@ import { SolanaMergeTokensTool, SolanaSpreadTokenTool, SolanaSwitchboardSimulateFeed, + SolanaFluxbeamCreatePoolTool, } from "./index"; export function createSolanaTools(solanaKit: SolanaAgentKit) { @@ -263,5 +264,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaMergeTokensTool(solanaKit), new SolanaSpreadTokenTool(solanaKit), new SolanaAlloraGetPriceInference(solanaKit), + new SolanaFluxbeamCreatePoolTool(solanaKit), ]; } diff --git a/src/langchain/solana/balance_other.ts b/src/langchain/solana/balance_other.ts index c29f7f1a..7c0741bd 100644 --- a/src/langchain/solana/balance_other.ts +++ b/src/langchain/solana/balance_other.ts @@ -19,7 +19,6 @@ export class SolanaBalanceOtherTool extends Tool { protected async _call(input: string): Promise { try { const { walletAddress, tokenAddress } = JSON.parse(input); - const tokenPubKey = tokenAddress ? new PublicKey(tokenAddress) : undefined; diff --git a/src/tools/fluxbeam/fluxbeam_create_pool.ts b/src/tools/fluxbeam/fluxbeam_create_pool.ts new file mode 100644 index 00000000..f918207b --- /dev/null +++ b/src/tools/fluxbeam/fluxbeam_create_pool.ts @@ -0,0 +1,73 @@ +import { VersionedTransaction, PublicKey } from "@solana/web3.js"; +import { SolanaAgentKit } from "../../index"; +import { FLUXBEAM_BASE_URI, TOKENS } from "../../constants"; +import { getTokenDecimals } from "../../utils/FluxbeamUtils"; + +/** + * Create a new pool using FluxBeam + * @param agent SolanaAgentKit instance + * @param token_a token mint address of the first token + * @param token_a_amount Amount to swap (in token decimals) + * @param token_b Source token mint address (defaults to USDC) + * @param token_b_amount Source token mint address (defaults to USDC) + * @param slippageBps Slippage tolerance in basis points (default: 300 = 3%) + * @returns Transaction signature + */ + +export async function fluxBeamCreatePool( + agent: SolanaAgentKit, + token_a: PublicKey, + token_a_amount: number, + token_b: PublicKey, + token_b_amount: number, +): Promise { + try { + const isTokenA_NativeSol = token_a.equals(TOKENS.SOL); + const tokenA_Decimals = isTokenA_NativeSol + ? 9 + : await getTokenDecimals(agent, token_a); + + const scaledAmountTokenA = token_a_amount * Math.pow(10, tokenA_Decimals); + const isTokenB_NativeSol = token_b.equals(TOKENS.SOL); + const tokenB_Decimals = isTokenB_NativeSol + ? 9 + : await getTokenDecimals(agent, token_b); + + const scaledAmountTokenB = token_b_amount * Math.pow(10, tokenB_Decimals); + const response = await ( + await fetch(`${FLUXBEAM_BASE_URI}/token_pools`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + payer: agent.wallet_address, + token_a: token_a, + token_b: token_b, + token_a_amount: scaledAmountTokenA, + token_b_amount: scaledAmountTokenB, + }), + }) + ).json(); + if (response.error) { + throw new Error(response.error); + } + // Deserialize transaction + const TransactionBuf = Buffer.from(response.transaction, "base64"); + + const transaction = VersionedTransaction.deserialize(TransactionBuf); + // Sign and send transaction + transaction.sign([agent.wallet]); + + const signature = await agent.connection.sendRawTransaction( + transaction.serialize(), + { + maxRetries: 3, + skipPreflight: true, + }, + ); + return signature; + } catch (error: any) { + throw new Error(`Failed to create fluxbeam pool: ${error.message}`); + } +} diff --git a/src/tools/fluxbeam/index.ts b/src/tools/fluxbeam/index.ts new file mode 100644 index 00000000..76c8696a --- /dev/null +++ b/src/tools/fluxbeam/index.ts @@ -0,0 +1 @@ +export * from "./fluxbeam_create_pool"; diff --git a/src/tools/index.ts b/src/tools/index.ts index e354bfcf..2b59052f 100644 --- a/src/tools/index.ts +++ b/src/tools/index.ts @@ -31,3 +31,4 @@ export * from "./mayan"; export * from "./allora"; export * from "./solutiofi"; export * from "./switchboard"; +export * from "./fluxbeam"; diff --git a/src/types/index.ts b/src/types/index.ts index 6329bbbf..a52fe912 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -301,3 +301,21 @@ export interface SwitchboardSimulateFeedResponse { message?: string; code?: string; } + +export interface FluxbeamServerResponse { + signature: string; +} + +export interface Quote { + amountIn: number; + inputMint: string; + minimumOut: number; + outAmount: number; + outputMint: string; + pool: string; + program: string; +} + +export interface TransformedResponse { + quote: Quote; +} diff --git a/src/utils/FluxbeamUtils.ts b/src/utils/FluxbeamUtils.ts new file mode 100644 index 00000000..241d7419 --- /dev/null +++ b/src/utils/FluxbeamUtils.ts @@ -0,0 +1,34 @@ +import { PublicKey } from "@solana/web3.js"; +import { SolanaAgentKit } from "../agent"; +import { + getMint, + TOKEN_PROGRAM_ID, + TOKEN_2022_PROGRAM_ID, +} from "@solana/spl-token"; + +// handles the case where a token in the pool is a token 2022 token +export async function getTokenDecimals( + agent: SolanaAgentKit, + mint: PublicKey, +): Promise { + try { + return ( + await getMint(agent.connection, mint, "finalized", TOKEN_PROGRAM_ID) + ).decimals; + } catch (error) { + try { + return ( + await getMint( + agent.connection, + mint, + "finalized", + TOKEN_2022_PROGRAM_ID, + ) + ).decimals; + } catch (finalError: any) { + throw new Error( + `Failed to fetch mint info for token ${mint.toBase58()}: ${finalError.message}`, + ); + } + } +}