added write functionalities ie, swap and transfer

This commit is contained in:
Deepak
2024-12-27 16:53:12 +05:30
parent ab9259d4e2
commit 3cdd45d623
13 changed files with 572 additions and 17 deletions

View File

@@ -6,7 +6,7 @@
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "node --loader ts-node/esm"
"dev": "tsx"
},
"keywords": [],
"author": "",
@@ -16,10 +16,12 @@
"@langchain/core": "^0.3.26",
"@langchain/langgraph": "^0.2.36",
"dotenv": "^16.4.7",
"solana-agent-kit": "^1.3.0"
"solana-agent-kit": "^1.3.0",
"zod": "^3.24.1"
},
"devDependencies": {
"ts-node": "^10.9.2",
"tsx": "^4.19.2",
"typescript": "^5.0.0"
},
"ts-node": {

View File

@@ -10,7 +10,7 @@ importers:
dependencies:
'@langchain/community':
specifier: ^0.3.20
version: 0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))
version: 0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))
'@langchain/core':
specifier: ^0.3.26
version: 0.3.26(openai@4.77.0(zod@3.24.1))
@@ -23,10 +23,16 @@ importers:
solana-agent-kit:
specifier: ^1.3.0
version: 1.3.0(@noble/hashes@1.6.1)(axios@1.7.4)(borsh@2.0.0)(buffer@6.0.3)(bufferutil@4.0.8)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)(zod@3.24.1)
zod:
specifier: ^3.24.1
version: 3.24.1
devDependencies:
ts-node:
specifier: ^10.9.2
version: 10.9.2(@types/node@18.19.68)(typescript@5.6.3)
tsx:
specifier: ^4.19.2
version: 4.19.2
typescript:
specifier: ^5.0.0
version: 5.6.3
@@ -82,6 +88,150 @@ packages:
'@emnapi/runtime@1.3.1':
resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
'@esbuild/aix-ppc64@0.23.1':
resolution: {integrity: sha512-6VhYk1diRqrhBAqpJEdjASR/+WVRtfjpqKuNw11cLiaWpAT/Uu+nokB+UJnevzy/P9C/ty6AOe0dwueMrGh/iQ==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [aix]
'@esbuild/android-arm64@0.23.1':
resolution: {integrity: sha512-xw50ipykXcLstLeWH7WRdQuysJqejuAGPd30vd1i5zSyKK3WE+ijzHmLKxdiCMtH1pHz78rOg0BKSYOSB/2Khw==}
engines: {node: '>=18'}
cpu: [arm64]
os: [android]
'@esbuild/android-arm@0.23.1':
resolution: {integrity: sha512-uz6/tEy2IFm9RYOyvKl88zdzZfwEfKZmnX9Cj1BHjeSGNuGLuMD1kR8y5bteYmwqKm1tj8m4cb/aKEorr6fHWQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [android]
'@esbuild/android-x64@0.23.1':
resolution: {integrity: sha512-nlN9B69St9BwUoB+jkyU090bru8L0NA3yFvAd7k8dNsVH8bi9a8cUAUSEcEEgTp2z3dbEDGJGfP6VUnkQnlReg==}
engines: {node: '>=18'}
cpu: [x64]
os: [android]
'@esbuild/darwin-arm64@0.23.1':
resolution: {integrity: sha512-YsS2e3Wtgnw7Wq53XXBLcV6JhRsEq8hkfg91ESVadIrzr9wO6jJDMZnCQbHm1Guc5t/CdDiFSSfWP58FNuvT3Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [darwin]
'@esbuild/darwin-x64@0.23.1':
resolution: {integrity: sha512-aClqdgTDVPSEGgoCS8QDG37Gu8yc9lTHNAQlsztQ6ENetKEO//b8y31MMu2ZaPbn4kVsIABzVLXYLhCGekGDqw==}
engines: {node: '>=18'}
cpu: [x64]
os: [darwin]
'@esbuild/freebsd-arm64@0.23.1':
resolution: {integrity: sha512-h1k6yS8/pN/NHlMl5+v4XPfikhJulk4G+tKGFIOwURBSFzE8bixw1ebjluLOjfwtLqY0kewfjLSrO6tN2MgIhA==}
engines: {node: '>=18'}
cpu: [arm64]
os: [freebsd]
'@esbuild/freebsd-x64@0.23.1':
resolution: {integrity: sha512-lK1eJeyk1ZX8UklqFd/3A60UuZ/6UVfGT2LuGo3Wp4/z7eRTRYY+0xOu2kpClP+vMTi9wKOfXi2vjUpO1Ro76g==}
engines: {node: '>=18'}
cpu: [x64]
os: [freebsd]
'@esbuild/linux-arm64@0.23.1':
resolution: {integrity: sha512-/93bf2yxencYDnItMYV/v116zff6UyTjo4EtEQjUBeGiVpMmffDNUyD9UN2zV+V3LRV3/on4xdZ26NKzn6754g==}
engines: {node: '>=18'}
cpu: [arm64]
os: [linux]
'@esbuild/linux-arm@0.23.1':
resolution: {integrity: sha512-CXXkzgn+dXAPs3WBwE+Kvnrf4WECwBdfjfeYHpMeVxWE0EceB6vhWGShs6wi0IYEqMSIzdOF1XjQ/Mkm5d7ZdQ==}
engines: {node: '>=18'}
cpu: [arm]
os: [linux]
'@esbuild/linux-ia32@0.23.1':
resolution: {integrity: sha512-VTN4EuOHwXEkXzX5nTvVY4s7E/Krz7COC8xkftbbKRYAl96vPiUssGkeMELQMOnLOJ8k3BY1+ZY52tttZnHcXQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [linux]
'@esbuild/linux-loong64@0.23.1':
resolution: {integrity: sha512-Vx09LzEoBa5zDnieH8LSMRToj7ir/Jeq0Gu6qJ/1GcBq9GkfoEAoXvLiW1U9J1qE/Y/Oyaq33w5p2ZWrNNHNEw==}
engines: {node: '>=18'}
cpu: [loong64]
os: [linux]
'@esbuild/linux-mips64el@0.23.1':
resolution: {integrity: sha512-nrFzzMQ7W4WRLNUOU5dlWAqa6yVeI0P78WKGUo7lg2HShq/yx+UYkeNSE0SSfSure0SqgnsxPvmAUu/vu0E+3Q==}
engines: {node: '>=18'}
cpu: [mips64el]
os: [linux]
'@esbuild/linux-ppc64@0.23.1':
resolution: {integrity: sha512-dKN8fgVqd0vUIjxuJI6P/9SSSe/mB9rvA98CSH2sJnlZ/OCZWO1DJvxj8jvKTfYUdGfcq2dDxoKaC6bHuTlgcw==}
engines: {node: '>=18'}
cpu: [ppc64]
os: [linux]
'@esbuild/linux-riscv64@0.23.1':
resolution: {integrity: sha512-5AV4Pzp80fhHL83JM6LoA6pTQVWgB1HovMBsLQ9OZWLDqVY8MVobBXNSmAJi//Csh6tcY7e7Lny2Hg1tElMjIA==}
engines: {node: '>=18'}
cpu: [riscv64]
os: [linux]
'@esbuild/linux-s390x@0.23.1':
resolution: {integrity: sha512-9ygs73tuFCe6f6m/Tb+9LtYxWR4c9yg7zjt2cYkjDbDpV/xVn+68cQxMXCjUpYwEkze2RcU/rMnfIXNRFmSoDw==}
engines: {node: '>=18'}
cpu: [s390x]
os: [linux]
'@esbuild/linux-x64@0.23.1':
resolution: {integrity: sha512-EV6+ovTsEXCPAp58g2dD68LxoP/wK5pRvgy0J/HxPGB009omFPv3Yet0HiaqvrIrgPTBuC6wCH1LTOY91EO5hQ==}
engines: {node: '>=18'}
cpu: [x64]
os: [linux]
'@esbuild/netbsd-x64@0.23.1':
resolution: {integrity: sha512-aevEkCNu7KlPRpYLjwmdcuNz6bDFiE7Z8XC4CPqExjTvrHugh28QzUXVOZtiYghciKUacNktqxdpymplil1beA==}
engines: {node: '>=18'}
cpu: [x64]
os: [netbsd]
'@esbuild/openbsd-arm64@0.23.1':
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
engines: {node: '>=18'}
cpu: [arm64]
os: [openbsd]
'@esbuild/openbsd-x64@0.23.1':
resolution: {integrity: sha512-aY2gMmKmPhxfU+0EdnN+XNtGbjfQgwZj43k8G3fyrDM/UdZww6xrWxmDkuz2eCZchqVeABjV5BpildOrUbBTqA==}
engines: {node: '>=18'}
cpu: [x64]
os: [openbsd]
'@esbuild/sunos-x64@0.23.1':
resolution: {integrity: sha512-RBRT2gqEl0IKQABT4XTj78tpk9v7ehp+mazn2HbUeZl1YMdaGAQqhapjGTCe7uw7y0frDi4gS0uHzhvpFuI1sA==}
engines: {node: '>=18'}
cpu: [x64]
os: [sunos]
'@esbuild/win32-arm64@0.23.1':
resolution: {integrity: sha512-4O+gPR5rEBe2FpKOVyiJ7wNDPA8nGzDuJ6gN4okSA1gEOYZ67N8JPk58tkWtdtPeLz7lBnY6I5L3jdsr3S+A6A==}
engines: {node: '>=18'}
cpu: [arm64]
os: [win32]
'@esbuild/win32-ia32@0.23.1':
resolution: {integrity: sha512-BcaL0Vn6QwCwre3Y717nVHZbAa4UBEigzFm6VdsVdT/MbZ38xoj1X9HPkZhbmaBGUD1W8vxAfffbDe8bA6AKnQ==}
engines: {node: '>=18'}
cpu: [ia32]
os: [win32]
'@esbuild/win32-x64@0.23.1':
resolution: {integrity: sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==}
engines: {node: '>=18'}
cpu: [x64]
os: [win32]
'@ethersproject/bytes@5.7.0':
resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==}
@@ -1338,6 +1488,11 @@ packages:
es6-promisify@5.0.0:
resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==}
esbuild@0.23.1:
resolution: {integrity: sha512-VVNz/9Sa0bs5SELtn3f7qhJCDPCF5oMEl5cO9/SSinpE9hbPVvxbd572HH5AKiP7WD8INO53GgfDDhRjkylHEg==}
engines: {node: '>=18'}
hasBin: true
event-target-shim@5.0.1:
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
engines: {node: '>=6'}
@@ -1407,6 +1562,11 @@ packages:
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
os: [darwin]
function-bind@1.1.2:
resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
@@ -1414,6 +1574,9 @@ packages:
resolution: {integrity: sha512-qxsEs+9A+u85HhllWJJFicJfPDhRmjzoYdl64aMWW9yRIJmSyxdn8IEkuIM530/7T+lv0TIHd8L6Q/ra0tEoeA==}
engines: {node: '>= 0.4'}
get-tsconfig@4.8.1:
resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==}
gopd@1.2.0:
resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==}
engines: {node: '>= 0.4'}
@@ -1831,6 +1994,9 @@ packages:
requires-port@1.0.0:
resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==}
resolve-pkg-maps@1.0.0:
resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==}
retry-axios@2.6.0:
resolution: {integrity: sha512-pOLi+Gdll3JekwuFjXO3fTq+L9lzMQGcSq7M5gIjExcl3Gu1hd4XXuf5o3+LuSBsaULQH7DiNbsqPd1chVpQGQ==}
engines: {node: '>=10.7.0'}
@@ -1953,6 +2119,11 @@ packages:
tslib@2.8.1:
resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==}
tsx@4.19.2:
resolution: {integrity: sha512-pOUl6Vo2LUq/bSa8S5q7b91cgNSjctn9ugq/+Mvow99qW6x/UZYwzxy/3NmqoT66eHYfCVvFvACC58UBPFf28g==}
engines: {node: '>=18.0.0'}
hasBin: true
tweetnacl@1.0.3:
resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==}
@@ -2207,6 +2378,78 @@ snapshots:
tslib: 2.8.1
optional: true
'@esbuild/aix-ppc64@0.23.1':
optional: true
'@esbuild/android-arm64@0.23.1':
optional: true
'@esbuild/android-arm@0.23.1':
optional: true
'@esbuild/android-x64@0.23.1':
optional: true
'@esbuild/darwin-arm64@0.23.1':
optional: true
'@esbuild/darwin-x64@0.23.1':
optional: true
'@esbuild/freebsd-arm64@0.23.1':
optional: true
'@esbuild/freebsd-x64@0.23.1':
optional: true
'@esbuild/linux-arm64@0.23.1':
optional: true
'@esbuild/linux-arm@0.23.1':
optional: true
'@esbuild/linux-ia32@0.23.1':
optional: true
'@esbuild/linux-loong64@0.23.1':
optional: true
'@esbuild/linux-mips64el@0.23.1':
optional: true
'@esbuild/linux-ppc64@0.23.1':
optional: true
'@esbuild/linux-riscv64@0.23.1':
optional: true
'@esbuild/linux-s390x@0.23.1':
optional: true
'@esbuild/linux-x64@0.23.1':
optional: true
'@esbuild/netbsd-x64@0.23.1':
optional: true
'@esbuild/openbsd-arm64@0.23.1':
optional: true
'@esbuild/openbsd-x64@0.23.1':
optional: true
'@esbuild/sunos-x64@0.23.1':
optional: true
'@esbuild/win32-arm64@0.23.1':
optional: true
'@esbuild/win32-ia32@0.23.1':
optional: true
'@esbuild/win32-x64@0.23.1':
optional: true
'@ethersproject/bytes@5.7.0':
dependencies:
'@ethersproject/logger': 5.7.0
@@ -2311,7 +2554,7 @@ snapshots:
'@jridgewell/resolve-uri': 3.1.2
'@jridgewell/sourcemap-codec': 1.5.0
'@langchain/community@0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10))':
'@langchain/community@0.3.20(@browserbasehq/sdk@2.0.0)(@browserbasehq/stagehand@1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1))(@ibm-cloud/watsonx-ai@1.3.0)(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1)))(@langchain/groq@0.1.2(@langchain/core@0.3.26(openai@4.77.0(zod@3.24.1))))(axios@1.7.4)(ibm-cloud-sdk-core@5.1.0)(jsonwebtoken@9.0.2)(lodash@4.17.21)(openai@4.77.0(zod@3.24.1))(playwright@1.49.1)(ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10))':
dependencies:
'@browserbasehq/stagehand': 1.8.0(@playwright/test@1.49.1)(bufferutil@4.0.8)(deepmerge@4.3.1)(dotenv@16.4.7)(openai@4.77.0(zod@3.24.1))(utf-8-validate@5.0.10)(zod@3.24.1)
'@ibm-cloud/watsonx-ai': 1.3.0
@@ -2333,7 +2576,7 @@ snapshots:
jsonwebtoken: 9.0.2
lodash: 4.17.21
playwright: 1.49.1
ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)
ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)
transitivePeerDependencies:
- '@langchain/anthropic'
- '@langchain/aws'
@@ -3324,6 +3567,33 @@ snapshots:
dependencies:
es6-promise: 4.2.8
esbuild@0.23.1:
optionalDependencies:
'@esbuild/aix-ppc64': 0.23.1
'@esbuild/android-arm': 0.23.1
'@esbuild/android-arm64': 0.23.1
'@esbuild/android-x64': 0.23.1
'@esbuild/darwin-arm64': 0.23.1
'@esbuild/darwin-x64': 0.23.1
'@esbuild/freebsd-arm64': 0.23.1
'@esbuild/freebsd-x64': 0.23.1
'@esbuild/linux-arm': 0.23.1
'@esbuild/linux-arm64': 0.23.1
'@esbuild/linux-ia32': 0.23.1
'@esbuild/linux-loong64': 0.23.1
'@esbuild/linux-mips64el': 0.23.1
'@esbuild/linux-ppc64': 0.23.1
'@esbuild/linux-riscv64': 0.23.1
'@esbuild/linux-s390x': 0.23.1
'@esbuild/linux-x64': 0.23.1
'@esbuild/netbsd-x64': 0.23.1
'@esbuild/openbsd-arm64': 0.23.1
'@esbuild/openbsd-x64': 0.23.1
'@esbuild/sunos-x64': 0.23.1
'@esbuild/win32-arm64': 0.23.1
'@esbuild/win32-ia32': 0.23.1
'@esbuild/win32-x64': 0.23.1
event-target-shim@5.0.1: {}
eventemitter3@4.0.7: {}
@@ -3380,6 +3650,9 @@ snapshots:
fsevents@2.3.2:
optional: true
fsevents@2.3.3:
optional: true
function-bind@1.1.2: {}
get-intrinsic@1.2.6:
@@ -3395,6 +3668,10 @@ snapshots:
hasown: 2.0.2
math-intrinsics: 1.1.0
get-tsconfig@4.8.1:
dependencies:
resolve-pkg-maps: 1.0.0
gopd@1.2.0: {}
graceful-fs@4.2.11:
@@ -3835,6 +4112,8 @@ snapshots:
requires-port@1.0.0: {}
resolve-pkg-maps@1.0.0: {}
retry-axios@2.6.0(axios@1.7.4):
dependencies:
axios: 1.7.4(debug@4.4.0)
@@ -4046,6 +4325,13 @@ snapshots:
tslib@2.8.1: {}
tsx@4.19.2:
dependencies:
esbuild: 0.23.1
get-tsconfig: 4.8.1
optionalDependencies:
fsevents: 2.3.3
tweetnacl@1.0.3: {}
typedoc@0.26.11(typescript@5.6.3):

