diff --git a/go.mod b/go.mod index 227cd76..a7a0b6e 100644 --- a/go.mod +++ b/go.mod @@ -8,6 +8,7 @@ require ( github.com/google/jsonschema-go v0.4.3 github.com/joho/godotenv v1.5.1 github.com/lib/pq v1.10.9 + github.com/mark3labs/x402-go v0.12.1 github.com/modelcontextprotocol/go-sdk v1.6.1 github.com/nacorid/logger v0.0.0-20251221013547-5fc8fd94ed80 github.com/ollama/ollama v0.12.10 @@ -16,18 +17,42 @@ require ( ) require ( + filippo.io/edwards25519 v1.1.0 // indirect + github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect + github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect + github.com/benbjohnson/clock v1.3.5 // indirect github.com/bits-and-blooms/bitset v1.24.2 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect github.com/consensys/gnark-crypto v0.19.2 // indirect github.com/crate-crypto/go-eth-kzg v1.5.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.6 // indirect github.com/ethereum/go-ethereum v1.17.2 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/solana-go v1.14.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect github.com/holiman/uint256 v1.3.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.18.1 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845 // indirect github.com/supranational/blst v0.3.16 // indirect + github.com/tyler-smith/go-bip32 v1.0.0 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect + go.mongodb.org/mongo-driver v1.17.6 // indirect + go.uber.org/ratelimit v0.3.1 // indirect golang.org/x/sync v0.19.0 // indirect + golang.org/x/term v0.38.0 // indirect ) require ( @@ -91,7 +116,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.46.0 // indirect - golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 // indirect golang.org/x/net v0.48.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sys v0.41.0 // indirect diff --git a/go.sum b/go.sum index f88d49c..f7de63b 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,14 @@ +filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= +github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e h1:ahyvB3q25YnZWly5Gq1ekg6jcmWaGj/vG/MhF4aisoc= +github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:kGUqhHd//musdITWjFvNTHn90WG9bMLBEPQZ17Cmlpw= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec h1:1Qb69mGp/UtRPn422BH4/Y4Q3SLUrD9KHuDkm8iodFc= +github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec/go.mod h1:CD8UlnlLDiqb36L110uqiP2iSflVjx9g/3U9hCI4q2U= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= @@ -10,16 +18,24 @@ github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9 github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.24.2 h1:M7/NzVbsytmtfHbumG+K2bremQPMJuqv1JD3vOaFxp0= github.com/bits-and-blooms/bitset v1.24.2/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/bluesky-social/indigo v0.0.0-20251009224519-09f107c1109e h1:6oNYIMh+kbArCQiwZYPGgfxQq88tnMyiBIZtg5clq90= github.com/bluesky-social/indigo v0.0.0-20251009224519-09f107c1109e/go.mod h1:RuQVrCGm42QNsgumKaR6se+XkFKfCPNwdCiTvqKRUck= github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e h1:0XBUw73chJ1VYSsfvcPvVT7auykAJce9FpRr10L6Qhw= +github.com/cmars/basen v0.0.0-20150613233007-fe3947df716e/go.mod h1:P13beTBKr5Q18lJe1rIoLUqjM+CB1zYrRg44ZqGuQSA= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= @@ -58,10 +74,22 @@ github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJ github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= github.com/ethereum/go-ethereum v1.17.2 h1:ag6geu0kn8Hv5FLKTpH+Hm2DHD+iuFtuqKxEuwUsDOI= github.com/ethereum/go-ethereum v1.17.2/go.mod h1:KHcRXfGOUfUmKg51IhQ0IowiqZ6PqZf08CMtk0g5K1o= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= +github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.14.0 h1:3WfAi70jOOjAJ0deFMjdhFYlLXATF4tOQXsDNWJtOLw= +github.com/gagliardetto/solana-go v1.14.0/go.mod h1:l/qqqIN6qJJPtxW/G1PF4JtcE3Zg2vD2EliZrr9Gn5k= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -86,6 +114,7 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/jsonschema-go v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0= @@ -153,15 +182,19 @@ github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0 github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.18.1 h1:bcSGx7UbpBqMChDtsF28Lw6v/G94LPrrbMbdC3JH2co= github.com/klauspost/compress v1.18.1/go.mod h1:ZQFFVG+MdnR0P+l6wpXgIL4NTtwiKIdBnrBd8Nrxr+0= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -174,6 +207,10 @@ github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzW github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/mark3labs/x402-go v0.12.1 h1:yWlT/mjF0P1j2sB0xAM4GJb+1/Ycv6p6EqUrT6RB2X0= +github.com/mark3labs/x402-go v0.12.1/go.mod h1:srAvV9FosjBiqrclF15thrQbz0fVVfNXtMcqD0e1hKU= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= @@ -184,12 +221,21 @@ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvls github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modelcontextprotocol/go-sdk v1.6.1 h1:0zOSupjKUxPKSocPT1Wtago+mUHU2/uZ4xSOY0FGReU= github.com/modelcontextprotocol/go-sdk v1.6.1/go.mod h1:kzm3kzFL1/+AziGOE0nUs3gvPoNxMCvkxokMkuFapXQ= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= @@ -206,6 +252,8 @@ github.com/nacorid/logger v0.0.0-20251221013547-5fc8fd94ed80 h1:nZwGInvJNQzPSFYp github.com/nacorid/logger v0.0.0-20251221013547-5fc8fd94ed80/go.mod h1:hd9h4KEPU1f/Vv2qP0x/fZUwz2clFvOV/uIF0pkGo+s= github.com/ollama/ollama v0.12.10 h1:Dd0/SeCc+nv+FffxmWuQTGiRreib7Gt3nBhIIFuKwZA= github.com/ollama/ollama v0.12.10/go.mod h1:RUSmYywUWx/YZMaHrqtnT1ZChu+iSz/7jx2aO9+Mgfg= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= @@ -247,6 +295,8 @@ github.com/segmentio/encoding v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfv github.com/segmentio/encoding v0.5.4/go.mod h1:HS1ZKa3kSN32ZHVZ7ZLPLXWvOVIiZtyJnO1gPH1sKt0= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= @@ -256,7 +306,11 @@ github.com/sokkalf/slog-seq v0.5.1 h1:4LicZGsMhuCtmZkbS++JOm3Wn8PLIrjFkuvEp0yeGH github.com/sokkalf/slog-seq v0.5.1/go.mod h1:B82pc/cMpdQQg6hkBbstHEL4vqI1eZ1MISuN1IK7h14= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845 h1:VMA0pZ3MI8BErRA3kh8dKJThP5d0Xh5vZVk5yFIgH/A= +github.com/streamingfast/logging v0.0.0-20250918142248-ac5a1e292845/go.mod h1:BtDq81Tyc7H8up5aXNi/I95nPmG3C0PLEqGWY/iWQ2E= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.1.5-0.20170601210322-f6abca593680/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -267,10 +321,16 @@ github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jq github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tyler-smith/go-bip32 v1.0.0 h1:sDR9juArbUgX+bO/iblgZnMPeWY1KZMUC2AFUJdv5KE= +github.com/tyler-smith/go-bip32 v1.0.0/go.mod h1:onot+eHknzV4BVPwrzqY5OoVpyCvnwD7lMawL5aQupE= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= @@ -294,6 +354,8 @@ github.com/yosida95/uritemplate/v3 v3.0.2/go.mod h1:ILOh0sOhIJR3+L/8afwt/kE++YT0 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.mongodb.org/mongo-driver v1.17.6 h1:87JUG1wZfWsr6rIz3ZmpH90rL5tea7O3IHuSwHUpsss= +go.mongodb.org/mongo-driver v1.17.6/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= @@ -308,26 +370,35 @@ go.opentelemetry.io/otel/sdk/metric v1.40.0 h1:mtmdVqgQkeRxHgRv4qhyJduP3fYJRMX4A go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw= go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0= +go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU= golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0= golang.org/x/exp v0.0.0-20251023183803-a4bb9ffd2546 h1:mgKeJMpvi0yx/sU5GsxQ7p6s2wtOnGAHZWCHUM4KGzY= @@ -343,6 +414,7 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU= golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= @@ -359,7 +431,9 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -372,6 +446,7 @@ golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q= golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU= golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY= golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= @@ -412,5 +487,7 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= +launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= diff --git a/internal/config/config.go b/internal/config/config.go index 22d283b..e44789a 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -25,7 +25,6 @@ type Config struct { ApiKey string ApiSecret string LogFile string - ActiveNetworks string } func Load() *Config { @@ -54,7 +53,6 @@ func Load() *Config { ApiKey: getEnv("CDP_API_KEY_ID", ""), ApiSecret: getEnv("CDP_API_SECRET", ""), LogFile: getEnv("LOG_FILE", "/var/log/mcpserver/output.log"), - ActiveNetworks: getEnv("ACTIVE_NETWORKS", "base"), } } diff --git a/internal/server/GlobalLoggingMiddleware.go b/internal/server/GlobalLoggingMiddleware.go deleted file mode 100644 index 073676e..0000000 --- a/internal/server/GlobalLoggingMiddleware.go +++ /dev/null @@ -1,63 +0,0 @@ -package server - -import ( - "fmt" - "net/http" - "strings" - "time" - - log "github.com/nacorid/logger" -) - -type statusTrackingWriter struct { - http.ResponseWriter - statusCode int -} - -func (stw *statusTrackingWriter) WriteHeader(code int) { - stw.statusCode = code - stw.ResponseWriter.WriteHeader(code) -} - -func (stw *statusTrackingWriter) Write(b []byte) (int, error) { - if stw.statusCode == 0 { - stw.statusCode = http.StatusOK - } - return stw.ResponseWriter.Write(b) -} - -func GlobalLoggingMiddleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - if r.URL.Path == "/healthz" { - next.ServeHTTP(w, r) - return - } - start := time.Now() - - ipAddr := r.RemoteAddr - if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" { - ipAddr = strings.TrimSpace(strings.Split(forwarded, ",")[0]) - } else if realIP := r.Header.Get("X-Real-Ip"); realIP != "" { - ipAddr = realIP - } - - stw := &statusTrackingWriter{ResponseWriter: w} - - next.ServeHTTP(stw, r) - - duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond)) - status := stw.statusCode - if status == 0 { - status = http.StatusOK - } - - log.InfoWithContext(r.Context(), "HTTP Request Processed", - "method", r.Method, - "path", r.URL.Path, - "status", status, - "duration", duration, - "remote_ip", ipAddr, - "user_agent", r.UserAgent(), - ) - }) -} diff --git a/internal/server/LoggingMiddleware.go b/internal/server/LoggingMiddleware.go deleted file mode 100644 index bb4e7f0..0000000 --- a/internal/server/LoggingMiddleware.go +++ /dev/null @@ -1,66 +0,0 @@ -package server - -import ( - "context" - "fmt" - "net/http" - "strings" - "time" - - "github.com/modelcontextprotocol/go-sdk/mcp" - log "github.com/nacorid/logger" -) - -type LoggingMiddleware struct{} - -func NewLoggingMiddleware() *LoggingMiddleware { - return &LoggingMiddleware{} -} - -// OnCall logs native MCP tool requests streamed over SSE/WebSockets -func (lm *LoggingMiddleware) OnCall(next mcp.MethodHandler) mcp.MethodHandler { - return func(ctx context.Context, method string, request mcp.Request) (mcp.Result, error) { - if method == "tools/call" { - start := time.Now() - - result, err := next(ctx, method, request) - - duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond)) - - toolName := "unknown" - if callReq, ok := request.(*mcp.CallToolRequest); ok && callReq.Params != nil { - toolName = callReq.Params.Name - } - - log.InfoWithContext(ctx, "MCP Tool Processed", - "transport", "mcp_native", - "tool", toolName, - "duration", duration, - "success", err == nil, - ) - return result, err - } - return next(ctx, method, request) - } -} - -func (lm *LoggingMiddleware) OnCallHTTP(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - start := time.Now() - - ipAddr := r.RemoteAddr - if forwarded := r.Header.Get("X-Forwarded-For"); forwarded != "" { - ipAddr = strings.TrimSpace(strings.Split(forwarded, ",")[0]) - } - - next.ServeHTTP(w, r) - - duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond)) - log.InfoWithContext(r.Context(), "REST Tool Processed", - "transport", "rest", - "path", r.URL.Path, - "duration", duration, - "remote_ip", ipAddr, - ) - }) -} diff --git a/internal/server/metricsMiddleware.go b/internal/server/metricsMiddleware.go index 138af47..a62b14d 100644 --- a/internal/server/metricsMiddleware.go +++ b/internal/server/metricsMiddleware.go @@ -2,7 +2,6 @@ package server import ( "context" - "fmt" "net/http" "time" @@ -30,7 +29,7 @@ func (mh *MetricsMiddleware) OnCall(next mcp.MethodHandler) mcp.MethodHandler { mh.requestsBucket.Increment() mh.totalRequests.Increment() result, err := next(ctx, method, request) - duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond)) + duration := time.Since(start) log.DebugWithContext(ctx, "MetricsMiddleware: MCP Handler", "duration", duration) return result, err } @@ -44,7 +43,7 @@ func (mh *MetricsMiddleware) OnCallHTTP(next http.Handler) http.Handler { mh.requestsBucket.Increment() mh.totalRequests.Increment() next.ServeHTTP(w, r) - duration := fmt.Sprintf("%.2fms", float64(time.Since(start))/float64(time.Millisecond)) + duration := time.Since(start) log.DebugWithContext(r.Context(), "MetricsMiddleware: HTTP Handler", "duration", duration) }) } diff --git a/internal/server/networkInfo.go b/internal/server/networkInfo.go deleted file mode 100644 index be96613..0000000 --- a/internal/server/networkInfo.go +++ /dev/null @@ -1,34 +0,0 @@ -package server - -type NetworkInfo struct { - Network string - Asset string - Extra map[string]any -} - -// NetworkRegistry maps human-readable names (slugs) to their full configuration parameters. -var NetworkRegistry = map[string]NetworkInfo{ - "base": { - Network: "eip155:8453", - Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", - }, - "sepolia": { - Network: "eip155:84532", - Asset: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", - }, - "polygon": { - Network: "eip155:137", - Asset: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359", - }, - "arbitrum": { - Network: "eip155:42161", - Asset: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831", - }, - "solana": { - Network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp", - Asset: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", - Extra: map[string]any{ - "feePayer": "BENrLoUbndxoNMUS5JXApGMtNykLjFXXixMtpDwDR9SP", - }, - }, -} diff --git a/internal/server/server.go b/internal/server/server.go index caa40eb..b88ab62 100644 --- a/internal/server/server.go +++ b/internal/server/server.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "maps" "net/http" "os" "strings" @@ -22,32 +21,29 @@ import ( "github.com/nacorid/naco-api/internal/x402" x402v2 "github.com/x402-foundation/x402/go/v2" x402http "github.com/x402-foundation/x402/go/v2/http/nethttp" + "github.com/x402-foundation/x402/go/v2/types" ) type Server struct { - listenAddress string - permissions os.FileMode - mcpHandler *x402.X402Server - db *store.Queries - apClient *activitypub.APClient - bskyClient *bluesky.BlueskyClient - ollama *ollama.OllamaClient - x402Wallet string - activeNetworks []NetworkInfo + listenAddress string + permissions os.FileMode + mcpHandler *x402.X402Server + db *store.Queries + apClient *activitypub.APClient + bskyClient *bluesky.BlueskyClient + ollama *ollama.OllamaClient + x402Wallet string } func New(ctx context.Context, db *store.Queries, ap *activitypub.APClient, bsky *bluesky.BlueskyClient, o *ollama.OllamaClient, cfg *config.Config) *Server { rateLimits := NewRateLimitMiddleware(float64(1.0/10.0), 2, []string{"getFeed"}) metrics := NewMetricsHook() - logging := NewLoggingMiddleware() toolChain := x402.X402Middlewares{ MCPMiddleware: []mcp.Middleware{ - logging.OnCall, metrics.OnCall, rateLimits.OnCall, }, HTTPMiddleware: []func(http.Handler) http.Handler{ - logging.OnCallHTTP, metrics.OnCallHTTP, rateLimits.OnCallHTTP, }, @@ -63,13 +59,13 @@ func New(ctx context.Context, db *store.Queries, ap *activitypub.APClient, bsky cfg.X402FacilitatorURL, auth, toolChain, - GlobalLoggingMiddleware, func(w http.ResponseWriter, r *http.Request, resp *x402v2.SettleResponse) { requirements, ok := x402http.RequirementsFromContext(r.Context()) if !ok { log.WarnWithContext(r.Context(), "failed to extract payment requirements from context during settlement hook") return } + amount := requirements.Amount asset := requirements.Asset to := requirements.PayTo @@ -89,27 +85,15 @@ func New(ctx context.Context, db *store.Queries, ap *activitypub.APClient, bsky return settleHook(settleCtx.Ctx, db, settleCtx.Result.Transaction, amount, asset, string(settleCtx.Result.Network), to, from) }) - enabledNetworkNames := parseActiveNetworks(cfg.ActiveNetworks) - - var activeNetworks []NetworkInfo - for _, name := range enabledNetworkNames { - if info, exists := NetworkRegistry[name]; exists { - activeNetworks = append(activeNetworks, info) - } else { - log.WarnWithContext(ctx, "configured network is not defined in the registry", "name", name) - } - } - s := &Server{ - listenAddress: cfg.ListenAddress, - permissions: cfg.UnixSocketPermissions, - mcpHandler: srv, - db: db, - apClient: ap, - bskyClient: bsky, - ollama: o, - x402Wallet: cfg.X402WalletAddress, - activeNetworks: activeNetworks, + listenAddress: cfg.ListenAddress, + permissions: cfg.UnixSocketPermissions, + mcpHandler: srv, + db: db, + apClient: ap, + bskyClient: bsky, + ollama: o, + x402Wallet: cfg.X402WalletAddress, } s.registerTools() @@ -155,6 +139,16 @@ func (s *Server) registerTools() { }, } + requirement := types.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", + Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Amount: "10000", + PayTo: s.x402Wallet, + MaxTimeoutSeconds: 60, + Extra: extra, + } + requirements := []types.PaymentRequirements{requirement} s.mcpHandler.AddPayableTool( mcp.Tool{Name: "getPost", Description: "Get a specific post from a specific actor", @@ -162,7 +156,7 @@ func (s *Server) registerTools() { OutputSchema: GetPostResponsePost{}, }, s.getPost, - s.buildRequirements("0.01", extra)..., + requirements..., ) extra = map[string]any{ @@ -197,6 +191,18 @@ func (s *Server) registerTools() { }, } + requirement = types.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", + Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Amount: "100000", + PayTo: s.x402Wallet, + MaxTimeoutSeconds: 60, + Extra: extra, + } + + requirements = []types.PaymentRequirements{requirement} + s.mcpHandler.AddPayableTool( mcp.Tool{Name: "getLatestPosts", Description: "Get the latest n posts from a specific actor", @@ -204,7 +210,7 @@ func (s *Server) registerTools() { OutputSchema: GetLatestPostsResponse{}, }, s.getLatestPosts, - s.buildRequirements("0.10", extra)..., + requirements..., ) extra = map[string]any{ @@ -249,6 +255,18 @@ func (s *Server) registerTools() { }, } + requirement = types.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", + Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Amount: "100000", + PayTo: s.x402Wallet, + MaxTimeoutSeconds: 60, + Extra: extra, + } + + requirements = []types.PaymentRequirements{requirement} + s.mcpHandler.AddPayableTool( mcp.Tool{Name: "getPostsInTime", Description: "Get posts from a specific actor in a time range", @@ -256,7 +274,7 @@ func (s *Server) registerTools() { OutputSchema: GetPostsInTimeResponse{}, }, s.getPostsInTime, - s.buildRequirements("0.10", extra)..., + requirements..., ) extra = map[string]any{ @@ -294,15 +312,27 @@ func (s *Server) registerTools() { }, } - /*s.mcpHandler.AddPayableTool( + requirement = types.PaymentRequirements{ + Scheme: "exact", + Network: "eip155:8453", + Asset: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", + Amount: "100000", + PayTo: s.x402Wallet, + MaxTimeoutSeconds: 60, + Extra: extra, + } + + requirements = []types.PaymentRequirements{requirement} + + s.mcpHandler.AddPayableTool( mcp.Tool{Name: "getStyleProfile", Description: "Get an actor's style Profile", InputSchema: GetStyleProfileRequest{}, OutputSchema: GetStyleProfileResponse{}, }, s.getStyleProfile, - s.buildRequirements("100000", extra)..., - )*/ + requirements..., + ) s.mcpHandler.AddTool( mcp.Tool{Name: "getFeed", @@ -703,39 +733,6 @@ func settleHook(ctx context.Context, db *store.Queries, transaction, amount, ass return nil } -func (s *Server) buildRequirements(amount string, extra map[string]any) []x402v2.PaymentRequirements { - requirements := make([]x402v2.PaymentRequirements, 0, len(s.activeNetworks)) - - for _, info := range s.activeNetworks { - mergedExtra := make(map[string]any) - maps.Copy(mergedExtra, extra) - maps.Copy(mergedExtra, info.Extra) - requirements = append(requirements, x402v2.PaymentRequirements{ - Scheme: "exact", - Network: info.Network, - Asset: info.Asset, - Amount: amount, - PayTo: s.x402Wallet, - MaxTimeoutSeconds: 60, - Extra: mergedExtra, - }) - } - - return requirements -} - -func parseActiveNetworks(raw string) []string { - parts := strings.Split(raw, ",") - var slugs []string - for _, part := range parts { - trimmed := strings.ToLower(strings.TrimSpace(part)) - if trimmed != "" { - slugs = append(slugs, trimmed) - } - } - return slugs -} - func (s *Server) Start() error { return s.mcpHandler.Start(s.listenAddress, s.permissions) } diff --git a/internal/utils/counter.go b/internal/utils/counter.go index 39e8399..22b70d5 100644 --- a/internal/utils/counter.go +++ b/internal/utils/counter.go @@ -3,7 +3,7 @@ package utils import "sync/atomic" type Counter struct { - value atomic.Int64 + valut atomic.Int64 } func NewCounter() *Counter { @@ -11,13 +11,13 @@ func NewCounter() *Counter { } func (c *Counter) Increment() { - c.value.Add(1) + c.valut.Add(1) } func (c *Counter) Get() int64 { - return c.value.Load() + return c.valut.Load() } func (c *Counter) Reset() { - c.value.Store(0) + c.valut.Store(0) } diff --git a/internal/x402/x402.go b/internal/x402/x402.go index 08e7b8b..6a47b16 100644 --- a/internal/x402/x402.go +++ b/internal/x402/x402.go @@ -44,12 +44,11 @@ type X402Server struct { version string middlewareChain func(http.Handler) http.Handler tools []ToolInfo - globalReqLog func(http.Handler) http.Handler } const VERSION1 = "v1/" -func NewX402Server(name, version string, facilitatorURL string, auth x402http.AuthProvider, mws X402Middlewares, globalLoggingMw func(http.Handler) http.Handler, settleHook func(http.ResponseWriter, *http.Request, *x402.SettleResponse)) (*X402Server, error) { +func NewX402Server(name, version string, facilitatorURL string, auth x402http.AuthProvider, mws X402Middlewares, settleHook func(w http.ResponseWriter, r *http.Request, resp *x402.SettleResponse)) (*X402Server, error) { mcpServer := mcp.NewServer( &mcp.Implementation{ Name: name, @@ -85,7 +84,6 @@ func NewX402Server(name, version string, facilitatorURL string, auth x402http.Au version: version, middlewareChain: chainHTTPMiddlewares(mws.HTTPMiddleware...), tools: make([]ToolInfo, 0), - globalReqLog: globalLoggingMw, } s.mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, r *http.Request) { @@ -178,7 +176,8 @@ func (s *X402Server) AddPayableTool( restHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { s.handleRESTCall(w, r, tool.Name, handler) }) - s.mux.Handle("POST /"+VERSION1+tool.Name, s.middlewareChain(paymentMiddleware(restHandler))) + chained := s.middlewareChain(restHandler) + s.mux.Handle("POST /"+VERSION1+tool.Name, paymentMiddleware(chained)) } func (s *X402Server) handleRESTCall(w http.ResponseWriter, r *http.Request, toolName string, handler mcp.ToolHandler) { @@ -268,7 +267,7 @@ func (s *X402Server) serveOpenAPI(w http.ResponseWriter, r *http.Request) { } } - paths["/"+VERSION1+info.Tool.Name] = map[string]any{ + paths["/"+info.Tool.Name] = map[string]any{ "post": postOp, } } @@ -279,9 +278,6 @@ func (s *X402Server) serveOpenAPI(w http.ResponseWriter, r *http.Request) { "title": s.name, "version": s.version, "description": "Auto-generated REST API matching active Model Context Protocol (MCP) tools.", - "contact": map[string]any{ - "email": "x402@naco.li", - }, }, "paths": paths, } @@ -319,7 +315,7 @@ func (s *X402Server) Start(addr string, permissions os.FileMode) error { defer listener.Close() srv := &http.Server{ - Handler: s.globalReqLog(s.mux), + Handler: s.mux, ErrorLog: slog.NewLogLogger(slog.Default().Handler(), slog.LevelDebug), } return srv.Serve(listener) diff --git a/internal/x402/x402_test.go b/internal/x402/x402_test.go index 19f8036..ba6e84a 100644 --- a/internal/x402/x402_test.go +++ b/internal/x402/x402_test.go @@ -29,7 +29,6 @@ func TestX402Server_HTTPBoundaries(t *testing.T) { mockFacilitator.URL, &DummyAuthProvider{}, X402Middlewares{}, - func(next http.Handler) http.Handler { return next }, func(w http.ResponseWriter, r *http.Request, resp *x402.SettleResponse) {}, ) if err != nil { @@ -100,7 +99,6 @@ func TestX402Server_MCPBoundaries(t *testing.T) { mockFacilitator.URL, &DummyAuthProvider{}, X402Middlewares{}, - func(next http.Handler) http.Handler { return next }, func(w http.ResponseWriter, r *http.Request, resp *x402.SettleResponse) {}, ) if err != nil { diff --git a/testClient/main.go b/testClient/main.go index 394d2c1..75279a5 100644 --- a/testClient/main.go +++ b/testClient/main.go @@ -3,6 +3,7 @@ package main import ( "bytes" "context" + "encoding/json" "fmt" "io" "log" @@ -13,10 +14,12 @@ import ( "github.com/joho/godotenv" - x402 "github.com/x402-foundation/x402/go/v2" - x402http "github.com/x402-foundation/x402/go/v2/http" - evm "github.com/x402-foundation/x402/go/v2/mechanisms/evm/exact/client" - evmsigners "github.com/x402-foundation/x402/go/v2/signers/evm" + //"github.com/mark3labs/mcp-go/client" + "github.com/mark3labs/x402-go" + x402http "github.com/mark3labs/x402-go/http" + + //x402client "github.com/mark3labs/x402-go/mcp/client" + "github.com/mark3labs/x402-go/signers/evm" ) type LoggingRoundTripper struct { @@ -60,17 +63,27 @@ func main() { godotenv.Load() var ( privateKey = os.Getenv("PRIVATE_KEY") - serverURL = "https://api.naco.li/v1" - ctx = context.Background() + serverURL = "https://api.naco.li" + err error ) - signer, err := evmsigners.NewClientSignerFromPrivateKey(privateKey) - if err != nil { - log.Fatal("Failed to create EVM signer:", err) + chainConfig := x402.BaseMainnet + + signerOpts := []evm.SignerOption{ + evm.WithPrivateKey(privateKey), + evm.WithNetwork(chainConfig.NetworkID), + evm.WithToken(chainConfig.USDCAddress, chainConfig.EIP3009Name, int(chainConfig.Decimals)), } - x402Client := x402.Newx402Client(). - Register("eip155:*", evm.NewExactEvmScheme(signer, nil)) + signer, err := evm.NewSigner(signerOpts...) + if err != nil { + log.Fatal("Failed to create signer:", err) + } + + /*x402mcpTransport, err := x402client.NewTransport(serverURL+"/mcp", x402client.WithSigner(signer)) + if err != nil { + log.Fatal("Failed to create transport:", err) + }*/ debugClient := &http.Client{ Transport: &LoggingRoundTripper{ @@ -78,44 +91,306 @@ func main() { }, } - httpClient := x402http.WrapHTTPClientWithPayment( - debugClient, - x402http.Newx402HTTPClient(x402Client), + callback := x402.PaymentCallback(func(pe x402.PaymentEvent) { + log.Printf("Type: %s, Tool: %s, Error: %s", pe.Type, pe.Tool, pe.Error) + }) + // Create MCP client with x402 transport + //mcpClient := client.NewClient(x402mcpTransport) + httpClient, err := x402http.NewClient(x402http.WithPaymentCallbacks( + callback, + callback, + callback, + ), + x402http.WithHTTPClient(debugClient), + x402http.WithSelector(x402.NewDefaultPaymentSelector()), + x402http.WithSigner(signer), ) - - log.Println("Starting REST API tests...") - - log.Println("\nCalling getFeed (free tool) via HTTP client...") - bodyGetFeed := []byte(`{"uri": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot"}`) - resp, err := httpClient.Post(fmt.Sprintf("%s/getFeed", serverURL), "application/json", bytes.NewReader(bodyGetFeed)) if err != nil { - log.Println("getFeed HTTP request failed:", err) + log.Fatal("Failed to create HTTP client:", err) + } + + ctx := context.Background() + /*if err := mcpClient.Start(ctx); err != nil { + log.Fatal("Failed to start client:", err) + } + defer mcpClient.Close() + */ + //startTime, _ := time.Parse(time.DateOnly, "2025-10-25") + //endTime, _ := time.Parse(time.DateOnly, "2025-10-31") + + /*// Initialize MCP session + initResp, err := mcpClient.Initialize(ctx, mcp.InitializeRequest{ + Params: mcp.InitializeParams{ + ProtocolVersion: "2024-11-05", + ClientInfo: mcp.Implementation{ + Name: "x402-test", + Version: "1.0.0", + }, + }, + }) + if err != nil { + log.Fatal("Failed to initialize:", err) + } + + log.Printf("Connected to server: %s v%s", + initResp.ServerInfo.Name, initResp.ServerInfo.Version) + + // List all available tools + log.Println("\nListing available tools...") + toolsResp, err := mcpClient.ListTools(ctx, mcp.ListToolsRequest{}) + if err != nil { + log.Printf("Failed to list tools: %v", err) } else { - defer resp.Body.Close() - body, _ := io.ReadAll(resp.Body) - log.Printf("getFeed Response Status: %s\n", resp.Status) - log.Printf("getFeed Response Body: %s\n", string(body)) + log.Println("Available tools:") + for _, tool := range toolsResp.Tools { + log.Printf(" - %s: %s", tool.Name, tool.Description) + } } - log.Println("\nCalling getPost (gated paid tool) via HTTP client...") - bodyGetPost := []byte(`{"actor":"sharkgamiart.bsky.social","rkey":"3m47y27c67c2b"}`) + log.Println("\nCalling feed tool (free)...") + _, err = mcpClient.CallTool(ctx, mcp.CallToolRequest{ + Params: mcp.CallToolParams{ + Name: "getFeed", + Arguments: map[string]any{ + "uri": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot", + }, + }, + }) - req, err := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/getPost", serverURL), bytes.NewReader(bodyGetPost)) if err != nil { - log.Fatal("Failed to create getPost request:", err) + log.Printf("Feed failed: %v", err) + } else { + log.Println("Feed response:") + if len(echoResp.Content) > 0 { + if textContent, ok := mcp.AsTextContent(echoResp.Content[0]); ok { + log.Println(textContent.Text) + } + } + log.Println("Feed response received successfully.") } + + log.Println("\nCalling feed tool again with proper feed uri...") + _, err = mcpClient.CallTool(ctx, mcp.CallToolRequest{ + Params: mcp.CallToolParams{ + Name: "getFeed", + Arguments: map[string]any{ + "uri": "at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot", + }, + }, + }) + + if err != nil { + log.Printf("Feed failed: %v", err) + } else { + log.Println("Feed response:") + if len(echoResp.Content) > 0 { + if textContent, ok := mcp.AsTextContent(echoResp.Content[0]); ok { + log.Println(textContent.Text) + } + } + log.Println("Feed response received successfully.") + } + + // Call the search tool (paid) + log.Println("\nGet Post (paid tool)...") + searchResp, err := mcpClient.CallTool(ctx, mcp.CallToolRequest{ + Params: mcp.CallToolParams{ + Name: "getPost", + Arguments: map[string]any{ + "actor": "sharkgamiart.bsky.social", + "rkey": "3m47y27c67c2b", + }, + }, + }) + + if err != nil { + log.Fatalf("Get Post failed: %v", err) + } + + log.Println("Post results:") + if len(searchResp.Content) > 0 { + if textContent, ok := mcp.AsTextContent(searchResp.Content[0]); ok { + log.Println(textContent.Text) + } + } + + log.Println("\nGet latest posts (paid tool)...") + latestResp, err := mcpClient.CallTool(ctx, mcp.CallToolRequest{ + Params: mcp.CallToolParams{ + Name: "getLatestPosts", + Arguments: map[string]any{ + "actor": "sharkgamiart.bsky.social", + "n": 10, + }, + }, + }) + + if err != nil { + log.Fatalf("Get Latest Posts failed: %v", err) + } + + log.Printf("Latest posts (%d):\n", len(latestResp.Content)) + if len(latestResp.Content) > 0 { + if textContent, ok := mcp.AsTextContent(latestResp.Content[0]); ok { + log.Println(" - ", textContent.Text) + } + } + + log.Println("\nGet posts in timeframe (paid tool)...") + timeframeResp, err := mcpClient.CallTool(ctx, mcp.CallToolRequest{ + Params: mcp.CallToolParams{ + Name: "getPostsInTime", + Arguments: map[string]any{ + "actor": "sharkgamiart.bsky.social", + "startTime": startTime.Format(time.RFC3339), + "endTime": endTime.Format(time.RFC3339), + "n": 5, + }, + }, + }) + + if err != nil { + log.Fatalf("Get Posts in Timeframe failed: %v", err) + } + + log.Println("Posts in timeframe results:") + if len(timeframeResp.Content) > 0 { + if textContent, ok := mcp.AsTextContent(timeframeResp.Content[0]); ok { + log.Println(textContent.Text) + } + } + + mcpClient.Close()*/ + + var dataGetFeed any + log.Println("Calling getFeed via HTTP client") + resp, err := httpClient.Post(fmt.Sprintf("%s/getFeed", serverURL), "application/json", bytes.NewReader([]byte(`{"uri": "https://bsky.app/profile/did:plc:z72i7hdynmk6r22z27h6tvur/feed/whats-hot"}`))) + if err != nil { + log.Println("getFeed failed:", err) + } + + body, err := io.ReadAll(resp.Body) + if err != nil { + log.Println("Failed to read getFeed response body:", err) + } + if resp.StatusCode != http.StatusOK { + log.Printf("Raw Response Body: %s\n", string(body)) + } + err = json.Unmarshal(body, &dataGetFeed) + if err != nil { + log.Println("Failed to unmarshal getFeed response body:", err) + log.Printf("Received Raw Body: %s\n", string(body)) + } + //log.Println("getFeed response:", dataGetFeed) + resp.Body.Close() + + /* var dataGetFeed2 any + log.Println("Calling getFeed via HTTP client with proper feed uri") + resp, err = httpClient.Post(fmt.Sprintf("%s/getFeed", serverURL), "application/json", bytes.NewReader([]byte(`{"uri":"at://did:plc:z72i7hdynmk6r22z27h6tvur/app.bsky.feed.generator/whats-hot"}`))) + if err != nil { + log.Println("getFeed failed:", err) + } + + body, err = io.ReadAll(resp.Body) + if err != nil { + log.Println("Failed to read getFeed response body:", err) + } + if resp.StatusCode != http.StatusOK { + log.Printf("Raw Response Body: %s\n", string(body)) + } + err = json.Unmarshal(body, &dataGetFeed2) + if err != nil { + log.Println("Failed to unmarshal getFeed response body:", err) + log.Printf("Received Raw Body: %s\n", string(body)) + } + //log.Println("getFeed response:", dataGetFeed2) + resp.Body.Close() + */ + var dataGetPost any + log.Println("Calling getPost via HTTP client") + bodyBytes := []byte(`{"actor":"sharkgamiart.bsky.social","rkey":"3m47y27c67c2b"}`) + + req, _ := http.NewRequestWithContext(ctx, "POST", fmt.Sprintf("%s/getPost", serverURL), bytes.NewReader(bodyBytes)) req.GetBody = func() (io.ReadCloser, error) { - return io.NopCloser(bytes.NewReader(bodyGetPost)), nil + return io.NopCloser(bytes.NewReader(bodyBytes)), nil } req.Header.Set("Content-Type", "application/json") - respPost, err := httpClient.Do(req) + resp, err = httpClient.Do(req) if err != nil { - log.Println("getPost HTTP request failed:", err) - } else { - defer respPost.Body.Close() - body, _ := io.ReadAll(respPost.Body) - log.Printf("getPost Response Status: %s\n", respPost.Status) - log.Printf("getPost Response Body: %s\n", string(body)) + log.Println("getPost failed:", err) } + + body, err = io.ReadAll(resp.Body) + if err != nil { + log.Println("Failed to read getPost response body:", err) + } + if resp.StatusCode != http.StatusOK { + log.Printf("Raw Response Body: %s\n", string(body)) + } + err = json.Unmarshal(body, &dataGetPost) + if err != nil { + log.Println("Failed to unmarshal getPost response body:", err) + log.Printf("Received Raw Body: %s\n", string(body)) + } + log.Println("getPost response:", dataGetPost) + resp.Body.Close() + /* + var dataGetLatestPosts any + log.Println("Calling getLatestPosts via HTTP client") + resp, err = httpClient.Post(fmt.Sprintf("%s/getLatestPosts", serverURL), "application/json", bytes.NewReader([]byte(`{"actor":"sharkgamiart.bsky.social","n":10}`))) + + if err != nil { + log.Println("getLatestPosts failed:", err) + } + + log.Println(resp.Proto) + body, err = io.ReadAll(resp.Body) + + if err != nil { + log.Println("Failed to read getLatestPosts response body:", err) + } + + if resp.StatusCode != http.StatusOK { + log.Printf("Raw Response Body: %s\n", string(body)) + } + + err = json.Unmarshal(body, &dataGetLatestPosts) + + if err != nil { + log.Println("Failed to unmarshal getLatestPosts response body:", err) + log.Printf("Received Raw Body: %s\n", string(body)) + } + + log.Println("getLatestPosts response:", dataGetLatestPosts) + resp.Body.Close() + + var dataGetPostsInTime any + log.Println("Calling getPostsInTime via HTTP client") + resp, err = httpClient.Post(fmt.Sprintf("%s/getPostsInTime", serverURL), "application/json", bytes.NewReader([]byte(fmt.Sprintf(`{"actor":"sharkgamiart.bsky.social","startTime":"%s","endTime":"%s","n":5}`, startTime.Format(time.RFC3339), endTime.Format(time.RFC3339))))) + + if err != nil { + log.Println("getPostsInTime failed:", err) + } + + body, err = io.ReadAll(resp.Body) + + if err != nil { + log.Println("Failed to read getPostsInTime response body:", err) + } + + if resp.StatusCode != http.StatusOK { + log.Printf("Raw Response Body: %s\n", string(body)) + } + + err = json.Unmarshal(body, &dataGetPostsInTime) + + if err != nil { + log.Println("Failed to unmarshal getPostsInTime response body:", err) + log.Printf("Received Raw Body: %s\n", string(body)) + } + + log.Println("getPostsInTime response:", dataGetPostsInTime) + resp.Body.Close() + */ }