diff --git a/eslint.config.mjs b/eslint.config.mjs index 94b8c83..0e4ed09 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -27,6 +27,10 @@ const eslintConfig = defineConfig([ "next-env.d.ts", // Open-source packages have their own lint config "packages/**", + // Trigger.dev build artifacts + ".trigger/**", + // Claude Code agent worktrees + ".claude/worktrees/**", ]), ]); diff --git a/package.json b/package.json index a2b29b6..20c6323 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "publish:all": "pnpm run publish:sdk && pnpm run publish:mcp && pnpm run publish:facilitator" }, "dependencies": { + "8004-solana": "^0.7.9", "@ai-sdk/anthropic": "^3.0.44", "@fal-ai/serverless-client": "^0.15.0", "@hono/zod-validator": "^0.7.6", @@ -51,6 +52,10 @@ "@trigger.dev/sdk": "^4.4.1", "@upstash/ratelimit": "^2.0.8", "@upstash/redis": "^1.36.2", + "@x402/core": "^2.3.1", + "@x402/fetch": "^2.6.0", + "@x402/hono": "^2.6.0", + "@x402/svm": "^2.3.0", "ai": "^6.0.86", "bs58": "^6.0.0", "class-variance-authority": "^0.7.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 483ce3a..5c53cc8 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -12,6 +12,9 @@ importers: .: dependencies: + 8004-solana: + specifier: ^0.7.9 + version: 0.7.9(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) '@ai-sdk/anthropic': specifier: ^3.0.44 version: 3.0.44(zod@4.3.6) @@ -74,7 +77,7 @@ importers: version: 0.6.32(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-wallets': specifier: ^0.19.37 - version: 0.19.37(@azure/identity@4.13.0)(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10)))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.2.14)(@upstash/redis@1.36.2)(bs58@6.0.0)(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.3(react@19.2.3))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(react@19.2.3)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@4.3.6) + version: 0.19.37(@azure/identity@4.13.0)(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.2.14)(@upstash/redis@1.36.2)(bs58@6.0.0)(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.3(react@19.2.3))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(react@19.2.3)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@4.3.6) '@solana/web3.js': specifier: ^1.98.4 version: 1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) @@ -93,6 +96,18 @@ importers: '@upstash/redis': specifier: ^1.36.2 version: 1.36.2 + '@x402/core': + specifier: ^2.3.1 + version: 2.3.1 + '@x402/fetch': + specifier: ^2.6.0 + version: 2.6.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/hono': + specifier: ^2.6.0 + version: 2.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(hono@4.11.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@x402/svm': + specifier: ^2.3.0 + version: 2.3.0(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10) ai: specifier: ^6.0.86 version: 6.0.86(zod@4.3.6) @@ -320,6 +335,10 @@ importers: packages: + 8004-solana@0.7.9: + resolution: {integrity: sha512-7qSldH9Af89Vpq7NuE2AqN0lW283xCSqR2t2e5kYYgvEGCCwEZhS/DR0cUI4KX0iEsYBlTfmXva9A9O6P44YVw==} + engines: {node: '>=18.0.0'} + '@a2a-js/sdk@0.2.5': resolution: {integrity: sha512-VTDuRS5V0ATbJ/LkaQlisMnTAeYKXAK6scMguVBstf+KIBQ7HIuKhiXLv+G/hvejkV+THoXzoNifInAkU81P1g==} engines: {node: '>=18'} @@ -330,6 +349,9 @@ packages: '@adobe/css-tools@4.4.4': resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + '@adraffy/ens-normalize@1.11.1': resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} @@ -845,6 +867,12 @@ packages: '@cloudflare/workers-types@4.20260210.0': resolution: {integrity: sha512-zHaF0RZVYUQwNCJCECnNAJdMur72Lk3FMiD6wU78Dx3Bv7DQRcuXNmPNuJmsGnosVZCcWintHlPTQ/4BEiDG5w==} + '@coral-xyz/borsh@0.32.1': + resolution: {integrity: sha512-pWsqkkZ+psLlupMkgu5rDok7baDQLWKqyDsb76gUNArbVB783mF3ZOleKMHVXZczl5JuxnVVfO1+XDVvR17C3A==} + engines: {node: '>=10'} + peerDependencies: + '@solana/web3.js': ^1.69.0 + '@csstools/color-helpers@6.0.1': resolution: {integrity: sha512-NmXRccUJMk2AWA5A7e5a//3bCIMyOu2hAtdRYrhPPHjDxINuCwX1w6rnIZ4xjLcp0ayv6h8Pc3X0eJUGiAAXHQ==} engines: {node: '>=20.19.0'} @@ -1651,6 +1679,9 @@ packages: resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + '@noble/curves@1.4.2': resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} @@ -1678,6 +1709,10 @@ packages: resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} engines: {node: '>= 20.19.0'} + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + '@noble/hashes@1.4.0': resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} engines: {node: '>= 16'} @@ -4536,6 +4571,21 @@ packages: peerDependencies: '@solana/web3.js': '*' + '@spruceid/siwe-parser@2.1.2': + resolution: {integrity: sha512-d/r3S1LwJyMaRAKQ0awmo9whfXeE88Qt00vRj91q5uv5ATtWIQEGJ67Yr5eSZw5zp1/fZCXZYuEckt8lSkereQ==} + + '@stablelib/binary@1.0.1': + resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} + + '@stablelib/int@1.0.1': + resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + + '@stablelib/random@1.0.2': + resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} + + '@stablelib/wipe@1.0.1': + resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + '@standard-community/standard-json@0.3.5': resolution: {integrity: sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA==} peerDependencies: @@ -5088,6 +5138,9 @@ packages: '@types/node@20.19.33': resolution: {integrity: sha512-Rs1bVAIdBs5gbTIKza/tgpMuG1k3U/UMJLWecIMxNdJFDMzcM5LOiLVRYh3PilWEYDIeUDv7bpiHPLPsbydGcw==} + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/pg@8.11.0': resolution: {integrity: sha512-sDAlRiBNthGjNFfvt0k6mtotoVYVQ63pA8R4EMWka7crawSR60waVYR0HAgmPRs/e2YaeJTD/43OoZ3PFw80pw==} @@ -5501,6 +5554,24 @@ packages: '@x402/core@2.3.1': resolution: {integrity: sha512-CWvsf09tslISoVOzQ2TIoBLBP+bUycPsYmmRVe3EV5X2FtD7eXXpiPsiXLEVtWP7zhqLNP/5OIATsA2hSVLSfw==} + '@x402/core@2.6.0': + resolution: {integrity: sha512-ISC/JeVss6xlKvor2rp18tJf9K5OQlIDDfZW1VZJQGDI2F4gy+HWxxkFfcQalCsPp4YUlwqh0YOkUxP+LTZWVg==} + + '@x402/extensions@2.6.0': + resolution: {integrity: sha512-aLY9xAOOiRLKDN9HT2r9TYUXbD+IsoBces9qPZNVJGO2TBi2rfmbIBc3pcKCtWKn3iTvG2QFr3gpOFdpJRzqww==} + + '@x402/fetch@2.6.0': + resolution: {integrity: sha512-OnHXw/mv76ig4UBJEgfQIWHSWcrgIOT2i8RxEuGl12QtaYwSgBcgDub2GdllL/iIB9OneM1m0UWlrPh23JdVjQ==} + + '@x402/hono@2.6.0': + resolution: {integrity: sha512-Wt+7Ik6gnVNEY57O+A8/hueL9j+DvbNtHvvqKkTvpq6gadvU2ZtOn++0sWtDIFKRaTq3MVix/rWKlNCRoG0hDQ==} + peerDependencies: + '@x402/paywall': 2.6.0 + hono: ^4.0.0 + peerDependenciesMeta: + '@x402/paywall': + optional: true + '@x402/svm@2.3.0': resolution: {integrity: sha512-Lh02bBBwv9fHSTId8Iqj+SGl9zjSYCrUHaJ0VsrN/GKBcFJwXoDNXgqc7qJGKbkdriBnvAHMxtFR1snpAaBm+w==} @@ -5567,6 +5638,9 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -5634,6 +5708,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + apg-js@4.4.0: + resolution: {integrity: sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==} + aproba@2.1.0: resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} @@ -5936,6 +6013,10 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + buffer-layout@1.2.2: + resolution: {integrity: sha512-kWSuLN694+KTk8SrYvCqwP2WcgQjoRCiF5b4QDvkkz8EmgD+aWAIceGFKMIAdmF/pH+vpgNV3d3kAKorcdAmWA==} + engines: {node: '>=4.5'} + buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} @@ -6853,6 +6934,10 @@ packages: ethereum-cryptography@2.2.1: resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + ethers@6.16.0: + resolution: {integrity: sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==} + engines: {node: '>=14.0.0'} + ev-emitter@2.1.2: resolution: {integrity: sha512-jQ5Ql18hdCQ4qS+RCrbLfz1n+Pags27q5TwMKvZyhp5hh2UULUYZUy1keqj6k6SYsdqIYjnmz7xyyEY0V67B8Q==} @@ -9702,6 +9787,11 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + siwe@2.3.2: + resolution: {integrity: sha512-aSf+6+Latyttbj5nMu6GF3doMfv2UYj83hhwZgUF20ky6fTS83uVhkQABdIVnEuS8y1bBdk7p6ltb9SmlhTTlA==} + peerDependencies: + ethers: ^5.6.8 || ^6.0.8 + slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} @@ -10108,6 +10198,9 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -10210,6 +10303,9 @@ packages: undici-types@5.26.5: resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -10399,6 +10495,9 @@ packages: resolution: {integrity: sha512-AXyzMjazYB3ovL3q051VLH06Ixj//Knx7QnUSi1T//Ie3io6CpsPu9nVMOx5MoLWh6xV0B9J0hIaxungxXUbPQ==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + valid-url@1.0.9: + resolution: {integrity: sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==} + validate-npm-package-name@7.0.2: resolution: {integrity: sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==} engines: {node: ^20.17.0 || >=22.9.0} @@ -10831,6 +10930,20 @@ packages: snapshots: + 8004-solana@0.7.9(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10): + dependencies: + '@coral-xyz/borsh': 0.32.1(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) + '@noble/hashes': 2.0.1 + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) + borsh: 0.7.0 + bs58: 6.0.0 + tweetnacl: 1.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + '@a2a-js/sdk@0.2.5': dependencies: '@types/cors': 2.8.19 @@ -10846,6 +10959,8 @@ snapshots: '@adobe/css-tools@4.4.4': {} + '@adraffy/ens-normalize@1.10.1': {} + '@adraffy/ens-normalize@1.11.1': {} '@ai-sdk/anthropic@3.0.44(zod@4.3.6)': @@ -11774,6 +11889,12 @@ snapshots: '@cloudflare/workers-types@4.20260210.0': {} + '@coral-xyz/borsh@0.32.1(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))': + dependencies: + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) + bn.js: 5.2.2 + buffer-layout: 1.2.2 + '@csstools/color-helpers@6.0.1': {} '@csstools/css-calc@3.0.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': @@ -12660,6 +12781,10 @@ snapshots: '@noble/ciphers@1.3.0': {} + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + '@noble/curves@1.4.2': dependencies: '@noble/hashes': 1.4.0 @@ -12688,6 +12813,8 @@ snapshots: dependencies: '@noble/hashes': 2.0.1 + '@noble/hashes@1.3.2': {} + '@noble/hashes@1.4.0': {} '@noble/hashes@1.7.0': {} @@ -14688,10 +14815,9 @@ snapshots: dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))': + '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))': dependencies: '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@solana/sysvars': 6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@solana-program/token-2022@0.6.1(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))': dependencies: @@ -16187,11 +16313,11 @@ snapshots: - typescript - utf-8-validate - '@solana/wallet-adapter-trezor@0.1.6(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@solana/wallet-adapter-trezor@0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@trezor/connect-web': 9.7.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/connect-web': 9.7.1(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) buffer: 6.0.3 transitivePeerDependencies: - '@solana/sysvars' @@ -16254,7 +16380,7 @@ snapshots: - utf-8-validate - zod - '@solana/wallet-adapter-wallets@0.19.37(@azure/identity@4.13.0)(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10)))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.2.14)(@upstash/redis@1.36.2)(bs58@6.0.0)(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.3(react@19.2.3))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(react@19.2.3)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@4.3.6)': + '@solana/wallet-adapter-wallets@0.19.37(@azure/identity@4.13.0)(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.2.14)(@upstash/redis@1.36.2)(bs58@6.0.0)(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.3(react@19.2.3))(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(react@19.2.3)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(zod@4.3.6)': dependencies: '@solana/wallet-adapter-alpha': 0.1.14(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.17(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) @@ -16287,7 +16413,7 @@ snapshots: '@solana/wallet-adapter-tokenary': 0.1.16(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-tokenpocket': 0.4.23(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-torus': 0.11.32(@babel/runtime@7.28.6)(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-trezor': 0.1.6(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@solana/wallet-adapter-trezor': 0.1.6(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-trust': 0.1.17(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.11(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-walletconnect': 0.1.21(@azure/identity@4.13.0)(@react-native-async-storage/async-storage@1.24.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.4(bufferutil@4.1.0)(encoding@0.1.13)(typescript@5.9.3)(utf-8-validate@5.0.10))(@types/react@19.2.14)(@upstash/redis@1.36.2)(bufferutil@4.1.0)(encoding@0.1.13)(react@19.2.3)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6) @@ -16467,6 +16593,26 @@ snapshots: eventemitter3: 5.0.4 uuid: 9.0.1 + '@spruceid/siwe-parser@2.1.2': + dependencies: + '@noble/hashes': 1.8.0 + apg-js: 4.4.0 + uri-js: 4.4.1 + valid-url: 1.0.9 + + '@stablelib/binary@1.0.1': + dependencies: + '@stablelib/int': 1.0.1 + + '@stablelib/int@1.0.1': {} + + '@stablelib/random@1.0.2': + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/wipe@1.0.1': {} + '@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(quansync@0.2.11)(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': dependencies: '@standard-schema/spec': 1.1.0 @@ -16796,12 +16942,12 @@ snapshots: - react-native - utf-8-validate - '@trezor/blockchain-link@2.6.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/blockchain-link@2.6.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana-program/stake': 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) '@stellar/stellar-sdk': 14.2.0 @@ -16850,9 +16996,9 @@ snapshots: - expo-localization - react-native - '@trezor/connect-web@9.7.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/connect-web@9.7.1(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: - '@trezor/connect': 9.7.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/connect': 9.7.1(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@trezor/connect-common': 0.5.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1) '@trezor/utils': 9.5.0(tslib@2.8.1) '@trezor/websocket-client': 1.3.0(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@5.0.10) @@ -16871,7 +17017,7 @@ snapshots: - utf-8-validate - ws - '@trezor/connect@9.7.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': + '@trezor/connect@9.7.1(bufferutil@4.1.0)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))': dependencies: '@ethereumjs/common': 10.1.1 '@ethereumjs/tx': 10.1.1 @@ -16882,9 +17028,9 @@ snapshots: '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana-program/system': 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) - '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)))(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))) '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) - '@trezor/blockchain-link': 2.6.1(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + '@trezor/blockchain-link': 2.6.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) '@trezor/blockchain-link-types': 1.5.0(tslib@2.8.1) '@trezor/blockchain-link-utils': 1.5.1(bufferutil@4.1.0)(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1)(utf-8-validate@5.0.10) '@trezor/connect-analytics': 1.4.0(react-native@0.84.0(@babel/core@7.29.0)(@types/react@19.2.14)(bufferutil@4.1.0)(react@19.2.3)(utf-8-validate@5.0.10))(tslib@2.8.1) @@ -17278,6 +17424,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + '@types/pg@8.11.0': dependencies: '@types/node': 20.19.33 @@ -18149,6 +18299,47 @@ snapshots: dependencies: zod: 3.25.76 + '@x402/core@2.6.0': + dependencies: + zod: 3.25.76 + + '@x402/extensions@2.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@scure/base': 1.2.6 + '@x402/core': 2.6.0 + ajv: 8.17.1 + siwe: 2.3.2(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + tweetnacl: 1.0.3 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - ethers + - typescript + - utf-8-validate + + '@x402/fetch@2.6.0(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@x402/core': 2.6.0 + viem: 2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@x402/hono@2.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(hono@4.11.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@x402/core': 2.6.0 + '@x402/extensions': 2.6.0(bufferutil@4.1.0)(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10))(typescript@5.9.3)(utf-8-validate@5.0.10) + hono: 4.11.9 + zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - ethers + - typescript + - utf-8-validate + '@x402/svm@2.3.0(@solana/sysvars@6.0.1(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)': dependencies: '@solana-program/compute-budget': 0.11.0(@solana/kit@5.5.1(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(utf-8-validate@5.0.10)) @@ -18193,6 +18384,11 @@ snapshots: typescript: 5.9.3 zod: 3.22.4 + abitype@1.2.3(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + abitype@1.2.3(typescript@5.9.3)(zod@4.3.6): optionalDependencies: typescript: 5.9.3 @@ -18226,6 +18422,8 @@ snapshots: acorn@8.15.0: {} + aes-js@4.0.0-beta.5: {} + agent-base@6.0.2: dependencies: debug: 4.4.3 @@ -18292,6 +18490,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + apg-js@4.4.0: {} + aproba@2.1.0: optional: true @@ -18706,6 +18906,8 @@ snapshots: buffer-from@1.1.2: {} + buffer-layout@1.2.2: {} + buffer-xor@1.0.3: {} buffer@5.7.1: @@ -19813,6 +20015,19 @@ snapshots: '@scure/bip32': 1.4.0 '@scure/bip39': 1.3.0 + ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.1.0)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + ev-emitter@2.1.2: {} event-target-shim@5.0.1: {} @@ -22071,6 +22286,21 @@ snapshots: transitivePeerDependencies: - zod + ox@0.12.1(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + ox@0.12.1(typescript@5.9.3)(zod@4.3.6): dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -23325,6 +23555,14 @@ snapshots: sisteransi@1.0.5: {} + siwe@2.3.2(ethers@6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10)): + dependencies: + '@spruceid/siwe-parser': 2.1.2 + '@stablelib/random': 1.0.2 + ethers: 6.16.0(bufferutil@4.1.0)(utf-8-validate@5.0.10) + uri-js: 4.4.1 + valid-url: 1.0.9 + slash@3.0.0: {} slug@6.1.0: {} @@ -23771,6 +24009,8 @@ snapshots: tslib@1.14.1: {} + tslib@2.7.0: {} + tslib@2.8.1: {} tsyringe@4.10.0: @@ -23885,6 +24125,8 @@ snapshots: undici-types@5.26.5: {} + undici-types@6.19.8: {} + undici-types@6.21.0: {} undici-types@7.21.0: {} @@ -24034,6 +24276,8 @@ snapshots: '@types/uuid': 8.3.4 uuid: 8.3.2 + valid-url@1.0.9: {} + validate-npm-package-name@7.0.2: {} valtio@1.13.2(@types/react@19.2.14)(react@19.2.3): @@ -24102,6 +24346,23 @@ snapshots: - utf-8-validate - zod + viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10)) + ox: 0.12.1(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.1.0)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + viem@2.45.3(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@4.3.6): dependencies: '@noble/curves': 1.9.1 diff --git a/scripts/register-toto-mainnet.ts b/scripts/register-toto-mainnet.ts new file mode 100644 index 0000000..559508f --- /dev/null +++ b/scripts/register-toto-mainnet.ts @@ -0,0 +1,629 @@ +/** + * register-toto-mainnet.ts + * + * One-time script: Register Toto's agent identity on the Solana Agent Registry (mainnet-beta). + * + * Flow: + * 1. Validate environment variables + * 2. Upload Toto's metadata JSON to IPFS via Pinata + * 3. Register a new agent NFT on the Solana Agent Registry using 8004-solana SDK + * 4. Print the asset address and Solana Explorer URL + * 5. Write result to scripts/toto-nft-result.json + * + * SDK quirks discovered: + * - 8004-solana v0.7.9 uses @solana/web3.js v1 (Keypair, Connection, PublicKey), + * NOT @solana/kit. No bridging via @solana/compat is required here because this + * is a standalone script — we import @solana/web3.js directly alongside @solana/kit. + * - SolanaSDK.registerAgent() returns TransactionResult & { asset?: PublicKey } on + * live send, or PreparedTransaction & { asset: PublicKey } when skipSend=true. + * - The OASF skill/domain taxonomy used by the SDK does NOT match the prompt's + * assumed tags (e.g. "business/finance/grant_writing" is NOT valid). Valid tags + * were validated via getAllSkills() / getAllDomains() at script-write time. + * - When skipSend=true (dry-run), registerAgent still needs Connection + cluster + * to fetch a recent blockhash for the serialized tx, so a real RPC connection + * is required even in dry-run mode. + * - The SDK's Keypair signer is a @solana/web3.js Keypair decoded from base58. + * + * Usage: + * # Dry run (no on-chain tx): + * npx tsx scripts/register-toto-mainnet.ts --dry-run + * + * # Live run (Matt runs this manually): + * HELIUS_RPC_URL=https://... PINATA_JWT=... AGENT_AUTHORITY_PRIVATE_KEY=... \ + * npx tsx scripts/register-toto-mainnet.ts + * + * Required env vars: + * HELIUS_RPC_URL Helius mainnet RPC endpoint + * PINATA_JWT Pinata API JWT for IPFS upload + * AGENT_AUTHORITY_PRIVATE_KEY Base58-encoded Solana keypair (the registrant/signer) + * + * SECURITY: Private key only lives in memory for the duration of this script. + * Never stored, never logged, never sent over the wire. + * For live runs, pass via env var at the shell — do NOT commit to .env files. + */ + +// --------------------------------------------------------------------------- +// NOTE: This script intentionally imports @solana/web3.js v1 because the +// 8004-solana SDK requires it. @solana/kit is NOT used here — this is a +// standalone script outside the app bundle. The @solana/compat bridge is +// therefore unnecessary. +// --------------------------------------------------------------------------- + +import { Keypair, Connection, PublicKey } from '@solana/web3.js'; +import bs58 from 'bs58'; +import { SolanaSDK } from '8004-solana'; +import type { TransactionResult, PreparedTransaction } from '8004-solana'; +import * as fs from 'fs/promises'; +import * as path from 'path'; + +// --------------------------------------------------------------------------- +// Constants +// --------------------------------------------------------------------------- + +const DRY_RUN = process.argv.includes('--dry-run'); + +/** + * Toto's agent metadata in Pinata pinning format. + * + * Skills and domains use valid OASF taxonomy tags as validated by + * 8004-solana's getAllSkills() / getAllDomains() / validateSkill() / + * validateDomain() at script-write time. + * + * Original prompt tags (INVALID — not in OASF taxonomy): + * "business/finance/grant_writing" + * "business/marketing/content_strategy" + * "natural_language_processing/text_generation/text_generation" + * "technology/blockchain/solana" + * "business/finance/funding" + * + * Valid replacements used here: + * Skills: + * advanced_reasoning_planning/strategic_planning + * natural_language_processing/natural_language_generation/natural_language_generation + * natural_language_processing/information_retrieval_synthesis/knowledge_synthesis + * Domains: + * finance_and_business/finance + * technology/blockchain/blockchain + */ +const TOTO_METADATA = { + name: 'Toto', + description: + 'Funding strategist for ozskr.ai — non-dilutive funding, grant applications, revenue strategy across the Solana ecosystem.', + skills: [ + 'advanced_reasoning_planning/strategic_planning', + 'natural_language_processing/natural_language_generation/natural_language_generation', + 'natural_language_processing/information_retrieval_synthesis/knowledge_synthesis', + ], + domains: [ + 'finance_and_business/finance', + 'technology/blockchain/blockchain', + ], + version: '1.0.0', + platform: 'ozskr.ai', +}; + +const RESULT_FILE = path.resolve('/home/matt/projects/ozskr/scripts/toto-nft-result.json'); + +// --------------------------------------------------------------------------- +// Env validation +// --------------------------------------------------------------------------- + +interface EnvConfig { + rpcUrl: string; + pinataJwt: string; + privateKeyBase58: string; +} + +function validateEnv(): EnvConfig { + const rpcUrl = + process.env.HELIUS_RPC_URL ?? + process.env.NEXT_PUBLIC_HELIUS_RPC_URL; + + const pinataJwt = process.env.PINATA_JWT; + const privateKeyBase58 = process.env.AGENT_AUTHORITY_PRIVATE_KEY; + + const missing: string[] = []; + + if (!rpcUrl) missing.push('HELIUS_RPC_URL (or NEXT_PUBLIC_HELIUS_RPC_URL)'); + if (!pinataJwt) missing.push('PINATA_JWT'); + if (!privateKeyBase58) missing.push('AGENT_AUTHORITY_PRIVATE_KEY'); + + if (missing.length > 0) { + console.error('ERROR: Missing required environment variables:'); + for (const m of missing) { + console.error(` - ${m}`); + } + console.error(''); + console.error('For dry-run (no on-chain tx), stub values are accepted:'); + console.error( + ' HELIUS_RPC_URL=https://mainnet.helius-rpc.com/?api-key=STUB \\', + ); + console.error(' PINATA_JWT=STUB \\'); + console.error( + ' AGENT_AUTHORITY_PRIVATE_KEY= \\', + ); + console.error(' npx tsx scripts/register-toto-mainnet.ts --dry-run'); + process.exit(1); + } + + return { + rpcUrl: rpcUrl!, + pinataJwt: pinataJwt!, + privateKeyBase58: privateKeyBase58!, + }; +} + +// --------------------------------------------------------------------------- +// Keypair loading +// --------------------------------------------------------------------------- + +/** + * Decode a base58-encoded 64-byte Solana keypair into a @solana/web3.js Keypair. + * The 64-byte format is: [32-byte secret key || 32-byte public key]. + */ +function loadKeypairFromBase58(base58Key: string): Keypair { + let secretBytes: Uint8Array; + try { + secretBytes = bs58.decode(base58Key); + } catch (err) { + throw new Error( + `AGENT_AUTHORITY_PRIVATE_KEY is not valid base58: ${ + err instanceof Error ? err.message : String(err) + }`, + ); + } + + if (secretBytes.length !== 64) { + throw new Error( + `AGENT_AUTHORITY_PRIVATE_KEY must be a 64-byte keypair (got ${secretBytes.length} bytes). ` + + 'Use the full keypair bytes, not just the 32-byte secret scalar.', + ); + } + + const keypair = Keypair.fromSecretKey(secretBytes); + // Zero the raw key material from memory now that it is held inside the Keypair object. + secretBytes.fill(0); + return keypair; +} + +// --------------------------------------------------------------------------- +// IPFS upload via Pinata +// --------------------------------------------------------------------------- + +/** + * Upload a JSON object to IPFS via Pinata's pinning API. + * Returns the IPFS URI: ipfs:// + */ +async function uploadToIPFS(metadata: object): Promise { + console.log('Uploading metadata to IPFS via Pinata...'); + + const response = await fetch('https://api.pinata.cloud/pinning/pinJSONToIPFS', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${process.env.PINATA_JWT}`, + }, + body: JSON.stringify({ + pinataContent: metadata, + pinataMetadata: { name: 'toto-agent-metadata.json' }, + }), + }); + + if (!response.ok) { + const body = await response.text().catch(() => ''); + throw new Error( + `Pinata upload failed (HTTP ${response.status}): ${body}`, + ); + } + + const result = (await response.json()) as { IpfsHash: string }; + + if (!result.IpfsHash) { + throw new Error( + `Pinata response missing IpfsHash field: ${JSON.stringify(result)}`, + ); + } + + const uri = `ipfs://${result.IpfsHash}`; + console.log(`Metadata pinned: ${uri}`); + return uri; +} + +// --------------------------------------------------------------------------- +// Priority fee estimation via Helius +// --------------------------------------------------------------------------- + +/** + * Estimate a recommended priority fee using Helius getPriorityFeeEstimate. + * Returns microlamports. Falls back to 50_000 if the RPC call fails. + * + * This is informational only in this script — the 8004-solana SDK manages + * its own compute unit budget. We print it so Matt can assess cost before + * executing the live run. + */ +async function estimatePriorityFee(rpcUrl: string): Promise { + const FALLBACK = 50_000n; + + try { + const response = await fetch(rpcUrl, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ + jsonrpc: '2.0', + id: 1, + method: 'getPriorityFeeEstimate', + params: [ + { + // No specific account keys — we want a general estimate + accountKeys: [], + options: { recommended: true }, + }, + ], + }), + }); + + if (!response.ok) return FALLBACK; + + const data = (await response.json()) as { + result?: { priorityFeeEstimate?: number }; + }; + + const fee = data.result?.priorityFeeEstimate; + if (typeof fee === 'number' && fee > 0) { + return BigInt(Math.ceil(fee)); + } + + return FALLBACK; + } catch { + return FALLBACK; + } +} + +// --------------------------------------------------------------------------- +// Transaction cost estimation +// --------------------------------------------------------------------------- + +interface TransactionCostEstimate { + baseFee: bigint; + priorityFee: bigint; + totalEstimate: bigint; + displayAmount: string; +} + +function formatSol(lamports: bigint): string { + const whole = lamports / 1_000_000_000n; + const frac = lamports % 1_000_000_000n; + return `${whole}.${frac.toString().padStart(9, '0')} SOL`; +} + +// --------------------------------------------------------------------------- +// Type guards for SDK return types +// --------------------------------------------------------------------------- + +function isPreparedTransaction( + result: unknown, +): result is PreparedTransaction & { asset: PublicKey } { + return ( + typeof result === 'object' && + result !== null && + 'transaction' in result && + 'asset' in result && + (result as { signed: unknown }).signed === false + ); +} + +function isTransactionResult( + result: unknown, +): result is TransactionResult & { asset?: PublicKey; signatures?: string[] } { + return ( + typeof result === 'object' && + result !== null && + 'signature' in result && + 'success' in result + ); +} + +// --------------------------------------------------------------------------- +// Result type +// --------------------------------------------------------------------------- + +interface RegistrationResult { + assetAddress: string; + metadataUri: string; + txSignature?: string; + explorerUrl: string; + timestamp: string; + dryRun: boolean; + preparedTransaction?: string; +} + +// --------------------------------------------------------------------------- +// Main +// --------------------------------------------------------------------------- + +async function main(): Promise { + console.log('=== Toto Agent NFT — Solana Agent Registry (mainnet-beta) ==='); + console.log(`Mode: ${DRY_RUN ? 'DRY RUN (no on-chain transaction)' : 'LIVE — will submit transaction'}`); + console.log(''); + + // 1. Validate env + const env = validateEnv(); + + // 2. Load authority keypair + // SECURITY: secret bytes live only in memory, never logged + let authority: Keypair; + try { + authority = loadKeypairFromBase58(env.privateKeyBase58); + } catch (err) { + console.error( + `ERROR: Failed to load keypair: ${err instanceof Error ? err.message : String(err)}`, + ); + process.exit(1); + } + + const authorityAddress = authority.publicKey.toBase58(); + console.log(`Authority wallet: ${authorityAddress}`); + console.log(`Network: mainnet-beta`); + console.log(`RPC: ${env.rpcUrl.replace(/api[-_]?key=[^&]+/i, 'api-key=')}`); + console.log(''); + + // 3. Estimate priority fee (informational) + console.log('Fetching priority fee estimate...'); + const priorityFee = await estimatePriorityFee(env.rpcUrl); + const baseFee = 5_000n; // standard 5000 lamport base fee per signature + const costEstimate: TransactionCostEstimate = { + baseFee, + priorityFee, + totalEstimate: baseFee + priorityFee, + displayAmount: formatSol(baseFee + priorityFee), + }; + + console.log('Estimated transaction cost:'); + console.log(` Base fee: ${formatSol(costEstimate.baseFee)}`); + console.log(` Priority fee: ${costEstimate.priorityFee} microlamports (~${formatSol(costEstimate.priorityFee / 1000n)})`); + console.log(` Total: ${costEstimate.displayAmount}`); + console.log(' Note: The 8004-solana SDK adds compute unit budget instructions.'); + console.log(' Actual cost may differ slightly from this estimate.'); + console.log(''); + + // 4. Upload metadata to IPFS + let metadataUri: string; + + if (DRY_RUN) { + // In dry-run mode, skip actual Pinata upload if JWT is a stub + if (env.pinataJwt === 'STUB' || env.pinataJwt.length < 20) { + metadataUri = 'ipfs://DRY_RUN_PLACEHOLDER_CID'; + console.log(`[DRY RUN] Skipping Pinata upload — would pin: ${JSON.stringify(TOTO_METADATA, null, 2)}`); + console.log(`[DRY RUN] Metadata URI would be: ${metadataUri}`); + } else { + // Real JWT provided even in dry-run — upload but still skip the tx + metadataUri = await uploadToIPFS(TOTO_METADATA); + } + } else { + metadataUri = await uploadToIPFS(TOTO_METADATA); + } + + console.log(''); + + // 5. Build SDK client + // 8004-solana uses @solana/web3.js v1 Connection internally. + // We pass rpcUrl and cluster to SolanaSDK which creates the Connection. + console.log('Initializing 8004-solana SDK...'); + + const sdk = new SolanaSDK({ + cluster: 'mainnet-beta', + rpcUrl: env.rpcUrl, + signer: authority, + // No ipfsClient — we handled IPFS upload ourselves via Pinata above, + // and pass the resulting URI directly to registerAgent(). + forceOnChain: true, // Bypass indexer for writes; we only need on-chain + }); + + console.log('SDK initialized.'); + console.log(''); + + // 6. Print what will be submitted + console.log('Registration payload:'); + console.log(` Agent URI (metadata): ${metadataUri}`); + console.log(` Signer/owner: ${authorityAddress}`); + console.log(` Network: mainnet-beta`); + console.log(` Program: ${ + // MAINNET_AGENT_REGISTRY_PROGRAM_ID is the identity registry program + // Value: FLod5vBGm3L3Prnsefmf7LbBkKAf3GxNNNfaXoBFVuW (from 8004-solana constants) + 'FLod5vBGm3L3Prnsefmf7LbBkKAf3GxNNNfaXoBFVuW' + }`); + console.log(''); + + if (DRY_RUN) { + // ----------------------------------------------------------------------- + // DRY RUN: prepare the transaction without sending it + // ----------------------------------------------------------------------- + console.log('[DRY RUN] Preparing transaction (skipSend=true)...'); + + let prepResult: Awaited>; + try { + prepResult = await sdk.registerAgent(metadataUri, { + skipSend: true, + }); + } catch (err) { + console.error( + `[DRY RUN] ERROR: registerAgent (skipSend) failed: ${ + err instanceof Error ? err.message : String(err) + }`, + ); + console.error( + 'This may indicate an RPC connection issue or invalid metadata URI.', + ); + process.exit(1); + } + + if (!isPreparedTransaction(prepResult)) { + console.error( + '[DRY RUN] ERROR: Unexpected return type from registerAgent(skipSend=true):', + prepResult, + ); + process.exit(1); + } + + const assetAddress = prepResult.asset.toBase58(); + const explorerUrl = `https://explorer.solana.com/address/${assetAddress}?cluster=mainnet-beta`; + + console.log(''); + console.log('[DRY RUN] Transaction prepared successfully.'); + console.log(''); + console.log('=== DRY RUN RESULT ==='); + console.log(`Asset address (NFT): ${assetAddress}`); + console.log(`Explorer URL: ${explorerUrl}`); + console.log(`Metadata URI: ${metadataUri}`); + console.log(`Blockhash: ${prepResult.blockhash}`); + console.log(`Last valid height: ${prepResult.lastValidBlockHeight}`); + console.log(`Required signers: ${prepResult.requiredSigners?.join(', ') ?? prepResult.signer}`); + console.log(`Transaction signed: ${prepResult.signed} (must be signed before send)`); + console.log(''); + console.log('Transaction base64 (first 80 chars):'); + console.log(` ${prepResult.transaction.slice(0, 80)}...`); + console.log(''); + console.log('To execute on mainnet, run WITHOUT --dry-run:'); + console.log( + ' HELIUS_RPC_URL=... PINATA_JWT=... AGENT_AUTHORITY_PRIVATE_KEY=... \\', + ); + console.log(' npx tsx scripts/register-toto-mainnet.ts'); + + const result: RegistrationResult = { + assetAddress, + metadataUri, + explorerUrl, + timestamp: new Date().toISOString(), + dryRun: true, + preparedTransaction: prepResult.transaction, + }; + + await fs.writeFile(RESULT_FILE, JSON.stringify(result, null, 2), 'utf-8'); + console.log(''); + console.log(`Result written to: ${RESULT_FILE}`); + } else { + // ----------------------------------------------------------------------- + // LIVE RUN: submit the transaction + // ----------------------------------------------------------------------- + console.log('Submitting registration transaction...'); + console.log('IMPORTANT: This will create a permanent on-chain record.'); + console.log(''); + + const connection = new Connection(env.rpcUrl, 'confirmed'); + const balance = await connection.getBalance(authority.publicKey); + const balanceLamports = BigInt(balance); + + console.log(`Authority SOL balance: ${formatSol(balanceLamports)}`); + + if (balanceLamports < 10_000_000n) { + console.error( + `ERROR: Authority wallet has insufficient SOL (${formatSol(balanceLamports)}). ` + + 'Need at least 0.01 SOL to cover rent + fees for registration.', + ); + process.exit(1); + } + + // SECURITY: Simulate the transaction before sending per CLAUDE.md requirement. + // We use skipSend=true to build the serialized tx, decode and simulate it, + // then fall through to the live send only if simulation succeeds. + console.log('Simulating transaction before sending...'); + let prepForSim: Awaited>; + try { + prepForSim = await sdk.registerAgent(metadataUri, { skipSend: true }); + } catch (err) { + console.error(`ERROR: Failed to prepare transaction for simulation: ${err instanceof Error ? err.message : String(err)}`); + process.exit(1); + } + + if (!isPreparedTransaction(prepForSim)) { + console.error('ERROR: Could not prepare transaction for simulation — aborting.'); + process.exit(1); + } + + // Decode the base64 serialized transaction and simulate via RPC + const { Transaction } = await import('@solana/web3.js'); + const txBytes = Buffer.from(prepForSim.transaction, 'base64'); + const simulateTx = Transaction.from(txBytes); + const simResult = await connection.simulateTransaction(simulateTx); + + if (simResult.value.err) { + console.error('ERROR: Transaction simulation failed — aborting live send.'); + console.error('Simulation error:', JSON.stringify(simResult.value.err, null, 2)); + if (simResult.value.logs) { + console.error('Program logs:'); + simResult.value.logs.forEach((log) => console.error(' ', log)); + } + process.exit(1); + } + + console.log('Simulation succeeded. Proceeding with live send.'); + console.log(''); + + let txResult: Awaited>; + try { + txResult = await sdk.registerAgent(metadataUri, { + // SDK default: skipSend=false — will sign and send + atomEnabled: false, // ATOM reputation tracking not needed at registration time + }); + } catch (err) { + console.error( + `ERROR: registerAgent failed: ${ + err instanceof Error ? err.message : String(err) + }`, + ); + process.exit(1); + } + + if (!isTransactionResult(txResult)) { + console.error( + 'ERROR: Unexpected return type from registerAgent():', + txResult, + ); + process.exit(1); + } + + if (!txResult.success) { + console.error(`ERROR: Transaction failed: ${txResult.error ?? '(no error message)'}`); + process.exit(1); + } + + const assetAddress = txResult.asset?.toBase58() ?? '(asset not returned)'; + const explorerUrl = `https://explorer.solana.com/address/${assetAddress}?cluster=mainnet-beta`; + const txExplorerUrl = `https://explorer.solana.com/tx/${txResult.signature}?cluster=mainnet-beta`; + + console.log(''); + console.log('=== REGISTRATION SUCCESSFUL ==='); + console.log(`Asset address (NFT): ${assetAddress}`); + console.log(`Transaction sig: ${txResult.signature}`); + console.log(`Explorer (asset): ${explorerUrl}`); + console.log(`Explorer (tx): ${txExplorerUrl}`); + console.log(`Metadata URI: ${metadataUri}`); + console.log(''); + + const result: RegistrationResult = { + assetAddress, + metadataUri, + txSignature: txResult.signature, + explorerUrl, + timestamp: new Date().toISOString(), + dryRun: false, + }; + + await fs.writeFile(RESULT_FILE, JSON.stringify(result, null, 2), 'utf-8'); + console.log(`Result written to: ${RESULT_FILE}`); + console.log(''); + console.log('Next steps:'); + console.log(' 1. Verify the asset on Solana Explorer (link above).'); + console.log(' 2. Update TOTO_NFT_ASSET_ADDRESS in environment config.'); + console.log(' 3. Call sdk.setMetadata() to attach OASF skill/domain tags on-chain.'); + } +} + +main().catch((err) => { + console.error(''); + console.error('FATAL:', err instanceof Error ? err.message : String(err)); + if (err instanceof Error && err.stack) { + console.error(err.stack); + } + process.exit(1); +}); diff --git a/src/app/(dashboard)/agents/[id]/page.tsx b/src/app/(dashboard)/agents/[id]/page.tsx index a673fd2..7442d8b 100644 --- a/src/app/(dashboard)/agents/[id]/page.tsx +++ b/src/app/(dashboard)/agents/[id]/page.tsx @@ -23,6 +23,7 @@ import { } from 'lucide-react'; import { useCharacter, useUpdateCharacter } from '@/hooks/use-characters'; import { GenerateModal } from '@/features/agents/components/generate-modal'; +import { ContentGenerateModal } from '@/features/content/components/content-generate-modal'; import { ScheduleModal } from '@/features/agents/components/schedule-modal'; import { DelegationCard } from '@/features/agents/components/delegation-card'; import { ContentLibrary } from '@/features/agents/components/content-library'; @@ -57,6 +58,7 @@ export default function AgentDetailPage({ params }: AgentDetailPageProps) { const { data: characterRaw, isLoading, error } = useCharacter(id); const { mutate: updateCharacter } = useUpdateCharacter(id); const [generateModalOpen, setGenerateModalOpen] = useState(false); + const [contentGenerateModalOpen, setContentGenerateModalOpen] = useState(false); const [scheduleModalOpen, setScheduleModalOpen] = useState(false); // Fetch schedules for this character @@ -201,14 +203,25 @@ export default function AgentDetailPage({ params }: AgentDetailPageProps) { - +
+ + +
@@ -462,7 +475,7 @@ export default function AgentDetailPage({ params }: AgentDetailPageProps) { - {/* Generation Modal */} + {/* Generation Modal (existing image-generate flow) */} + {/* Content Generation Modal (multi-category content creation) */} + + {/* Schedule Modal */}

- {balance !== null ? 'SOL on devnet' : 'Connect wallet to view'} + {balance !== null + ? `SOL on ${process.env.NEXT_PUBLIC_SOLANA_NETWORK === 'mainnet-beta' ? 'mainnet' : 'devnet'}` + : 'Connect wallet to view'}

diff --git a/src/app/providers.tsx b/src/app/providers.tsx index 5c596c7..b9916f0 100644 --- a/src/app/providers.tsx +++ b/src/app/providers.tsx @@ -5,18 +5,20 @@ * Wraps the application with all required context providers */ -import { useMemo } from 'react'; +import { useMemo, useCallback } from 'react'; import { ConnectionProvider, WalletProvider, WalletContext, useWallet, } from '@solana/wallet-adapter-react'; +import type { WalletError } from '@solana/wallet-adapter-base'; import { WalletModalProvider } from '@solana/wallet-adapter-react-ui'; import { PhantomWalletAdapter } from '@solana/wallet-adapter-phantom'; import { SolflareWalletAdapter } from '@solana/wallet-adapter-solflare'; import { BackpackWalletAdapter } from '@solana/wallet-adapter-backpack'; import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { resolveHeliusRpcUrl } from '@/lib/solana/rpc'; // Import wallet adapter CSS import '@solana/wallet-adapter-react-ui/styles.css'; @@ -56,11 +58,14 @@ const queryClient = new QueryClient({ }); export function Providers({ children }: { children: React.ReactNode }) { - // Get RPC endpoint from environment (fallback based on network) + // Resolve RPC endpoint using NEXT_PUBLIC_SOLANA_NETWORK as the source of + // truth. resolveHeliusRpcUrl() corrects the Helius subdomain to match the + // active network so a devnet API key URL is never accidentally used on + // mainnet-beta (and vice-versa). Falls back to the public cluster endpoint + // when no Helius URL is configured. const endpoint = useMemo(() => { - if (process.env.NEXT_PUBLIC_HELIUS_RPC_URL) { - return process.env.NEXT_PUBLIC_HELIUS_RPC_URL; - } + const heliusUrl = resolveHeliusRpcUrl(); + if (heliusUrl) return heliusUrl; return process.env.NEXT_PUBLIC_SOLANA_NETWORK === 'mainnet-beta' ? 'https://api.mainnet-beta.solana.com' : 'https://api.devnet.solana.com'; @@ -78,10 +83,17 @@ export function Providers({ children }: { children: React.ReactNode }) { [] ); + // Suppress non-fatal MetaMask connection errors — MetaMask registers itself + // via Wallet Standard auto-discovery but cannot connect in a Solana context. + const onWalletError = useCallback((error: WalletError) => { + if (error.name === 'WalletConnectionError' && error.message?.includes('MetaMask')) return; + console.error('[WalletProvider]', error); + }, []); + return ( - + {children} diff --git a/src/features/agents/components/delegation-card.tsx b/src/features/agents/components/delegation-card.tsx index 1c752a6..e970104 100644 --- a/src/features/agents/components/delegation-card.tsx +++ b/src/features/agents/components/delegation-card.tsx @@ -27,7 +27,6 @@ import { useDelegationTransactions, useApproveDelegation, useRevokeDelegation, - useAgentSpend, } from '@/hooks/use-delegation'; import { formatTokenAmount, parseTokenAmount } from '@/lib/solana/tokens'; import { @@ -40,18 +39,18 @@ import { AlertTriangle, Copy, Check, - Send, } from 'lucide-react'; import { cn } from '@/lib/utils'; -// Devnet USDC-Dev SPL token mint (Circle test faucet) +// USDC SPL token mints +const MAINNET_USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v'; const DEVNET_USDC_MINT = '4zMMC9srt5Ri5X14GAgXhaHii3GnPAEERYPJgZJDncDU'; +const USDC_MINT = + process.env.NEXT_PUBLIC_SOLANA_NETWORK === 'mainnet-beta' + ? MAINNET_USDC_MINT + : DEVNET_USDC_MINT; const USDC_DECIMALS = 6; -// Devnet demo: deterministic recipient for testing delegated agent spends. -// PDA derived from ['ozskr', 'demo-fee'] via System Program — no private key exists. -const DEMO_FEE_RECIPIENT = 'Eum62rLLk5EyhfCiC8Ka6PZpTKqv1fQ3dj3apiMpTHyN'; -const DEMO_SPEND_AMOUNT = '100000'; // 0.10 USDC in base units interface DelegationCardProps { characterId: string; @@ -104,16 +103,11 @@ export function DelegationCard({ characterId, characterName }: DelegationCardPro const { data: txData } = useDelegationTransactions(characterId); const approveMutation = useApproveDelegation(); const revokeMutation = useRevokeDelegation(); - const spendMutation = useAgentSpend(); const [approveDialogOpen, setApproveDialogOpen] = useState(false); const [revokeDialogOpen, setRevokeDialogOpen] = useState(false); const [amountInput, setAmountInput] = useState('10'); - const [mintInput, setMintInput] = useState(DEVNET_USDC_MINT); - const [lastSpend, setLastSpend] = useState<{ - signature: string; - explorerUrl: string; - } | null>(null); + const [mintInput] = useState(USDC_MINT); if (isLoading) { return ( @@ -201,24 +195,6 @@ export function DelegationCard({ characterId, characterName }: DelegationCardPro } }; - const handleTestSpend = async () => { - try { - const result = await spendMutation.mutateAsync({ - characterId, - destinationOwner: DEMO_FEE_RECIPIENT, - amount: DEMO_SPEND_AMOUNT, - decimals: USDC_DECIMALS, - tokenMint: delegation.delegationTokenMint || DEVNET_USDC_MINT, - }); - setLastSpend({ - signature: result.signature, - explorerUrl: result.explorerUrl, - }); - } catch { - // Error handled by mutation state - } - }; - return ( @@ -328,12 +304,12 @@ export function DelegationCard({ characterId, characterName }: DelegationCardPro setMintInput(e.target.value)} + readOnly placeholder="Token mint address" - className="font-mono text-xs" + className="font-mono text-xs cursor-default opacity-75" />

- Default: Devnet USDC-Dev + USDC ({process.env.NEXT_PUBLIC_SOLANA_NETWORK === 'mainnet-beta' ? 'Mainnet' : 'Devnet'})

@@ -448,58 +424,6 @@ export function DelegationCard({ characterId, characterName }: DelegationCardPro )} - {/* Test Agent Spend */} - {isActive && ( - - )} - - )} - - {/* Last spend result */} - {lastSpend && ( -
-
- Agent spend confirmed - - View on Explorer - - -
-

- {lastSpend.signature} -

-
- )} - - {/* Spend error */} - {spendMutation.error && !spendMutation.isPending && ( -
-

- {spendMutation.error.message} -

)} diff --git a/src/features/agents/components/generate-modal.tsx b/src/features/agents/components/generate-modal.tsx index 553386f..aac9f93 100644 --- a/src/features/agents/components/generate-modal.tsx +++ b/src/features/agents/components/generate-modal.tsx @@ -2,10 +2,12 @@ /** * Content Generation Modal - * Handles content generation with SSE streaming progress + * + * x402-payment-gated image generation via POST /api/services/image-generate[-pro]. + * All images are generated by nanobanana 2 and paid in USDC on-chain. */ -import { useState, useEffect } from 'react'; +import { useState, useRef } from 'react'; import Image from 'next/image'; import { useQueryClient } from '@tanstack/react-query'; import { @@ -18,25 +20,25 @@ import { import { Button } from '@/components/ui/button'; import { Textarea } from '@/components/ui/textarea'; import { Label } from '@/components/ui/label'; -import { Badge } from '@/components/ui/badge'; import { Card } from '@/components/ui/card'; import { Loader2, Check, AlertCircle, - Copy, Share2, RefreshCw, - Image as ImageIcon, - FileText, Library, + Coins, } from 'lucide-react'; -import { useGenerateContent, useGenerationStream } from '@/hooks/use-generations'; -import { GenerationType } from '@/types/database'; +import { useX402Generate } from '@/hooks/use-x402-generate'; import { cn } from '@/lib/utils'; -import type { GenerationStage } from '@/hooks/use-generations'; +import type { X402GenerateType } from '@/hooks/use-x402-generate'; import { PublishModal } from './publish-modal'; +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + interface GenerateModalProps { open: boolean; onOpenChange: (open: boolean) => void; @@ -44,24 +46,85 @@ interface GenerateModalProps { characterName: string; } -const STAGE_ORDER: GenerationStage[] = [ - 'loading_character', - 'enhancing_prompt', - 'generating_content', - 'quality_check', - 'moderation', - 'complete', +// --------------------------------------------------------------------------- +// Model config +// --------------------------------------------------------------------------- + +const MODELS: { type: X402GenerateType; name: string; description: string; price: string }[] = [ + { + type: 'image', + name: 'nanobanana 2', + description: 'Fast, high-quality image generation', + price: '$0.10 USDC', + }, + { + type: 'image-pro', + name: 'nanobanana 2 Pro', + description: 'High-resolution, premium output', + price: '$0.15 USDC', + }, ]; -const STAGE_LABELS: Record = { - loading_character: 'Summoning character DNA...', - enhancing_prompt: 'Weaving the prompt...', - generating_content: 'The wizard is working...', - quality_check: 'Polishing the emeralds...', - moderation: 'Final curtain check...', - complete: 'Complete', - error: 'Error', -}; +// --------------------------------------------------------------------------- +// Payment confirmation overlay +// --------------------------------------------------------------------------- + +interface PaymentConfirmProps { + amountUsdc: string; + payTo: string; + onConfirm: () => void; + onCancel: () => void; +} + +function PaymentConfirmOverlay({ amountUsdc, payTo, onConfirm, onCancel }: PaymentConfirmProps) { + const shortAddress = `${payTo.slice(0, 6)}...${payTo.slice(-4)}`; + + return ( + +
+
+ +
+

Confirm USDC Payment

+

+ Your wallet will be prompted to sign a USDC transfer. No SOL is spent beyond + the transaction fee. +

+
+
+ +
+
+ Amount + {amountUsdc} USDC +
+
+ Recipient + {shortAddress} +
+
+ +
+ + +
+
+
+ ); +} + +// --------------------------------------------------------------------------- +// Main modal +// --------------------------------------------------------------------------- export function GenerateModal({ open, @@ -69,243 +132,240 @@ export function GenerateModal({ characterId, characterName, }: GenerateModalProps) { - const [contentType, setContentType] = useState(GenerationType.TEXT); const [prompt, setPrompt] = useState(''); - const [generationId, setGenerationId] = useState(null); + const [modelType, setModelType] = useState('image'); + const [imageUrl, setImageUrl] = useState(null); + const [genError, setGenError] = useState(null); const [publishOpen, setPublishOpen] = useState(false); + const [pendingConfirmation, setPendingConfirmation] = useState<{ + amountUsdc: string; + payTo: string; + } | null>(null); + + const confirmResolverRef = useRef<(() => void) | null>(null); + const confirmRejecterRef = useRef<((reason?: unknown) => void) | null>(null); + const queryClient = useQueryClient(); - const { mutate: generateContent, isPending: isSubmitting } = useGenerateContent(characterId); - const { progress } = useGenerationStream(generationId); - - const isComplete = progress?.stage === 'complete'; - const hasError = progress?.stage === 'error'; - - // Invalidate the content library cache as soon as generation finishes - // so the library is already refreshed by the time the user closes the modal. - useEffect(() => { - if (isComplete) { - void queryClient.invalidateQueries({ - queryKey: ['character-generations', characterId], + + const { mutate: generate, isPending, reset } = useX402Generate({ + onConfirm: async ({ amountUsdc, payTo }) => { + return new Promise((resolve, reject) => { + confirmResolverRef.current = resolve; + confirmRejecterRef.current = reject; + setPendingConfirmation({ amountUsdc, payTo }); }); - } - }, [isComplete, queryClient, characterId]); + }, + }); + + // ------------------------------------------------------------------------- + // Derived flags + // ------------------------------------------------------------------------- + const isGenerating = isPending && !pendingConfirmation; + const hasResult = !!imageUrl; - // Submit generation + // ------------------------------------------------------------------------- + // Handlers + // ------------------------------------------------------------------------- const handleSubmit = () => { if (!prompt.trim()) return; + setImageUrl(null); + setGenError(null); - generateContent( + generate( + { characterId, prompt: prompt.trim(), type: modelType }, { - generationType: contentType, - inputPrompt: prompt.trim(), - }, - { - onSuccess: (response) => { - setGenerationId(response.generationId); + onSuccess: (result) => { + setImageUrl(result.imageUrl); + void queryClient.invalidateQueries({ queryKey: ['character-generations', characterId] }); + }, + onError: (err) => { + setGenError(err instanceof Error ? err.message : 'Generation failed'); }, } ); }; - // Reset for new generation const handleGenerateAgain = () => { - setGenerationId(null); + setImageUrl(null); + setGenError(null); setPrompt(''); + reset(); + }; + + const handleConfirmPayment = () => { + setPendingConfirmation(null); + confirmResolverRef.current?.(); + confirmResolverRef.current = null; + confirmRejecterRef.current = null; + }; + + const handleCancelPayment = () => { + setPendingConfirmation(null); + confirmRejecterRef.current?.(new Error('User cancelled payment')); + confirmResolverRef.current = null; + confirmRejecterRef.current = null; + setGenError('Payment cancelled'); + reset(); }; - // Close and reset const handleClose = () => { onOpenChange(false); setTimeout(() => { - setGenerationId(null); setPrompt(''); - setContentType(GenerationType.TEXT); + setImageUrl(null); + setGenError(null); + setPendingConfirmation(null); + confirmRejecterRef.current?.(new Error('Modal closed')); + confirmResolverRef.current = null; + confirmRejecterRef.current = null; + reset(); }, 300); }; - // Copy result - const handleCopy = () => { - if (progress?.result?.outputText) { - navigator.clipboard.writeText(progress.result.outputText); - } - }; + const selectedModel = MODELS.find((m) => m.type === modelType) ?? MODELS[0]; + // ------------------------------------------------------------------------- + // Render + // ------------------------------------------------------------------------- return ( <> - - - - Generate Content - - Create content with {characterName} - - - - {/* Input Form (shown before generation starts) */} - {!generationId && ( -
- {/* Content Type Toggle */} -
- -
- - + + + + Generate Image + Create an image with {characterName} + + + {/* ================================================================ + Form — hidden while pending / showing result + ================================================================ */} + {!hasResult && !isGenerating && !pendingConfirmation && !genError && ( +
+ {/* Model selector */} +
+ +
+ {MODELS.map((m) => ( + + ))} +
-
- {/* Prompt Input */} -
- -