View File

@@ -1,8 +1,7 @@
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { gpt4o } from "../utils/model.js";
import { solanaAgentState } from "../utils/state.js";
import { gpt4o } from "../utils/model";
import { solanaAgentState } from "../utils/state";
import { TavilySearchResults } from "@langchain/community/tools/tavily_search";
import { HumanMessage } from "@langchain/core/messages";
// Initialize tools array
const searchTools = [];
@@ -12,7 +11,7 @@ if (process.env.TAVILY_API_KEY) {
searchTools.push(new TavilySearchResults());
}
export const generalAgent = createReactAgent({
const generalAgent = createReactAgent({
llm: gpt4o,
tools: searchTools,
});
@@ -24,9 +23,3 @@ export const generalistNode = async (state: typeof solanaAgentState.State) => {
return { messages: [...result.messages] };
};
const messages = [new HumanMessage("What is the best way to buy SOL?")];
const result = await generalAgent.invoke({ messages });
console.log(result.messages);

View File

@@ -0,0 +1,23 @@
import { prompt, parser } from "../prompts/manager";
import { RunnableSequence } from "@langchain/core/runnables";
import { solanaAgentState } from "../utils/state";
import { gpt4o } from "../utils/model";
const chain = RunnableSequence.from([prompt, gpt4o, parser]);
export const managerNode = async (state: typeof solanaAgentState.State) => {
const { messages } = state;
const result = await chain.invoke({
formatInstructions: parser.getFormatInstructions(),
messages: messages,
});
const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = result;
return {
isSolanaReadQuery,
isSolanaWriteQuery,
isGeneralQuery,
};
};

View File

@@ -0,0 +1,25 @@
import { gpt4o } from "../utils/model";
import { agentKit } from "../utils/solanaAgent";
import { solanaAgentState } from "../utils/state";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { SolanaTransferTool } from "solana-agent-kit/dist/langchain";
import { transferSwapPrompt } from "../prompts/transferSwap";
import { swapTool } from "../tools/swap";
const transferOrSwapAgent = createReactAgent({
stateModifier: transferSwapPrompt,
llm: gpt4o,
tools: [new SolanaTransferTool(agentKit), swapTool],
});
export const transferSwapNode = async (
state: typeof solanaAgentState.State,
) => {
const { messages } = state;
const result = await transferOrSwapAgent.invoke({
messages,
});
return result;
};

View File

@@ -0,0 +1,5 @@
import { HumanMessage } from "@langchain/core/messages";
export const generalQuestion = [
new HumanMessage("Who is the president of Ecuador?"),
];

View File

@@ -0,0 +1,50 @@
export const tokenList = [
{
name: "USDC",
ticker: "USDC",
decimal: 6,
mintAddress: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
},
{
name: "USDT",
ticker: "USDT",
decimal: 6,
mintAddress: "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB",
},
{
name: "USDS",
ticker: "USDS",
decimal: 6,
mintAddress: "USDSwr9ApdHk5bvJKMjzff41FfuX8bSxdKcR81vTwcA",
},
{
name: "SOL",
ticker: "SOL",
decimal: 9,
mintAddress: "So11111111111111111111111111111111111111112",
},
{
name: "jitoSOL",
ticker: "jitoSOL",
decimal: 9,
mintAddress: "J1toso1uCk3RLmjorhTtrVwY9HJ7X8V9yYac6Y7kGCPn",
},
{
name: "bSOL",
ticker: "bSOL",
decimal: 9,
mintAddress: "bSo13r4TkiE4KumL71LsHTPpL2euBYLFx6h9HP3piy1",
},
{
name: "mSOL",
ticker: "mSOL",
decimal: 9,
mintAddress: "mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So",
},
{
name: "BONK",
ticker: "BONK",
decimal: 9,
mintAddress: "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
},
];

View File

@@ -1,6 +1,25 @@
import { StateGraph } from "@langchain/langgraph";
import { solanaAgentState } from "./utils/state";
import { generalistNode } from "./agents/generalAgent";
import { transferSwapNode } from "./agents/transferOrSwap";
import { managerNode } from "./agents/manager";
import { START, END } from "@langchain/langgraph";
import { managerRouter } from "./utils/route";
import { HumanMessage } from "@langchain/core/messages";
const workflow = new StateGraph(solanaAgentState);
const workflow = new StateGraph(solanaAgentState)
.addNode("generalist", generalistNode)
.addNode("manager", managerNode)
.addNode("transferSwap", transferSwapNode)
.addEdge(START, "manager")
.addConditionalEdges("manager", managerRouter)
.addEdge("generalist", END)
.addEdge("transferSwap", END);
export const graph = workflow.compile();
const result = await graph.invoke({
messages: [new HumanMessage("swap 0.1 usdc to sol")],
});
console.log(result);

View File

@@ -0,0 +1,48 @@
import { StructuredOutputParser } from "@langchain/core/output_parsers";
import { z } from "zod";
import { PromptTemplate } from "@langchain/core/prompts";
export const parser = StructuredOutputParser.fromZodSchema(
z.object({
isSolanaReadQuery: z
.boolean()
.describe("Query requires reading data from Solana blockchain"),
isSolanaWriteQuery: z
.boolean()
.describe("Query requires writing/modifying data on Solana blockchain"),
isGeneralQuery: z
.boolean()
.describe("Query is about non-blockchain topics"),
}),
);
export const prompt = PromptTemplate.fromTemplate(
`
You are the Chief Routing Officer for a multi-blockchain agent network. Your role is to:
1. Analyze and classify incoming queries
2. Determine if the query requires Solana read operations, write operations, or is general
Format your response according to:
{formatInstructions}
Classification Guidelines:
- Solana Read Operations include:
* Checking account balances
* Viewing NFT metadata
* Getting program data
* Querying transaction history
* Checking token prices or holdings
- Solana Write Operations include:
* Creating or updating programs
* Sending tokens or SOL
* Minting NFTs
* Creating accounts
* Any transaction that modifies blockchain state
- General queries include:
* Non-blockchain topics
* Internet searches
* General knowledge questions
\n {messages} \n
`,
);

View File

@@ -0,0 +1,43 @@
import {
ChatPromptTemplate,
MessagesPlaceholder,
} from "@langchain/core/prompts";
import { tokenList } from "../helper/tokenList";
// Convert token list to a more readable format for the prompt
const formattedTokenList = tokenList
.map(
(token) =>
`- ${token.name} (${token.ticker}) - Decimals: ${token.decimal} - Address: ${token.mintAddress}`,
)
.join("\n ");
export const transferSwapPrompt = ChatPromptTemplate.fromMessages([
[
"system",
`You are an agent that is an expert in Solana transactions, specialized in token transfers and swaps. You can execute these transactions using the available tools based on user input.
When processing token amounts:
1. Use EXACTLY the decimal amount specified by the user without any modifications
2. Do not round or adjust the numbers
3. Maintain precise decimal places as provided in the user input
For transfers:
- User must specify the token, amount, and recipient address
- The same token will be used for input and output
For swaps:
- User must specify the input token, output token, and amount to swap
- Input and output tokens must be different
- Select tokens from this list of supported tokens:
${formattedTokenList}
Example amounts:
If you say "0.01 SOL", I will use exactly 0.01 (not 0.010 or 0.0100)
If you say "1.234 USDC", I will use exactly 1.234 (not 1.23 or 1.2340)
For swaps, have the slippage be 200 bps
`,
],
new MessagesPlaceholder("messages"),
]);

View File

@@ -0,0 +1,45 @@
import { agentKit } from "../utils/solanaAgent";
import { tool } from "@langchain/core/tools";
import { z } from "zod";
import { PublicKey } from "@solana/web3.js";
export const swapTool = tool(
async ({ outputMint, inputAmount, inputMint, inputDecimal }) => {
try {
const inputAmountWithDecimals = inputAmount * 10 ** inputDecimal;
const outputMintAddress = new PublicKey(outputMint);
const inputMintAddress = new PublicKey(inputMint);
console.log(inputAmountWithDecimals, outputMintAddress, inputMintAddress);
const tx = await agentKit.trade(
outputMintAddress,
inputAmountWithDecimals,
inputMintAddress,
200,
);
return tx;
} catch (error) {
console.error(error);
return "error";
}
},
{
name: "swap",
description:
"call to swap/trade tokens from one token to the other using Jupiter exchange",
schema: z.object({
outputMint: z
.string()
.describe("The mint address of destination token to be swapped to"),
inputAmount: z
.number()
.describe(
"the input amount of the token to be swapped without adding any decimals",
),
inputMint: z.string().describe("The mint address of the origin token "),
inputDecimal: z
.number()
.describe("The decimal of the input token that is being traded"),
}),
},
);

View File

@@ -0,0 +1,14 @@
import { solanaAgentState } from "./state";
import { END } from "@langchain/langgraph";
export const managerRouter = (state: typeof solanaAgentState.State) => {
const { isSolanaReadQuery, isSolanaWriteQuery, isGeneralQuery } = state;
if (isGeneralQuery) {
return "generalist";
} else if (isSolanaWriteQuery) {
return "transferSwap";
} else {
return END;
}
};

View File

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