From 651ee9623e8d67c380764afa2df1a9937272b4e9 Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 13:44:55 +0100 Subject: [PATCH 1/7] Implement getAsset tool --- package.json | 1 + pnpm-lock.yaml | 528 ++++++++++++++++++++++++++++ src/actions/index.ts | 2 + src/actions/metaplex/getAsset.ts | 51 +++ src/agent/index.ts | 6 + src/langchain/index.ts | 2 + src/langchain/metaplex/get_asset.ts | 34 ++ src/tools/metaplex/get_asset.ts | 31 ++ src/tools/metaplex/index.ts | 1 + 9 files changed, 656 insertions(+) create mode 100644 src/actions/metaplex/getAsset.ts create mode 100644 src/langchain/metaplex/get_asset.ts create mode 100644 src/tools/metaplex/get_asset.ts diff --git a/package.json b/package.json index d62664b..c10020d 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@langchain/openai": "^0.3.16", "@lightprotocol/compressed-token": "^0.17.1", "@lightprotocol/stateless.js": "^0.17.1", + "@metaplex-foundation/digital-asset-standard-api": "^1.0.4", "@metaplex-foundation/mpl-core": "^1.1.1", "@metaplex-foundation/mpl-token-metadata": "^3.3.0", "@metaplex-foundation/mpl-toolbox": "^0.9.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 31aed29..a9a61b8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: '@lightprotocol/stateless.js': specifier: ^0.17.1 version: 0.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@metaplex-foundation/digital-asset-standard-api': + specifier: ^1.0.4 + version: 1.0.4(@metaplex-foundation/umi@0.9.2) '@metaplex-foundation/mpl-core': specifier: ^1.1.1 version: 1.1.1(@metaplex-foundation/umi@0.9.2)(@noble/hashes@1.7.0) @@ -780,6 +783,11 @@ packages: '@metaplex-foundation/cusper@0.0.2': resolution: {integrity: sha512-S9RulC2fFCFOQraz61bij+5YCHhSO9llJegK8c8Y6731fSi6snUSQJdCUqYS8AIgR0TKbQvdvgSyIIdbDFZbBA==} + '@metaplex-foundation/digital-asset-standard-api@1.0.4': + resolution: {integrity: sha512-YSYyMnIoKNykDZTXsSCeiIOJ7NT5Ke2pzghXDsinRwHvwIZWv+zY5kJQBvTglAzYlt/GaI+noAhUZXXmSbp07A==} + peerDependencies: + '@metaplex-foundation/umi': '>= 0.8.2 < 1' + '@metaplex-foundation/js@0.20.1': resolution: {integrity: sha512-aqiLoEiToXdfI5pS+17/GN/dIO2D31gLoVQvEKDQi9XcnOPVhfJerXDmwgKbhp79OGoYxtlvVw+b2suacoUzGQ==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -1606,6 +1614,9 @@ packages: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} + abs@1.3.14: + resolution: {integrity: sha512-PrS26IzwKLWwuURpiKl8wRmJ2KdR/azaVrLEBWG/TALwT20Y7qjtYp1qcMLHA4206hBHY5phv3w4pjf9NPv4Vw==} + accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} engines: {node: '>= 0.6'} @@ -1914,6 +1925,10 @@ packages: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} engines: {node: '>=10'} + capture-stack-trace@1.0.2: + resolution: {integrity: sha512-X/WM2UQs6VMHUtjUDnZTRI+i1crWteJySFzr9UpGoQa4WQffXVTTXuekjl7TjZRlcF2XfjgITT0HxZ9RnxeT0w==} + engines: {node: '>=0.10.0'} + ccount@2.0.1: resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} @@ -2038,6 +2053,13 @@ packages: resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} engines: {node: '>= 0.6'} + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-error-class@3.0.2: + resolution: {integrity: sha512-gYTKKexFO3kh200H1Nit76sRwRtOY32vQd3jpAQKpLtZqyNsSQNfI4N7o3eP2wUjV35pTWKRYqFUDBvUha/Pkw==} + engines: {node: '>=0.10.0'} + create-hash@1.2.0: resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} @@ -2136,6 +2158,9 @@ packages: resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} engines: {node: '>=10'} + deffy@2.2.4: + resolution: {integrity: sha512-pLc9lsbsWjr6RxmJ2OLyvm+9l4j1yK69h+TML/gUit/t3vTijpkNGh8LioaJYTGO7F25m6HZndADcUOo2PsiUg==} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -2205,6 +2230,9 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} @@ -2251,6 +2279,12 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + err@1.1.1: + resolution: {integrity: sha512-N97Ybd2jJHVQ+Ft3Q5+C2gM3kgygkdeQmEqbN2z15UTVyyEsIwLA1VK39O1DHEJhXbwIFcJLqm6iARNhFANcQA==} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -2401,6 +2435,9 @@ packages: resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} engines: {node: '>=12.0.0'} + exec-limiter@3.2.13: + resolution: {integrity: sha512-86Ri699bwiHZVBzTzNj8gspqAhCPchg70zPVWIh3qzUOA1pUMcb272Em3LPk8AE0mS95B9yMJhtqF8vFJAn0dA==} + execa@8.0.1: resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} engines: {node: '>=16.17'} @@ -2567,6 +2604,9 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + function.name@1.0.13: + resolution: {integrity: sha512-mVrqdoy5npWZyoXl4DxCeuVF6delDcQjVS9aPdvLYlBxtMTZDR2B5GVEQEoM1jJyspCqg3C0v4ABkLE7tp9xFA==} + get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} @@ -2594,6 +2634,18 @@ packages: get-tsconfig@4.8.1: resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + git-package-json@1.4.10: + resolution: {integrity: sha512-DRAcvbzd2SxGK7w8OgYfvKqhFliT5keX0lmSmVdgScgf1kkl5tbbo7Pam6uYoCa1liOiipKxQZG8quCtGWl/fA==} + + git-source@1.1.10: + resolution: {integrity: sha512-XZZ7ZgnLL35oLgM/xjnLYgtlKlxJG0FohC1kWDvGkU7s1VKGXK0pFF/g1itQEwQ3D+uTQzBnzPi8XbqOv7Wc1Q==} + + git-up@1.2.1: + resolution: {integrity: sha512-SRVN3rOLACva8imc7BFrB6ts5iISWKH1/h/1Z+JZYoUI7UVQM7gQqk4M2yxUENbq2jUUT09NEND5xwP1i7Ktlw==} + + git-url-parse@5.0.1: + resolution: {integrity: sha512-4uSiOgrryNEMBX+gTWogenYRUh2j1D+95STTSEF2RCTgLkfJikl8c7BGr0Bn274hwuxTsbS2/FQ5pVS9FoXegQ==} + github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} @@ -2634,6 +2686,10 @@ packages: resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} engines: {node: '>=10.19.0'} + got@5.7.1: + resolution: {integrity: sha512-1qd54GLxvVgzuidFmw9ze9umxS3rzhdBH6Wt6BTYrTQUXTN01vGGYXwzLzYLowNx8HBH3/c7kRyvx90fh13i7Q==} + engines: {node: '>=0.10.0 <7'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -2646,6 +2702,9 @@ packages: groq-sdk@0.5.0: resolution: {integrity: sha512-RVmhW7qZ+XZoy5fIuSdx/LGQJONpL8MHgZEW7dFwTdgkzStub2XQx6OKv28CHogijdwH41J+Npj/z2jBPu3vmw==} + gry@5.0.8: + resolution: {integrity: sha512-meq9ZjYVpLzZh3ojhTg7IMad9grGsx6rUUKHLqPnhLXzJkRQvEL2U3tQpS5/WentYTtHtxkT3Ew/mb10D6F6/g==} + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -2684,6 +2743,9 @@ packages: hmac-drbg@1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -2765,10 +2827,17 @@ packages: resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} engines: {node: '>= 0.4'} + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + is-core-module@2.16.1: + resolution: {integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==} + engines: {node: '>= 0.4'} + is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} @@ -2813,14 +2882,29 @@ packages: resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} engines: {node: '>=8'} + is-redirect@1.0.0: + resolution: {integrity: sha512-cr/SlUEe5zOGmzvj9bUyC4LVvkNVAXu4GytXLNMr1pny+a65MpQ9IJzFHD5vi7FyJgb4qt27+eS3TuQnqB+RQw==} + engines: {node: '>=0.10.0'} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} + is-retry-allowed@1.2.0: + resolution: {integrity: sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==} + engines: {node: '>=0.10.0'} + is-retry-allowed@2.2.0: resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} engines: {node: '>=10'} + is-ssh@1.4.0: + resolution: {integrity: sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2836,6 +2920,9 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -2844,6 +2931,9 @@ packages: peerDependencies: ws: '*' + iterate-object@1.3.4: + resolution: {integrity: sha512-4dG1D1x/7g8PwHS9aK6QV5V94+ZvyP4+d19qDv43EzImmrndysIl4prmJ1hWWIGCqrZHyaHBm6BSEWHOLnpoNw==} + jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} @@ -3017,6 +3107,9 @@ packages: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} engines: {node: '>=14'} + limit-it@3.2.10: + resolution: {integrity: sha512-T0NK99pHnkimldr1WUqvbGV1oWDku/xC9J/OqzJFsV1jeOS6Bwl8W7vkeQIBqwiON9dTALws+rX/XPMQqWerDQ==} + linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} @@ -3073,6 +3166,10 @@ packages: lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowercase-keys@1.0.1: + resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==} + engines: {node: '>=0.10.0'} + lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -3314,6 +3411,16 @@ packages: engines: {node: '>=10'} hasBin: true + node-status-codes@1.0.0: + resolution: {integrity: sha512-1cBMgRxdMWE8KeWCqk2RIOrvUb0XCwYfEsY5/y2NlXyq4Y/RumnOZvTj4Nbr77+Vb2C+kyBoRTdkNOS8L3d/aQ==} + engines: {node: '>=0.10.0'} + + noop6@1.0.9: + resolution: {integrity: sha512-DB3Hwyd89dPr5HqEPg3YHjzvwh/mCqizC1zZ8vyofqc+TQRyPDnT4wgXXbLGF4z9YAzwwTLi8pNLhGqcbSjgkA==} + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} engines: {node: '>=10'} @@ -3326,6 +3433,16 @@ packages: resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} engines: {node: '>=6.5.0', npm: '>=3'} + oargv@3.4.10: + resolution: {integrity: sha512-SXaMANv9sr7S/dP0vj0+Ybipa47UE1ntTWQ2rpPRhC6Bsvfl+Jg03Xif7jfL0sWKOYWK8oPjcZ5eJ82t8AP/8g==} + + obj-def@1.0.9: + resolution: {integrity: sha512-bQ4ya3VYD6FAA1+s6mEhaURRHSmw4+sKaXE6UyXZ1XDYc5D+c7look25dFdydmLd18epUegh398gdDkMUZI9xg==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + object-inspect@1.13.3: resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} engines: {node: '>= 0.4'} @@ -3349,6 +3466,9 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + one-by-one@3.2.8: + resolution: {integrity: sha512-HR/pSzZdm46Xqj58K+Bu64kMbSTw8/u77AwWvV+rprO/OsuR++pPlkUJn+SmwqBGRgHKwSKQ974V3uls7crIeQ==} + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} @@ -3419,6 +3539,17 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-json-path@1.0.9: + resolution: {integrity: sha512-uNu7f6Ef7tQHZRnkyVnCtzdSYVN9uBtge/sG7wzcUaawFWkPYUq67iXxRGrQSg/q0tzxIB8jSyIYUKjG2Jn//A==} + + package-json@2.4.0: + resolution: {integrity: sha512-PRg65iXMTt/uK8Rfh5zvzkUbfAPitF17YaCY+IbHsYgksiLvtzWWTUildHth3mVaZ7871OJ7gtP4LBRBlmAdXg==} + engines: {node: '>=0.10.0'} + + package.json@2.0.1: + resolution: {integrity: sha512-pSxZ6XR5yEawRN2ekxx9IKgPN5uNAYco7MCPxtBEWMKO3UKWa1X2CtQMzMgloeGj2g2o6cue3Sb5iPkByIJqlw==} + deprecated: Use pkg.json instead. + pako@0.2.9: resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} @@ -3429,6 +3560,13 @@ packages: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + + parse-url@1.3.11: + resolution: {integrity: sha512-1wj9nkgH/5EboDxLwaTMGJh3oH3f+Gue+aGdh631oCqoSBpokzmMmOldvOeBPtB8GJBYJbaF93KPzlkU+Y1ksg==} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -3449,6 +3587,9 @@ packages: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -3480,6 +3621,14 @@ packages: engines: {node: '>=0.10'} hasBin: true + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + poly1305-js@0.4.4: resolution: {integrity: sha512-5B6/S+vg5AOr66wJDkh5LOpU/F3EKANDy4VXKsNZLXea1uCy6CiOWOZ3VhcC0nYdhE7vJUMcLxqcVlrv2g/+Rg==} @@ -3499,6 +3648,10 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prepend-http@1.0.4: + resolution: {integrity: sha512-PhmXi5XmoyKw1Un4E+opM2KcsJInDvKyuOumcjjw3waw86ZNjHwVUOOWLc4bCzLdcKNaWBH9e99sbWzDQsVaYg==} + engines: {node: '>=0.10.0'} + prettier-linter-helpers@1.0.0: resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} engines: {node: '>=6.0.0'} @@ -3513,6 +3666,9 @@ packages: engines: {node: '>=14'} hasBin: true + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + prom-client@15.1.3: resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} engines: {node: ^16 || ^18 || >=20} @@ -3528,6 +3684,12 @@ packages: resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} engines: {node: '>=12.0.0'} + protocols@1.4.8: + resolution: {integrity: sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==} + + protocols@2.0.1: + resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -3557,6 +3719,12 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} + r-json@1.3.0: + resolution: {integrity: sha512-xesd+RHCpymPCYd9DvDvUr1w1IieSChkqYF1EpuAYrvCfLXji9NP36DvyYZJZZB5soVDvZ0WUtBoZaU1g5Yt9A==} + + r-package-json@1.0.9: + resolution: {integrity: sha512-G4Vpf1KImWmmPFGdtWQTU0L9zk0SjqEC4qs/jE7AQ+Ylmr5kizMzGeC4wnHp5+ijPqNN+2ZPpvyjVNdN1CDVcg==} + randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -3576,6 +3744,13 @@ packages: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} + read-all-stream@3.1.0: + resolution: {integrity: sha512-DI1drPHbmBcUDWrJ7ull/F2Qb8HkwBncVx8/RpKYFSIACYaVRQReISYPdZz/mt1y1+qMCOrfReTopERmaxtP6w==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -3592,6 +3767,13 @@ packages: regex@5.1.1: resolution: {integrity: sha512-dN5I359AVGPnwzJm2jN1k0W9LPZ+ePvoOeVMMfqIMFz53sSwXkxaJoxr50ptnsC771lK95BnTrVSZxq0b9yCGw==} + registry-auth-token@3.4.0: + resolution: {integrity: sha512-4LM6Fw8eBQdwMYcES4yTnn2TqIasbXuwDx3um+QRs7S55aMKCBKBxvPXl2RiUjHwuJLTyYfxSpmfSAjQpcuP+A==} + + registry-url@3.1.0: + resolution: {integrity: sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==} + engines: {node: '>=0.10.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -3606,6 +3788,11 @@ packages: resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + resolve@1.22.10: + resolution: {integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==} + engines: {node: '>= 0.4'} + hasBin: true + responselike@2.0.1: resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} @@ -3672,6 +3859,9 @@ packages: rxjs@7.8.1: resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -3696,6 +3886,10 @@ packages: resolution: {integrity: sha512-O4OZEaNtkMd/K0i6js9SL+gqy0ZCBMgUvlSqHKi4IBdjhe7wB8pwztUk1BbZ1fmrvpwFrPbHzqd2w5pTcJH6LA==} engines: {node: '>=0.8.0'} + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + semver@7.6.3: resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} engines: {node: '>=10'} @@ -3768,6 +3962,9 @@ packages: resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} engines: {node: '>=18'} + sliced@1.0.1: + resolution: {integrity: sha512-VZBmZP8WU3sMOZm1bdgTadsQbcscK0UM8oKxKVBs4XAhUo2Xxzm/OFMGBkPusxw9xL3Uy8LrzEqGqJhclsr0yA==} + snake-case@3.0.4: resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} @@ -3815,6 +4012,18 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + spok@1.5.5: resolution: {integrity: sha512-IrJIXY54sCNFASyHPOY+jEirkiJ26JDqsGiI0Dvhwcnkl0PEWi1PSsrkYql0rzDw8LFVTcA7rdUCAJdE2HE+2Q==} @@ -3848,6 +4057,9 @@ packages: resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} engines: {node: '>=18'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -3900,6 +4112,10 @@ packages: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + swr@2.3.0: resolution: {integrity: sha512-NyZ76wA4yElZWBHzSgEJc28a0u6QZvhb6w0azeL2k7+Q1gAzVK+IqQYXhVOC/mzi+HZIozrZvBVeSeOZNR2bqA==} peerDependencies: @@ -3932,6 +4148,10 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + timed-out@3.1.3: + resolution: {integrity: sha512-3RB4qgvPkxF/FGPnrzaWLhW1rxNK2sdH0mFjbhxkfTR6QXvcM3EtYm9L44UrhODZrZ+yhDXeMncLqi8QXn2MJg==} + engines: {node: '>=0.10.0'} + tiny-inflate@1.0.3: resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} @@ -3941,6 +4161,10 @@ packages: tmp-promise@3.0.3: resolution: {integrity: sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==} + tmp@0.0.28: + resolution: {integrity: sha512-c2mmfiBmND6SOVxzogm1oda0OJ1HZVIk/5n26N59dDTh80MUeavpiCls4PGAdkX1PFkKokLpcf7prSjCeXLsJg==} + engines: {node: '>=0.4.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -4074,9 +4298,15 @@ packages: engines: {node: '>=14.17'} hasBin: true + typpy@2.3.13: + resolution: {integrity: sha512-vOxIcQz9sxHi+rT09SJ5aDgVgrPppQjwnnayTrMye1ODaU8gIZTDM19t9TxmEElbMihx2Nq/0/b/MtyKfayRqA==} + uc.micro@2.1.0: resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + ul@5.2.15: + resolution: {integrity: sha512-svLEUy8xSCip5IWnsRa0UOg+2zP0Wsj4qlbjTmX6GJSmvKMHADBuHOm1dpNkWqWPIGuVSqzUkV3Cris5JrlTRQ==} + undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} @@ -4112,9 +4342,17 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} + unzip-response@1.0.2: + resolution: {integrity: sha512-pwCcjjhEcpW45JZIySExBHYv5Y9EeL2OIGEfrSKp2dMUFGFv4CpvZkwJbVge8OvGH2BNNtJBx67DuKuJhf+N5Q==} + engines: {node: '>=0.10'} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-parse-lax@1.0.0: + resolution: {integrity: sha512-BVA4lR5PIviy2PMseNd2jbFQ+jwSwQGdJejf5ctd1rEXt0Ypd7yanUK9+lYechVlN5VaTJGsu2U/3MDDu6KgBA==} + engines: {node: '>=0.10.0'} + url-value-parser@2.2.0: resolution: {integrity: sha512-yIQdxJpgkPamPPAPuGdS7Q548rLhny42tg8d4vyTNzFqvOnwqrgHXvgehT09U7fwrzxi3RxCiXjoNUNnNOlQ8A==} engines: {node: '>=6.0.0'} @@ -4160,6 +4398,9 @@ packages: v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -4173,6 +4414,9 @@ packages: vlq@2.0.4: resolution: {integrity: sha512-aodjPa2wPQFkra1G8CzJBTHXhgk3EVSwxSWXNPr1fgdFLUb8kvLV1iEb6rFgasIsjP82HWI6dsb5Io26DDnasA==} + w-json@1.3.10: + resolution: {integrity: sha512-XadVyw0xE+oZ5FGApXsdswv96rOhStzKqL53uSe5UaTadABGkWIg1+DTx8kiZ/VqTZTBneoL0l65RcPe4W3ecw==} + wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} @@ -5525,6 +5769,11 @@ snapshots: '@metaplex-foundation/cusper@0.0.2': {} + '@metaplex-foundation/digital-asset-standard-api@1.0.4(@metaplex-foundation/umi@0.9.2)': + dependencies: + '@metaplex-foundation/umi': 0.9.2 + package.json: 2.0.1 + '@metaplex-foundation/js@0.20.1(arweave@1.15.5)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.6.3)(utf-8-validate@5.0.10)': dependencies: '@irys/sdk': 0.0.2(arweave@1.15.5)(bufferutil@4.0.9)(debug@4.4.0)(utf-8-validate@5.0.10) @@ -7372,6 +7621,10 @@ snapshots: dependencies: event-target-shim: 5.0.1 + abs@1.3.14: + dependencies: + ul: 5.2.15 + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -7780,6 +8033,8 @@ snapshots: camelcase@6.3.0: {} + capture-stack-trace@1.0.2: {} + ccount@2.0.1: {} chai@5.1.2: @@ -7879,6 +8134,12 @@ snapshots: cookie@0.7.1: {} + core-util-is@1.0.3: {} + + create-error-class@3.0.2: + dependencies: + capture-stack-trace: 1.0.2 + create-hash@1.2.0: dependencies: cipher-base: 1.0.6 @@ -7965,6 +8226,10 @@ snapshots: defer-to-connect@2.0.1: {} + deffy@2.2.4: + dependencies: + typpy: 2.3.13 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 @@ -8020,6 +8285,10 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexer2@0.1.4: + dependencies: + readable-stream: 2.3.8 + eastasianwidth@0.2.0: {} ee-first@1.1.1: {} @@ -8066,6 +8335,14 @@ snapshots: err-code@2.0.3: {} + err@1.1.1: + dependencies: + typpy: 2.3.13 + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + es-define-property@1.0.1: {} es-errors@1.3.0: {} @@ -8278,6 +8555,11 @@ snapshots: eventsource@2.0.2: {} + exec-limiter@3.2.13: + dependencies: + limit-it: 3.2.10 + typpy: 2.3.13 + execa@8.0.1: dependencies: cross-spawn: 7.0.6 @@ -8521,6 +8803,10 @@ snapshots: function-bind@1.1.2: {} + function.name@1.0.13: + dependencies: + noop6: 1.0.9 + get-caller-file@2.0.5: {} get-east-asian-width@1.3.0: {} @@ -8553,6 +8839,31 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + git-package-json@1.4.10: + dependencies: + deffy: 2.2.4 + err: 1.1.1 + gry: 5.0.8 + normalize-package-data: 2.5.0 + oargv: 3.4.10 + one-by-one: 3.2.8 + r-json: 1.3.0 + r-package-json: 1.0.9 + tmp: 0.0.28 + + git-source@1.1.10: + dependencies: + git-url-parse: 5.0.1 + + git-up@1.2.1: + dependencies: + is-ssh: 1.4.0 + parse-url: 1.3.11 + + git-url-parse@5.0.1: + dependencies: + git-up: 1.2.1 + github-from-package@0.0.0: {} glob-parent@5.1.2: @@ -8612,6 +8923,26 @@ snapshots: p-cancelable: 2.1.1 responselike: 2.0.1 + got@5.7.1: + dependencies: + '@types/keyv': 3.1.4 + '@types/responselike': 1.0.3 + create-error-class: 3.0.2 + duplexer2: 0.1.4 + is-redirect: 1.0.0 + is-retry-allowed: 1.2.0 + is-stream: 1.1.0 + lowercase-keys: 1.0.1 + node-status-codes: 1.0.0 + object-assign: 4.1.1 + parse-json: 2.2.0 + pinkie-promise: 2.0.1 + read-all-stream: 3.1.0 + readable-stream: 2.3.8 + timed-out: 3.1.3 + unzip-response: 1.0.2 + url-parse-lax: 1.0.0 + graceful-fs@4.2.11: optional: true @@ -8635,6 +8966,13 @@ snapshots: transitivePeerDependencies: - encoding + gry@5.0.8: + dependencies: + abs: 1.3.14 + exec-limiter: 3.2.13 + one-by-one: 3.2.8 + ul: 5.2.15 + has-flag@4.0.0: {} has-property-descriptors@1.0.2: @@ -8688,6 +9026,8 @@ snapshots: minimalistic-assert: 1.0.1 minimalistic-crypto-utils: 1.0.1 + hosted-git-info@2.8.9: {} + html-void-elements@3.0.0: {} http-cache-semantics@4.1.1: {} @@ -8778,8 +9118,14 @@ snapshots: call-bound: 1.0.3 has-tostringtag: 1.0.2 + is-arrayish@0.2.1: {} + is-callable@1.2.7: {} + is-core-module@2.16.1: + dependencies: + hasown: 2.0.2 + is-extglob@2.1.1: {} is-fullwidth-code-point@3.0.0: {} @@ -8814,6 +9160,8 @@ snapshots: is-path-inside@3.0.3: {} + is-redirect@1.0.0: {} + is-regex@1.2.1: dependencies: call-bound: 1.0.3 @@ -8821,8 +9169,16 @@ snapshots: has-tostringtag: 1.0.2 hasown: 2.0.2 + is-retry-allowed@1.2.0: {} + is-retry-allowed@2.2.0: {} + is-ssh@1.4.0: + dependencies: + protocols: 2.0.1 + + is-stream@1.1.0: {} + is-stream@3.0.0: {} is-typed-array@1.1.15: @@ -8833,6 +9189,8 @@ snapshots: is-unicode-supported@0.1.0: {} + isarray@1.0.0: {} + isexe@2.0.0: {} isomorphic-ws@4.0.1(ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10)): @@ -8843,6 +9201,8 @@ snapshots: dependencies: ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + iterate-object@1.3.4: {} + jackspeak@3.4.3: dependencies: '@isaacs/cliui': 8.0.2 @@ -9010,6 +9370,10 @@ snapshots: lilconfig@3.1.3: {} + limit-it@3.2.10: + dependencies: + typpy: 2.3.13 + linkify-it@5.0.0: dependencies: uc.micro: 2.1.0 @@ -9079,6 +9443,8 @@ snapshots: dependencies: tslib: 2.8.1 + lowercase-keys@1.0.1: {} + lowercase-keys@2.0.0: {} lru-cache@10.4.3: {} @@ -9286,6 +9652,17 @@ snapshots: node-addon-api: 3.2.1 prebuild-install: 7.1.2 + node-status-codes@1.0.0: {} + + noop6@1.0.9: {} + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.10 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + normalize-url@6.1.0: {} npm-run-path@5.3.0: @@ -9297,6 +9674,17 @@ snapshots: bn.js: 4.11.6 strip-hex-prefix: 1.0.0 + oargv@3.4.10: + dependencies: + iterate-object: 1.3.4 + ul: 5.2.15 + + obj-def@1.0.9: + dependencies: + deffy: 2.2.4 + + object-assign@4.1.1: {} + object-inspect@1.13.3: {} object-is@1.1.6: @@ -9323,6 +9711,11 @@ snapshots: dependencies: wrappy: 1.0.2 + one-by-one@3.2.8: + dependencies: + obj-def: 1.0.9 + sliced: 1.0.1 + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 @@ -9408,6 +9801,23 @@ snapshots: package-json-from-dist@1.0.1: {} + package-json-path@1.0.9: + dependencies: + abs: 1.3.14 + + package-json@2.4.0: + dependencies: + got: 5.7.1 + registry-auth-token: 3.4.0 + registry-url: 3.1.0 + semver: 5.7.2 + + package.json@2.0.1: + dependencies: + git-package-json: 1.4.10 + git-source: 1.1.10 + package-json: 2.4.0 + pako@0.2.9: {} pako@2.1.0: {} @@ -9416,6 +9826,15 @@ snapshots: dependencies: callsites: 3.1.0 + parse-json@2.2.0: + dependencies: + error-ex: 1.3.2 + + parse-url@1.3.11: + dependencies: + is-ssh: 1.4.0 + protocols: 1.4.8 + parseurl@1.3.3: {} path-exists@4.0.0: {} @@ -9426,6 +9845,8 @@ snapshots: path-key@4.0.0: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -9454,6 +9875,12 @@ snapshots: pidtree@0.6.0: {} + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + poly1305-js@0.4.4: dependencies: big-integer: 1.6.52 @@ -9479,6 +9906,8 @@ snapshots: prelude-ls@1.2.1: {} + prepend-http@1.0.4: {} + prettier-linter-helpers@1.0.0: dependencies: fast-diff: 1.3.0 @@ -9487,6 +9916,8 @@ snapshots: prettier@3.4.2: {} + process-nextick-args@2.0.1: {} + prom-client@15.1.3: dependencies: '@opentelemetry/api': 1.9.0 @@ -9514,6 +9945,10 @@ snapshots: '@types/node': 22.10.5 long: 5.2.4 + protocols@1.4.8: {} + + protocols@2.0.1: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -9538,6 +9973,15 @@ snapshots: quick-lru@5.1.1: {} + r-json@1.3.0: + dependencies: + w-json: 1.3.10 + + r-package-json@1.0.9: + dependencies: + package-json-path: 1.0.9 + r-json: 1.3.0 + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -9560,6 +10004,21 @@ snapshots: react@19.0.0: {} + read-all-stream@3.1.0: + dependencies: + pinkie-promise: 2.0.1 + readable-stream: 2.3.8 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -9579,6 +10038,15 @@ snapshots: dependencies: regex-utilities: 2.3.0 + registry-auth-token@3.4.0: + dependencies: + rc: 1.2.8 + safe-buffer: 5.2.1 + + registry-url@3.1.0: + dependencies: + rc: 1.2.8 + require-directory@2.1.1: {} resolve-alpn@1.2.1: {} @@ -9587,6 +10055,12 @@ snapshots: resolve-pkg-maps@1.0.0: {} + resolve@1.22.10: + dependencies: + is-core-module: 2.16.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + responselike@2.0.1: dependencies: lowercase-keys: 2.0.0 @@ -9673,6 +10147,8 @@ snapshots: dependencies: tslib: 2.8.1 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-regex-test@1.1.0: @@ -9695,6 +10171,8 @@ snapshots: semaphore@1.1.0: {} + semver@5.7.2: {} + semver@7.6.3: {} send@0.19.0: @@ -9807,6 +10285,8 @@ snapshots: ansi-styles: 6.2.1 is-fullwidth-code-point: 5.0.0 + sliced@1.0.1: {} + snake-case@3.0.4: dependencies: dot-case: 3.0.4 @@ -9857,6 +10337,20 @@ snapshots: space-separated-tokens@2.0.2: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.20 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + + spdx-license-ids@3.0.20: {} + spok@1.5.5: dependencies: ansicolors: 0.3.2 @@ -9895,6 +10389,10 @@ snapshots: get-east-asian-width: 1.3.0 strip-ansi: 7.1.0 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -9936,6 +10434,8 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + swr@2.3.0(react@19.0.0): dependencies: dequal: 2.0.3 @@ -9974,6 +10474,8 @@ snapshots: through@2.3.8: {} + timed-out@3.1.3: {} + tiny-inflate@1.0.3: {} tiny-invariant@1.3.3: {} @@ -9983,6 +10485,10 @@ snapshots: tmp: 0.2.3 optional: true + tmp@0.0.28: + dependencies: + os-tmpdir: 1.0.2 + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -10136,8 +10642,17 @@ snapshots: typescript@5.7.2: {} + typpy@2.3.13: + dependencies: + function.name: 1.0.13 + uc.micro@2.1.0: {} + ul@5.2.15: + dependencies: + deffy: 2.2.4 + typpy: 2.3.13 + undici-types@5.26.5: {} undici-types@6.19.8: {} @@ -10176,10 +10691,16 @@ snapshots: unpipe@1.0.0: {} + unzip-response@1.0.2: {} + uri-js@4.4.1: dependencies: punycode: 2.3.1 + url-parse-lax@1.0.0: + dependencies: + prepend-http: 1.0.4 + url-value-parser@2.2.0: {} usb@2.9.0: @@ -10219,6 +10740,11 @@ snapshots: v8-compile-cache-lib@3.0.1: {} + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + vary@1.1.2: {} vfile-message@4.0.2: @@ -10233,6 +10759,8 @@ snapshots: vlq@2.0.4: {} + w-json@1.3.10: {} + wcwidth@1.0.1: dependencies: defaults: 1.0.4 diff --git a/src/actions/index.ts b/src/actions/index.ts index 29cf233..ca260e1 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -59,6 +59,7 @@ import withdrawFromDriftAccountAction from "./drift/withdrawFromDriftAccount"; import driftUserAccountInfoAction from "./drift/driftUserAccountInfo"; import deriveDriftVaultAddressAction from "./drift/deriveVaultAddress"; import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate"; +import getAssetAction from "./metaplex/getAsset"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, @@ -123,6 +124,7 @@ export const ACTIONS = { DRIFT_USER_ACCOUNT_INFO_ACTION: driftUserAccountInfoAction, DERIVE_DRIFT_VAULT_ADDRESS_ACTION: deriveDriftVaultAddressAction, UPDATE_DRIFT_VAULT_DELEGATE_ACTION: updateDriftVaultDelegateAction, + GET_ASSET_ACTION: getAssetAction, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/actions/metaplex/getAsset.ts b/src/actions/metaplex/getAsset.ts new file mode 100644 index 0000000..b9940c9 --- /dev/null +++ b/src/actions/metaplex/getAsset.ts @@ -0,0 +1,51 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { get_asset } from "../../tools/metaplex"; + +const getAssetAction: Action = { + name: "GET_ASSET", + similes: [ + "fetch asset", + "retrieve asset", + "get asset details", + "fetch asset details", + ], + description: `Fetch asset details using the Metaplex DAS API.`, + examples: [ + [ + { + input: { + assetId: "Asset ID", + }, + output: { + status: "success", + message: "Asset retrieved successfully", + result: { + // Example asset details + name: "Example Asset", + symbol: "EXA", + uri: "https://example.com/asset.json", + }, + }, + explanation: "Fetch details of an asset using its ID", + }, + ], + ], + schema: z.object({ + assetId: z.string().min(1, "Asset ID is required"), + }), + handler: async (agent: SolanaAgentKit, input: Record) => { + const assetId = input.assetId; + + const result = await get_asset(agent, assetId); + + return { + status: "success", + message: "Asset retrieved successfully", + result, + }; + }, +}; + +export default getAssetAction; diff --git a/src/agent/index.ts b/src/agent/index.ts index d087931..1e42940 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -98,6 +98,7 @@ import { withdrawFromDriftVault, updateVaultDelegate, get_token_balance, + get_asset, } from "../tools"; import { Config, @@ -115,6 +116,7 @@ import { HeliusWebhookIdResponse, HeliusWebhookResponse, } from "../types"; +import { DasApiAsset } from "@metaplex-foundation/digital-asset-standard-api"; /** * Main class for interacting with Solana blockchain @@ -821,4 +823,8 @@ export class SolanaAgentKit { async updateDriftVaultDelegate(vaultAddress: string, delegate: string) { return await updateVaultDelegate(this, vaultAddress, delegate); } + + async getAsset(assetId: string): Promise { + return get_asset(this, assetId); + } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 809c340..0d9b9dd 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -115,6 +115,7 @@ import { SolanaWithdrawFromDriftAccountTool, SolanaWithdrawFromDriftVaultTool, } from "./index"; +import { SolanaGetAssetTool } from "./metaplex/get_asset"; export function createSolanaTools(solanaKit: SolanaAgentKit) { return [ @@ -208,5 +209,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaDriftVaultInfoTool(solanaKit), new SolanaWithdrawFromDriftAccountTool(solanaKit), new SolanaWithdrawFromDriftVaultTool(solanaKit), + new SolanaGetAssetTool(solanaKit), ]; } diff --git a/src/langchain/metaplex/get_asset.ts b/src/langchain/metaplex/get_asset.ts new file mode 100644 index 0000000..dc24275 --- /dev/null +++ b/src/langchain/metaplex/get_asset.ts @@ -0,0 +1,34 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaGetAssetTool extends Tool { + name = "solana_get_asset"; + description = `Fetch asset details using the Metaplex DAS API. + + Inputs (input is a JSON string): + assetId: string, eg "Asset ID" (required)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.getAsset(parsedInput.assetId); + + return JSON.stringify({ + status: "success", + message: "Asset retrieved successfully", + result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/tools/metaplex/get_asset.ts b/src/tools/metaplex/get_asset.ts new file mode 100644 index 0000000..c701806 --- /dev/null +++ b/src/tools/metaplex/get_asset.ts @@ -0,0 +1,31 @@ +import { SolanaAgentKit } from "../../index"; +import { publicKey } from "@metaplex-foundation/umi"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { + dasApi, + DasApiAsset, +} from "@metaplex-foundation/digital-asset-standard-api"; + +/** + * Fetch asset details using the Metaplex DAS API + * @param agent SolanaAgentKit instance + * @param assetId ID of the asset to fetch + * @returns Asset details + */ +export async function get_asset( + agent: SolanaAgentKit, + assetId: string, +): Promise { + try { + const endpoint = agent.connection.rpcEndpoint; + const umi = createUmi(endpoint).use(dasApi()); + const assetPublicKey = publicKey(assetId); + + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + return await umi.rpc.getAsset(assetPublicKey); + } catch (error: any) { + console.error("Error retrieving asset: ", error.message); + throw new Error(`Asset retrieval failed: ${error.message}`); + } +} diff --git a/src/tools/metaplex/index.ts b/src/tools/metaplex/index.ts index 7cdfe15..92a3efa 100644 --- a/src/tools/metaplex/index.ts +++ b/src/tools/metaplex/index.ts @@ -1,3 +1,4 @@ export * from "./deploy_collection"; export * from "./mint_nft"; export * from "./deploy_token"; +export * from "./get_asset"; From be0287c5a93822404e1938ebd9c95d32b26b38c5 Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 14:02:56 +0100 Subject: [PATCH 2/7] Implement getAssetsByAuthority tool --- src/actions/index.ts | 2 + src/actions/metaplex/getAssetByAuthority.ts | 70 +++++++++++++++++++ src/agent/index.ts | 11 ++- src/langchain/index.ts | 4 +- .../metaplex/get_asset_by_authority.ts | 39 +++++++++++ src/langchain/metaplex/index.ts | 2 + src/tools/metaplex/get_asset.ts | 5 +- src/tools/metaplex/get_assets_by_authority.ts | 15 ++++ src/tools/metaplex/index.ts | 1 + 9 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 src/actions/metaplex/getAssetByAuthority.ts create mode 100644 src/langchain/metaplex/get_asset_by_authority.ts create mode 100644 src/tools/metaplex/get_assets_by_authority.ts diff --git a/src/actions/index.ts b/src/actions/index.ts index ca260e1..32194c5 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -60,6 +60,7 @@ import driftUserAccountInfoAction from "./drift/driftUserAccountInfo"; import deriveDriftVaultAddressAction from "./drift/deriveVaultAddress"; import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate"; import getAssetAction from "./metaplex/getAsset"; +import getAssetByAuthorityAction from "./metaplex/getAssetByAuthority"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, @@ -125,6 +126,7 @@ export const ACTIONS = { DERIVE_DRIFT_VAULT_ADDRESS_ACTION: deriveDriftVaultAddressAction, UPDATE_DRIFT_VAULT_DELEGATE_ACTION: updateDriftVaultDelegateAction, GET_ASSET_ACTION: getAssetAction, + GET_ASSET_BY_AUTHORITY_ACTION: getAssetByAuthorityAction, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/actions/metaplex/getAssetByAuthority.ts b/src/actions/metaplex/getAssetByAuthority.ts new file mode 100644 index 0000000..1711c8f --- /dev/null +++ b/src/actions/metaplex/getAssetByAuthority.ts @@ -0,0 +1,70 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { get_assets_by_authority } from "../../tools/metaplex"; + +const getAssetByAuthorityAction: Action = { + name: "GET_ASSET_BY_AUTHORITY", + similes: [ + "fetch assets by authority", + "retrieve assets by authority", + "get assets by authority address", + "fetch authority assets", + ], + description: `Fetch a list of assets owned by a specific address using the Metaplex DAS API.`, + examples: [ + [ + { + input: { + authorityAddress: "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv", + limit: 10, + }, + output: { + status: "success", + message: "Assets retrieved successfully", + result: [ + // Example asset details + { + name: "Example Asset 1", + symbol: "EXA1", + uri: "https://example.com/asset1.json", + }, + { + name: "Example Asset 2", + symbol: "EXA2", + uri: "https://example.com/asset2.json", + }, + ], + }, + explanation: "Fetch a list of assets owned by a specific address", + }, + ], + ], + schema: z.object({ + authorityAddress: z.string().min(1, "Authority address is required"), + sortBy: z + .object({ + sortBy: z.enum(["created", "updated", "recentAction", "none"]), + sortDirection: z.enum(["asc", "desc"]), + }) + .optional(), + limit: z.number().optional(), + page: z.number().optional(), + before: z.string().optional(), + after: z.string().optional(), + }), + handler: async ( + agent: SolanaAgentKit, + input: z.infer, + ) => { + const result = await get_assets_by_authority(agent, input); + + return { + status: "success", + message: "Assets retrieved successfully", + result, + }; + }, +}; + +export default getAssetByAuthorityAction; diff --git a/src/agent/index.ts b/src/agent/index.ts index 1e42940..cbdd3b5 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -99,6 +99,7 @@ import { updateVaultDelegate, get_token_balance, get_asset, + get_assets_by_authority, } from "../tools"; import { Config, @@ -116,7 +117,10 @@ import { HeliusWebhookIdResponse, HeliusWebhookResponse, } from "../types"; -import { DasApiAsset } from "@metaplex-foundation/digital-asset-standard-api"; +import { + DasApiAsset, + GetAssetsByAuthorityRpcInput, +} from "@metaplex-foundation/digital-asset-standard-api"; /** * Main class for interacting with Solana blockchain @@ -827,4 +831,9 @@ export class SolanaAgentKit { async getAsset(assetId: string): Promise { return get_asset(this, assetId); } + async getAssetsByAuthority( + params: GetAssetsByAuthorityRpcInput, + ): Promise { + return get_assets_by_authority(this, params); + } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 0d9b9dd..78b8b11 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -114,8 +114,9 @@ import { SolanaUpdateDriftVaultTool, SolanaWithdrawFromDriftAccountTool, SolanaWithdrawFromDriftVaultTool, + SolanaGetAssetTool, + SolanaGetAssetsByAuthorityTool, } from "./index"; -import { SolanaGetAssetTool } from "./metaplex/get_asset"; export function createSolanaTools(solanaKit: SolanaAgentKit) { return [ @@ -210,5 +211,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaWithdrawFromDriftAccountTool(solanaKit), new SolanaWithdrawFromDriftVaultTool(solanaKit), new SolanaGetAssetTool(solanaKit), + new SolanaGetAssetsByAuthorityTool(solanaKit), ]; } diff --git a/src/langchain/metaplex/get_asset_by_authority.ts b/src/langchain/metaplex/get_asset_by_authority.ts new file mode 100644 index 0000000..17f1e8f --- /dev/null +++ b/src/langchain/metaplex/get_asset_by_authority.ts @@ -0,0 +1,39 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaGetAssetsByAuthorityTool extends Tool { + name = "solana_get_assets_by_authority"; + description = `Fetch a list of assets owned by a specific address using the Metaplex DAS API. + + Inputs (input is a JSON string): + authorityAddress: string, eg "N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw" (required) + sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) + limit: number (optional) + page: number (optional) + before: string (optional) + after: string (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.getAssetsByAuthority(parsedInput); + + return JSON.stringify({ + status: "success", + message: "Assets retrieved successfully", + result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/metaplex/index.ts b/src/langchain/metaplex/index.ts index 7cdfe15..3635d03 100644 --- a/src/langchain/metaplex/index.ts +++ b/src/langchain/metaplex/index.ts @@ -1,3 +1,5 @@ export * from "./deploy_collection"; export * from "./mint_nft"; export * from "./deploy_token"; +export * from "./get_asset"; +export * from "./get_asset_by_authority"; diff --git a/src/tools/metaplex/get_asset.ts b/src/tools/metaplex/get_asset.ts index c701806..768caad 100644 --- a/src/tools/metaplex/get_asset.ts +++ b/src/tools/metaplex/get_asset.ts @@ -19,11 +19,8 @@ export async function get_asset( try { const endpoint = agent.connection.rpcEndpoint; const umi = createUmi(endpoint).use(dasApi()); - const assetPublicKey = publicKey(assetId); - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - return await umi.rpc.getAsset(assetPublicKey); + return await umi.rpc.getAsset(publicKey(assetId)); } catch (error: any) { console.error("Error retrieving asset: ", error.message); throw new Error(`Asset retrieval failed: ${error.message}`); diff --git a/src/tools/metaplex/get_assets_by_authority.ts b/src/tools/metaplex/get_assets_by_authority.ts new file mode 100644 index 0000000..1ddee15 --- /dev/null +++ b/src/tools/metaplex/get_assets_by_authority.ts @@ -0,0 +1,15 @@ +import { SolanaAgentKit } from "../../agent"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { + dasApi, + GetAssetsByAuthorityRpcInput, +} from "@metaplex-foundation/digital-asset-standard-api"; + +export async function get_assets_by_authority( + agent: SolanaAgentKit, + params: GetAssetsByAuthorityRpcInput, +) { + const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); + const assets = await umi.rpc.getAssetsByAuthority(params); + return assets.items; +} diff --git a/src/tools/metaplex/index.ts b/src/tools/metaplex/index.ts index 92a3efa..0fc3fa7 100644 --- a/src/tools/metaplex/index.ts +++ b/src/tools/metaplex/index.ts @@ -2,3 +2,4 @@ export * from "./deploy_collection"; export * from "./mint_nft"; export * from "./deploy_token"; export * from "./get_asset"; +export * from "./get_assets_by_authority"; From a4774374b3d07e87f16532a3456b6da66c8ff78d Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 14:13:30 +0100 Subject: [PATCH 3/7] Implement getAssetsByCreator tool --- src/actions/index.ts | 6 +- src/actions/metaplex/getAssetByAuthority.ts | 70 ------------ src/actions/metaplex/getAssetsByAuthority.ts | 103 +++++++++++++++++ src/actions/metaplex/getAssetsByCreator.ts | 105 ++++++++++++++++++ src/agent/index.ts | 10 +- src/langchain/index.ts | 2 + ...uthority.ts => get_assets_by_authority.ts} | 0 .../metaplex/get_assets_by_creator.ts | 40 +++++++ src/langchain/metaplex/index.ts | 3 +- src/tools/metaplex/get_assets_by_authority.ts | 3 +- src/tools/metaplex/get_assets_by_creator.ts | 14 +++ src/tools/metaplex/index.ts | 1 + 12 files changed, 281 insertions(+), 76 deletions(-) delete mode 100644 src/actions/metaplex/getAssetByAuthority.ts create mode 100644 src/actions/metaplex/getAssetsByAuthority.ts create mode 100644 src/actions/metaplex/getAssetsByCreator.ts rename src/langchain/metaplex/{get_asset_by_authority.ts => get_assets_by_authority.ts} (100%) create mode 100644 src/langchain/metaplex/get_assets_by_creator.ts create mode 100644 src/tools/metaplex/get_assets_by_creator.ts diff --git a/src/actions/index.ts b/src/actions/index.ts index 32194c5..b9ff530 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -60,7 +60,8 @@ import driftUserAccountInfoAction from "./drift/driftUserAccountInfo"; import deriveDriftVaultAddressAction from "./drift/deriveVaultAddress"; import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate"; import getAssetAction from "./metaplex/getAsset"; -import getAssetByAuthorityAction from "./metaplex/getAssetByAuthority"; +import getAssetsByAuthorityAction from "./metaplex/getAssetsByAuthority"; +import getAssetsByCreatorAction from "./metaplex/getAssetsByCreator"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, @@ -126,7 +127,8 @@ export const ACTIONS = { DERIVE_DRIFT_VAULT_ADDRESS_ACTION: deriveDriftVaultAddressAction, UPDATE_DRIFT_VAULT_DELEGATE_ACTION: updateDriftVaultDelegateAction, GET_ASSET_ACTION: getAssetAction, - GET_ASSET_BY_AUTHORITY_ACTION: getAssetByAuthorityAction, + GET_ASSETS_BY_AUTHORITY_ACTION: getAssetsByAuthorityAction, + GET_ASSETS_BY_CREATOR_ACTION: getAssetsByCreatorAction, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/actions/metaplex/getAssetByAuthority.ts b/src/actions/metaplex/getAssetByAuthority.ts deleted file mode 100644 index 1711c8f..0000000 --- a/src/actions/metaplex/getAssetByAuthority.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Action } from "../../types/action"; -import { SolanaAgentKit } from "../../agent"; -import { z } from "zod"; -import { get_assets_by_authority } from "../../tools/metaplex"; - -const getAssetByAuthorityAction: Action = { - name: "GET_ASSET_BY_AUTHORITY", - similes: [ - "fetch assets by authority", - "retrieve assets by authority", - "get assets by authority address", - "fetch authority assets", - ], - description: `Fetch a list of assets owned by a specific address using the Metaplex DAS API.`, - examples: [ - [ - { - input: { - authorityAddress: "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv", - limit: 10, - }, - output: { - status: "success", - message: "Assets retrieved successfully", - result: [ - // Example asset details - { - name: "Example Asset 1", - symbol: "EXA1", - uri: "https://example.com/asset1.json", - }, - { - name: "Example Asset 2", - symbol: "EXA2", - uri: "https://example.com/asset2.json", - }, - ], - }, - explanation: "Fetch a list of assets owned by a specific address", - }, - ], - ], - schema: z.object({ - authorityAddress: z.string().min(1, "Authority address is required"), - sortBy: z - .object({ - sortBy: z.enum(["created", "updated", "recentAction", "none"]), - sortDirection: z.enum(["asc", "desc"]), - }) - .optional(), - limit: z.number().optional(), - page: z.number().optional(), - before: z.string().optional(), - after: z.string().optional(), - }), - handler: async ( - agent: SolanaAgentKit, - input: z.infer, - ) => { - const result = await get_assets_by_authority(agent, input); - - return { - status: "success", - message: "Assets retrieved successfully", - result, - }; - }, -}; - -export default getAssetByAuthorityAction; diff --git a/src/actions/metaplex/getAssetsByAuthority.ts b/src/actions/metaplex/getAssetsByAuthority.ts new file mode 100644 index 0000000..0b10b94 --- /dev/null +++ b/src/actions/metaplex/getAssetsByAuthority.ts @@ -0,0 +1,103 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { get_assets_by_authority } from "../../tools/metaplex"; + +const getAssetsByAuthorityAction: Action = { + name: "GET_ASSETS_BY_AUTHORITY", + similes: [ + "fetch assets by authority", + "retrieve assets by authority", + "get assets by authority address", + "fetch authority assets", + ], + description: `Fetch a list of assets owned by a specific address using the Metaplex DAS API.`, + examples: [ + [ + { + input: { + authorityAddress: "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv", + limit: 10, + }, + output: { + status: "success", + message: "Assets retrieved successfully", + result: { + total: 2, + limit: 10, + items: [ + { + interface: "V1_NFT", + id: "ExampleAssetId1", + content: { + json_uri: "https://example.com/asset1.json", + metadata: { + name: "Example Asset 1", + symbol: "EXA1", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + { + interface: "V1_NFT", + id: "ExampleAssetId2", + content: { + json_uri: "https://example.com/asset2.json", + metadata: { + name: "Example Asset 2", + symbol: "EXA2", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + ], + }, + }, + explanation: "Fetch a list of assets owned by a specific address", + }, + ], + ], + schema: z.object({ + authorityAddress: z.string().min(1, "Authority address is required"), + sortBy: z + .object({ + sortBy: z.enum(["created", "updated", "recentAction", "none"]), + sortDirection: z.enum(["asc", "desc"]), + }) + .optional(), + limit: z.number().optional(), + page: z.number().optional(), + before: z.string().optional(), + after: z.string().optional(), + }), + handler: async ( + agent: SolanaAgentKit, + input: z.infer, + ) => { + const result = await get_assets_by_authority(agent, input); + + return { + status: "success", + message: "Assets retrieved successfully", + result, + }; + }, +}; + +export default getAssetsByAuthorityAction; diff --git a/src/actions/metaplex/getAssetsByCreator.ts b/src/actions/metaplex/getAssetsByCreator.ts new file mode 100644 index 0000000..e0fdeed --- /dev/null +++ b/src/actions/metaplex/getAssetsByCreator.ts @@ -0,0 +1,105 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { get_assets_by_creator } from "../../tools/metaplex"; + +const getAssetsByCreatorAction: Action = { + name: "GET_ASSETS_BY_CREATOR", + similes: [ + "fetch assets by creator", + "retrieve assets by creator", + "get assets by creator address", + "fetch creator assets", + ], + description: `Fetch a list of assets created by a specific address using the Metaplex DAS API.`, + examples: [ + [ + { + input: { + creatorAddress: "D3XrkNZz6wx6cofot7Zohsf2KSsu2ArngNk8VqU9cTY3", + onlyVerified: true, + limit: 10, + }, + output: { + status: "success", + message: "Assets retrieved successfully", + result: { + total: 2, + limit: 10, + items: [ + { + interface: "V1_NFT", + id: "ExampleAssetId1", + content: { + json_uri: "https://example.com/asset1.json", + metadata: { + name: "Example Asset 1", + symbol: "EXA1", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + { + interface: "V1_NFT", + id: "ExampleAssetId2", + content: { + json_uri: "https://example.com/asset2.json", + metadata: { + name: "Example Asset 2", + symbol: "EXA2", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + ], + }, + }, + explanation: "Fetch a list of assets created by a specific address", + }, + ], + ], + schema: z.object({ + creatorAddress: z.string().min(1, "Creator address is required"), + onlyVerified: z.boolean(), + sortBy: z + .object({ + sortBy: z.enum(["created", "updated", "recentAction", "none"]), + sortDirection: z.enum(["asc", "desc"]), + }) + .optional(), + limit: z.number().optional(), + page: z.number().optional(), + before: z.string().optional(), + after: z.string().optional(), + }), + handler: async ( + agent: SolanaAgentKit, + input: z.infer, + ) => { + const result = await get_assets_by_creator(agent, input); + + return { + status: "success", + message: "Assets retrieved successfully", + result, + }; + }, +}; + +export default getAssetsByCreatorAction; diff --git a/src/agent/index.ts b/src/agent/index.ts index cbdd3b5..60a56b1 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -119,8 +119,11 @@ import { } from "../types"; import { DasApiAsset, + DasApiAssetList, GetAssetsByAuthorityRpcInput, + GetAssetsByCreatorRpcInput, } from "@metaplex-foundation/digital-asset-standard-api"; +import { get_assets_by_creator } from "../tools/metaplex/get_assets_by_creator"; /** * Main class for interacting with Solana blockchain @@ -833,7 +836,12 @@ export class SolanaAgentKit { } async getAssetsByAuthority( params: GetAssetsByAuthorityRpcInput, - ): Promise { + ): Promise { return get_assets_by_authority(this, params); } + async getAssetsByCreator( + params: GetAssetsByCreatorRpcInput, + ): Promise { + return get_assets_by_creator(this, params); + } } diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 78b8b11..22ee136 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -116,6 +116,7 @@ import { SolanaWithdrawFromDriftVaultTool, SolanaGetAssetTool, SolanaGetAssetsByAuthorityTool, + SolanaGetAssetsByCreatorTool, } from "./index"; export function createSolanaTools(solanaKit: SolanaAgentKit) { @@ -212,5 +213,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaWithdrawFromDriftVaultTool(solanaKit), new SolanaGetAssetTool(solanaKit), new SolanaGetAssetsByAuthorityTool(solanaKit), + new SolanaGetAssetsByCreatorTool(solanaKit), ]; } diff --git a/src/langchain/metaplex/get_asset_by_authority.ts b/src/langchain/metaplex/get_assets_by_authority.ts similarity index 100% rename from src/langchain/metaplex/get_asset_by_authority.ts rename to src/langchain/metaplex/get_assets_by_authority.ts diff --git a/src/langchain/metaplex/get_assets_by_creator.ts b/src/langchain/metaplex/get_assets_by_creator.ts new file mode 100644 index 0000000..84def56 --- /dev/null +++ b/src/langchain/metaplex/get_assets_by_creator.ts @@ -0,0 +1,40 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaGetAssetsByCreatorTool extends Tool { + name = "solana_get_assets_by_creator"; + description = `Fetch a list of assets created by a specific address using the Metaplex DAS API. + + Inputs (input is a JSON string): + creatorAddress: string, eg "N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw" (required) + onlyVerified: boolean (optional) + sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) + limit: number (optional) + page: number (optional) + before: string (optional) + after: string (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.getAssetsByCreator(parsedInput); + + return JSON.stringify({ + status: "success", + message: "Assets retrieved successfully", + result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/langchain/metaplex/index.ts b/src/langchain/metaplex/index.ts index 3635d03..41d11c7 100644 --- a/src/langchain/metaplex/index.ts +++ b/src/langchain/metaplex/index.ts @@ -2,4 +2,5 @@ export * from "./deploy_collection"; export * from "./mint_nft"; export * from "./deploy_token"; export * from "./get_asset"; -export * from "./get_asset_by_authority"; +export * from "./get_assets_by_authority"; +export * from "./get_assets_by_creator"; diff --git a/src/tools/metaplex/get_assets_by_authority.ts b/src/tools/metaplex/get_assets_by_authority.ts index 1ddee15..b6f1199 100644 --- a/src/tools/metaplex/get_assets_by_authority.ts +++ b/src/tools/metaplex/get_assets_by_authority.ts @@ -10,6 +10,5 @@ export async function get_assets_by_authority( params: GetAssetsByAuthorityRpcInput, ) { const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); - const assets = await umi.rpc.getAssetsByAuthority(params); - return assets.items; + return await umi.rpc.getAssetsByAuthority(params); } diff --git a/src/tools/metaplex/get_assets_by_creator.ts b/src/tools/metaplex/get_assets_by_creator.ts new file mode 100644 index 0000000..64a4ed3 --- /dev/null +++ b/src/tools/metaplex/get_assets_by_creator.ts @@ -0,0 +1,14 @@ +import { SolanaAgentKit } from "../../agent"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { + dasApi, + GetAssetsByCreatorRpcInput, +} from "@metaplex-foundation/digital-asset-standard-api"; + +export async function get_assets_by_creator( + agent: SolanaAgentKit, + params: GetAssetsByCreatorRpcInput, +) { + const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); + return await umi.rpc.getAssetsByCreator(params); +} diff --git a/src/tools/metaplex/index.ts b/src/tools/metaplex/index.ts index 0fc3fa7..41d11c7 100644 --- a/src/tools/metaplex/index.ts +++ b/src/tools/metaplex/index.ts @@ -3,3 +3,4 @@ export * from "./mint_nft"; export * from "./deploy_token"; export * from "./get_asset"; export * from "./get_assets_by_authority"; +export * from "./get_assets_by_creator"; From 4d213665d3291cfedef3b265c7df2743f48ae2c3 Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 14:22:50 +0100 Subject: [PATCH 4/7] Implement searchAssets tool --- src/actions/index.ts | 2 + src/actions/metaplex/searchAssets.ts | 113 ++++++++++++++++++ src/agent/index.ts | 7 +- src/langchain/metaplex/index.ts | 1 + src/langchain/metaplex/search_assets.ts | 57 +++++++++ src/tools/metaplex/get_assets_by_authority.ts | 6 + src/tools/metaplex/get_assets_by_creator.ts | 6 + src/tools/metaplex/index.ts | 1 + src/tools/metaplex/search_assets.ts | 20 ++++ 9 files changed, 212 insertions(+), 1 deletion(-) create mode 100644 src/actions/metaplex/searchAssets.ts create mode 100644 src/langchain/metaplex/search_assets.ts create mode 100644 src/tools/metaplex/search_assets.ts diff --git a/src/actions/index.ts b/src/actions/index.ts index b9ff530..290d021 100644 --- a/src/actions/index.ts +++ b/src/actions/index.ts @@ -62,6 +62,7 @@ import updateDriftVaultDelegateAction from "./drift/updateDriftVaultDelegate"; import getAssetAction from "./metaplex/getAsset"; import getAssetsByAuthorityAction from "./metaplex/getAssetsByAuthority"; import getAssetsByCreatorAction from "./metaplex/getAssetsByCreator"; +import searchAssetsAction from "./metaplex/searchAssets"; export const ACTIONS = { WALLET_ADDRESS_ACTION: getWalletAddressAction, @@ -129,6 +130,7 @@ export const ACTIONS = { GET_ASSET_ACTION: getAssetAction, GET_ASSETS_BY_AUTHORITY_ACTION: getAssetsByAuthorityAction, GET_ASSETS_BY_CREATOR_ACTION: getAssetsByCreatorAction, + SEARCH_ASSETS_ACTION: searchAssetsAction, }; export type { Action, ActionExample, Handler } from "../types/action"; diff --git a/src/actions/metaplex/searchAssets.ts b/src/actions/metaplex/searchAssets.ts new file mode 100644 index 0000000..e31b738 --- /dev/null +++ b/src/actions/metaplex/searchAssets.ts @@ -0,0 +1,113 @@ +import { Action } from "../../types/action"; +import { SolanaAgentKit } from "../../agent"; +import { z } from "zod"; +import { search_assets } from "../../tools/metaplex"; +import { publicKey } from "@metaplex-foundation/umi"; + +const searchAssetsAction: Action = { + name: "SEARCH_ASSETS", + similes: ["search assets", "find assets", "lookup assets", "query assets"], + description: `Search for assets using various criteria with the Metaplex DAS API.`, + examples: [ + [ + { + input: { + owner: publicKey("N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw"), + jsonUri: + "https://arweave.net/c9aGs5fOk7gD4wWnSvmzeqgtfxAGRgtI1jYzvl8-IVs/chiaki-violet-azure-common.json", + }, + output: { + status: "success", + message: "Assets retrieved successfully", + result: { + total: 2, + limit: 10, + items: [ + { + interface: "V1_NFT", + id: "ExampleAssetId1", + content: { + json_uri: "https://example.com/asset1.json", + metadata: { + name: "Example Asset 1", + symbol: "EXA1", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + { + interface: "V1_NFT", + id: "ExampleAssetId2", + content: { + json_uri: "https://example.com/asset2.json", + metadata: { + name: "Example Asset 2", + symbol: "EXA2", + }, + }, + authorities: [], + compression: {}, + grouping: [], + royalty: {}, + creators: [], + ownership: {}, + supply: {}, + mutable: true, + burnt: false, + }, + ], + }, + }, + explanation: "Search for assets using various criteria", + }, + ], + ], + schema: z.object({ + negate: z.boolean().optional(), + conditionType: z.enum(["all", "any"]).optional(), + interface: z.string().optional(), + jsonUri: z.string().optional(), + owner: z.string().optional(), + ownerType: z.enum(["single", "token"]).optional(), + creator: z.string().optional(), + creatorVerified: z.boolean().optional(), + authority: z.string().optional(), + grouping: z.tuple([z.string(), z.string()]).optional(), + delegate: z.string().optional(), + frozen: z.boolean().optional(), + supply: z.number().optional(), + supplyMint: z.string().optional(), + compressed: z.boolean().optional(), + compressible: z.boolean().optional(), + royaltyModel: z.enum(["creators", "fanout", "single"]).optional(), + royaltyTarget: z.string().optional(), + royaltyAmount: z.number().optional(), + burnt: z.boolean().optional(), + limit: z.number().optional(), + page: z.number().optional(), + before: z.string().optional(), + after: z.string().optional(), + }), + handler: async ( + agent: SolanaAgentKit, + input: z.infer, + ) => { + const result = await search_assets(agent, input); + + return { + status: "success", + message: "Assets retrieved successfully", + result, + }; + }, +}; + +export default searchAssetsAction; diff --git a/src/agent/index.ts b/src/agent/index.ts index 60a56b1..4bc5331 100644 --- a/src/agent/index.ts +++ b/src/agent/index.ts @@ -100,6 +100,8 @@ import { get_token_balance, get_asset, get_assets_by_authority, + get_assets_by_creator, + search_assets, } from "../tools"; import { Config, @@ -122,8 +124,8 @@ import { DasApiAssetList, GetAssetsByAuthorityRpcInput, GetAssetsByCreatorRpcInput, + SearchAssetsRpcInput, } from "@metaplex-foundation/digital-asset-standard-api"; -import { get_assets_by_creator } from "../tools/metaplex/get_assets_by_creator"; /** * Main class for interacting with Solana blockchain @@ -844,4 +846,7 @@ export class SolanaAgentKit { ): Promise { return get_assets_by_creator(this, params); } + async searchAssets(params: SearchAssetsRpcInput): Promise { + return search_assets(this, params); + } } diff --git a/src/langchain/metaplex/index.ts b/src/langchain/metaplex/index.ts index 41d11c7..d8ba77e 100644 --- a/src/langchain/metaplex/index.ts +++ b/src/langchain/metaplex/index.ts @@ -4,3 +4,4 @@ export * from "./deploy_token"; export * from "./get_asset"; export * from "./get_assets_by_authority"; export * from "./get_assets_by_creator"; +export * from "./search_assets"; diff --git a/src/langchain/metaplex/search_assets.ts b/src/langchain/metaplex/search_assets.ts new file mode 100644 index 0000000..10c3b44 --- /dev/null +++ b/src/langchain/metaplex/search_assets.ts @@ -0,0 +1,57 @@ +import { Tool } from "langchain/tools"; +import { SolanaAgentKit } from "../../agent"; + +export class SolanaSearchAssetsTool extends Tool { + name = "solana_search_assets"; + description = `Search for assets using various criteria with the Metaplex DAS API. + + Inputs (input is a JSON string): + negate: boolean (optional) + conditionType: "all" | "any" (optional) + interface: string (optional) + jsonUri: string (optional) + owner: string (optional) + ownerType: "single" | "token" (optional) + creator: string (optional) + creatorVerified: boolean (optional) + authority: string (optional) + grouping: [string, string] (optional) + delegate: string (optional) + frozen: boolean (optional) + supply: number (optional) + supplyMint: string (optional) + compressed: boolean (optional) + compressible: boolean (optional) + royaltyModel: "creators" | "fanout" | "single" (optional) + royaltyTarget: string (optional) + royaltyAmount: number (optional) + burnt: boolean (optional) + limit: number (optional) + page: number (optional) + before: string (optional) + after: string (optional)`; + + constructor(private solanaKit: SolanaAgentKit) { + super(); + } + + protected async _call(input: string): Promise { + try { + const parsedInput = JSON.parse(input); + + const result = await this.solanaKit.searchAssets(parsedInput); + + return JSON.stringify({ + status: "success", + message: "Assets retrieved successfully", + result, + }); + } catch (error: any) { + return JSON.stringify({ + status: "error", + message: error.message, + code: error.code || "UNKNOWN_ERROR", + }); + } + } +} diff --git a/src/tools/metaplex/get_assets_by_authority.ts b/src/tools/metaplex/get_assets_by_authority.ts index b6f1199..38ac3ee 100644 --- a/src/tools/metaplex/get_assets_by_authority.ts +++ b/src/tools/metaplex/get_assets_by_authority.ts @@ -5,6 +5,12 @@ import { GetAssetsByAuthorityRpcInput, } from "@metaplex-foundation/digital-asset-standard-api"; +/** + * Fetch assets by authority using the Metaplex DAS API + * @param agent SolanaAgentKit instance + * @param params Parameters for fetching assets by authority + * @returns List of assets associated with the given authority + */ export async function get_assets_by_authority( agent: SolanaAgentKit, params: GetAssetsByAuthorityRpcInput, diff --git a/src/tools/metaplex/get_assets_by_creator.ts b/src/tools/metaplex/get_assets_by_creator.ts index 64a4ed3..48eec44 100644 --- a/src/tools/metaplex/get_assets_by_creator.ts +++ b/src/tools/metaplex/get_assets_by_creator.ts @@ -5,6 +5,12 @@ import { GetAssetsByCreatorRpcInput, } from "@metaplex-foundation/digital-asset-standard-api"; +/** + * Fetch assets by creator using the Metaplex DAS API + * @param agent SolanaAgentKit instance + * @param params Parameters for fetching assets by creator + * @returns List of assets created by the specified creator + */ export async function get_assets_by_creator( agent: SolanaAgentKit, params: GetAssetsByCreatorRpcInput, diff --git a/src/tools/metaplex/index.ts b/src/tools/metaplex/index.ts index 41d11c7..d8ba77e 100644 --- a/src/tools/metaplex/index.ts +++ b/src/tools/metaplex/index.ts @@ -4,3 +4,4 @@ export * from "./deploy_token"; export * from "./get_asset"; export * from "./get_assets_by_authority"; export * from "./get_assets_by_creator"; +export * from "./search_assets"; diff --git a/src/tools/metaplex/search_assets.ts b/src/tools/metaplex/search_assets.ts new file mode 100644 index 0000000..9a74197 --- /dev/null +++ b/src/tools/metaplex/search_assets.ts @@ -0,0 +1,20 @@ +import { SolanaAgentKit } from "../../agent"; +import { createUmi } from "@metaplex-foundation/umi-bundle-defaults"; +import { + dasApi, + SearchAssetsRpcInput, +} from "@metaplex-foundation/digital-asset-standard-api"; + +/** + * Search for assets using the Metaplex DAS API + * @param agent SolanaAgentKit instance + * @param params Parameters for searching assets + * @returns List of assets matching the search criteria + */ +export async function search_assets( + agent: SolanaAgentKit, + params: SearchAssetsRpcInput, +) { + const umi = createUmi(agent.connection.rpcEndpoint).use(dasApi()); + return await umi.rpc.searchAssets(params); +} From 611de50acd724a58b48e00a2d0434f666abf7c46 Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 14:43:25 +0100 Subject: [PATCH 5/7] Tool fixes and updates --- src/actions/metaplex/getAssetsByAuthority.ts | 4 ++-- src/actions/metaplex/getAssetsByCreator.ts | 4 ++-- src/langchain/index.ts | 2 ++ src/langchain/metaplex/get_assets_by_authority.ts | 2 +- src/langchain/metaplex/get_assets_by_creator.ts | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/actions/metaplex/getAssetsByAuthority.ts b/src/actions/metaplex/getAssetsByAuthority.ts index 0b10b94..1eebc1e 100644 --- a/src/actions/metaplex/getAssetsByAuthority.ts +++ b/src/actions/metaplex/getAssetsByAuthority.ts @@ -16,7 +16,7 @@ const getAssetsByAuthorityAction: Action = { [ { input: { - authorityAddress: "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv", + authority: "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv", limit: 10, }, output: { @@ -74,7 +74,7 @@ const getAssetsByAuthorityAction: Action = { ], ], schema: z.object({ - authorityAddress: z.string().min(1, "Authority address is required"), + authority: z.string().min(1, "Authority address is required"), sortBy: z .object({ sortBy: z.enum(["created", "updated", "recentAction", "none"]), diff --git a/src/actions/metaplex/getAssetsByCreator.ts b/src/actions/metaplex/getAssetsByCreator.ts index e0fdeed..3bd0584 100644 --- a/src/actions/metaplex/getAssetsByCreator.ts +++ b/src/actions/metaplex/getAssetsByCreator.ts @@ -16,7 +16,7 @@ const getAssetsByCreatorAction: Action = { [ { input: { - creatorAddress: "D3XrkNZz6wx6cofot7Zohsf2KSsu2ArngNk8VqU9cTY3", + creator: "D3XrkNZz6wx6cofot7Zohsf2KSsu2ArngNk8VqU9cTY3", onlyVerified: true, limit: 10, }, @@ -75,7 +75,7 @@ const getAssetsByCreatorAction: Action = { ], ], schema: z.object({ - creatorAddress: z.string().min(1, "Creator address is required"), + creator: z.string().min(1, "Creator address is required"), onlyVerified: z.boolean(), sortBy: z .object({ diff --git a/src/langchain/index.ts b/src/langchain/index.ts index 22ee136..7de2e0b 100644 --- a/src/langchain/index.ts +++ b/src/langchain/index.ts @@ -117,6 +117,7 @@ import { SolanaGetAssetTool, SolanaGetAssetsByAuthorityTool, SolanaGetAssetsByCreatorTool, + SolanaSearchAssetsTool, } from "./index"; export function createSolanaTools(solanaKit: SolanaAgentKit) { @@ -214,5 +215,6 @@ export function createSolanaTools(solanaKit: SolanaAgentKit) { new SolanaGetAssetTool(solanaKit), new SolanaGetAssetsByAuthorityTool(solanaKit), new SolanaGetAssetsByCreatorTool(solanaKit), + new SolanaSearchAssetsTool(solanaKit), ]; } diff --git a/src/langchain/metaplex/get_assets_by_authority.ts b/src/langchain/metaplex/get_assets_by_authority.ts index 17f1e8f..9065f74 100644 --- a/src/langchain/metaplex/get_assets_by_authority.ts +++ b/src/langchain/metaplex/get_assets_by_authority.ts @@ -6,7 +6,7 @@ export class SolanaGetAssetsByAuthorityTool extends Tool { description = `Fetch a list of assets owned by a specific address using the Metaplex DAS API. Inputs (input is a JSON string): - authorityAddress: string, eg "N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw" (required) + authority: string, eg "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv" (required) sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) limit: number (optional) page: number (optional) diff --git a/src/langchain/metaplex/get_assets_by_creator.ts b/src/langchain/metaplex/get_assets_by_creator.ts index 84def56..bbd2a7b 100644 --- a/src/langchain/metaplex/get_assets_by_creator.ts +++ b/src/langchain/metaplex/get_assets_by_creator.ts @@ -6,7 +6,7 @@ export class SolanaGetAssetsByCreatorTool extends Tool { description = `Fetch a list of assets created by a specific address using the Metaplex DAS API. Inputs (input is a JSON string): - creatorAddress: string, eg "N4f6zftYsuu4yT7icsjLwh4i6pB1zvvKbseHj2NmSQw" (required) + creator: string, eg "D3XrkNZz6wx6cofot7Zohsf2KSsu2ArngNk8VqU9cTY3" (required) onlyVerified: boolean (optional) sortBy: { sortBy: "created" | "updated" | "recentAction" | "none", sortDirection: "asc" | "desc" } (optional) limit: number (optional) From 7df99ae8974550aac35b24d806038ef47002b4a7 Mon Sep 17 00:00:00 2001 From: Damjan Date: Thu, 16 Jan 2025 16:51:10 +0100 Subject: [PATCH 6/7] Update README.md --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 6fdedb8..a61cc12 100644 --- a/README.md +++ b/README.md @@ -471,6 +471,12 @@ Update the address a drift vault is delegated to. const signature = await agent.updateDriftVaultDelegate("41Y8C4oxk4zgJT1KXyQr35UhZcfsp5mP86Z2G7UUzojU", "new-address") ``` +### Get a Solana asset by its ID + +```typescript +const asset = await agent.getAsset("41Y8C4oxk4zgJT1KXyQr35UhZcfsp5mP86Z2G7UUzojU") +``` + ## Examples ### LangGraph Multi-Agent System @@ -494,6 +500,7 @@ The toolkit relies on several key Solana and Metaplex libraries: - @solana/web3.js - @solana/spl-token +- @metaplex-foundation/digital-asset-standard-api - @metaplex-foundation/mpl-token-metadata - @metaplex-foundation/mpl-core - @metaplex-foundation/umi From 331482ac6a7a8638464974650dcb159b8cbffc8e Mon Sep 17 00:00:00 2001 From: Damjan Date: Sat, 18 Jan 2025 10:06:09 +0100 Subject: [PATCH 7/7] Update get_asset.ts --- src/langchain/metaplex/get_asset.ts | 10 ++++------ src/langchain/metaplex/get_assets_by_authority.ts | 2 +- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/langchain/metaplex/get_asset.ts b/src/langchain/metaplex/get_asset.ts index dc24275..897ab30 100644 --- a/src/langchain/metaplex/get_asset.ts +++ b/src/langchain/metaplex/get_asset.ts @@ -3,10 +3,10 @@ import { SolanaAgentKit } from "../../agent"; export class SolanaGetAssetTool extends Tool { name = "solana_get_asset"; - description = `Fetch asset details using the Metaplex DAS API. + description = `Fetch asset details for a given asset ID using the Metaplex DAS API. - Inputs (input is a JSON string): - assetId: string, eg "Asset ID" (required)`; + Inputs (input is a string): + eg "8TrvJBRa6Pzb9BDadqroHhWTHxaxK8Ws8r91oZ2jxaVV" (required)`; constructor(private solanaKit: SolanaAgentKit) { super(); @@ -14,9 +14,7 @@ export class SolanaGetAssetTool extends Tool { protected async _call(input: string): Promise { try { - const parsedInput = JSON.parse(input); - - const result = await this.solanaKit.getAsset(parsedInput.assetId); + const result = await this.solanaKit.getAsset(input); return JSON.stringify({ status: "success", diff --git a/src/langchain/metaplex/get_assets_by_authority.ts b/src/langchain/metaplex/get_assets_by_authority.ts index 9065f74..9894d71 100644 --- a/src/langchain/metaplex/get_assets_by_authority.ts +++ b/src/langchain/metaplex/get_assets_by_authority.ts @@ -3,7 +3,7 @@ import { SolanaAgentKit } from "../../agent"; export class SolanaGetAssetsByAuthorityTool extends Tool { name = "solana_get_assets_by_authority"; - description = `Fetch a list of assets owned by a specific address using the Metaplex DAS API. + description = `Fetch a list of assets by a specific authority address using the Metaplex DAS API. Inputs (input is a JSON string): authority: string, eg "mRdta4rc2RtsxEUDYuvKLamMZAdW6qHcwuq866Skxxv" (required)