@lagoon-protocol/lagoon-mcp 0.5.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -54
- package/dist/cache/index.d.ts +4 -1
- package/dist/cache/index.d.ts.map +1 -1
- package/dist/cache/index.js +4 -1
- package/dist/cache/index.js.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +1 -1
- package/dist/core/container.js +1 -1
- package/dist/graphql/fragments/apr-breakdown.fragment.d.ts +4 -1
- package/dist/graphql/fragments/apr-breakdown.fragment.d.ts.map +1 -1
- package/dist/graphql/fragments/apr-breakdown.fragment.js +3 -0
- package/dist/graphql/fragments/apr-breakdown.fragment.js.map +1 -1
- package/dist/graphql/fragments/composition.fragment.d.ts +23 -134
- package/dist/graphql/fragments/composition.fragment.d.ts.map +1 -1
- package/dist/graphql/fragments/composition.fragment.js +9 -7
- package/dist/graphql/fragments/composition.fragment.js.map +1 -1
- package/dist/graphql/fragments/index.d.ts +1 -1
- package/dist/graphql/fragments/index.d.ts.map +1 -1
- package/dist/graphql/fragments/index.js +5 -4
- package/dist/graphql/fragments/index.js.map +1 -1
- package/dist/graphql/fragments/transaction-base.fragment.d.ts +1 -1
- package/dist/graphql/fragments/transaction-base.fragment.d.ts.map +1 -1
- package/dist/graphql/fragments/transaction-base.fragment.js +0 -1
- package/dist/graphql/fragments/transaction-base.fragment.js.map +1 -1
- package/dist/graphql/fragments/vault.fragment.d.ts +29 -1
- package/dist/graphql/fragments/vault.fragment.d.ts.map +1 -1
- package/dist/graphql/fragments/vault.fragment.js +29 -0
- package/dist/graphql/fragments/vault.fragment.js.map +1 -1
- package/dist/graphql/queries/composition.queries.d.ts +10 -28
- package/dist/graphql/queries/composition.queries.d.ts.map +1 -1
- package/dist/graphql/queries/composition.queries.js +17 -28
- package/dist/graphql/queries/composition.queries.js.map +1 -1
- package/dist/graphql/queries/discovery.queries.d.ts +50 -0
- package/dist/graphql/queries/discovery.queries.d.ts.map +1 -0
- package/dist/graphql/queries/discovery.queries.js +188 -0
- package/dist/graphql/queries/discovery.queries.js.map +1 -0
- package/dist/graphql/queries/export.queries.d.ts +5 -7
- package/dist/graphql/queries/export.queries.d.ts.map +1 -1
- package/dist/graphql/queries/export.queries.js +22 -28
- package/dist/graphql/queries/export.queries.js.map +1 -1
- package/dist/graphql/queries/index.d.ts +4 -3
- package/dist/graphql/queries/index.d.ts.map +1 -1
- package/dist/graphql/queries/index.js +5 -3
- package/dist/graphql/queries/index.js.map +1 -1
- package/dist/graphql/queries/performance.queries.d.ts +6 -4
- package/dist/graphql/queries/performance.queries.d.ts.map +1 -1
- package/dist/graphql/queries/performance.queries.js +5 -11
- package/dist/graphql/queries/performance.queries.js.map +1 -1
- package/dist/graphql/queries/portfolio.queries.d.ts +6 -12
- package/dist/graphql/queries/portfolio.queries.d.ts.map +1 -1
- package/dist/graphql/queries/portfolio.queries.js +21 -88
- package/dist/graphql/queries/portfolio.queries.js.map +1 -1
- package/dist/graphql/queries/prediction.queries.d.ts +13 -15
- package/dist/graphql/queries/prediction.queries.d.ts.map +1 -1
- package/dist/graphql/queries/prediction.queries.js +12 -31
- package/dist/graphql/queries/prediction.queries.js.map +1 -1
- package/dist/graphql/queries/risk.queries.d.ts +3 -3
- package/dist/graphql/queries/risk.queries.d.ts.map +1 -1
- package/dist/graphql/queries/risk.queries.js +7 -22
- package/dist/graphql/queries/risk.queries.js.map +1 -1
- package/dist/graphql/queries/search.queries.d.ts.map +1 -1
- package/dist/graphql/queries/search.queries.js +6 -2
- package/dist/graphql/queries/search.queries.js.map +1 -1
- package/dist/graphql/queries/transaction.queries.d.ts +6 -26
- package/dist/graphql/queries/transaction.queries.d.ts.map +1 -1
- package/dist/graphql/queries/transaction.queries.js +227 -59
- package/dist/graphql/queries/transaction.queries.js.map +1 -1
- package/dist/graphql/queries/vault.queries.d.ts +21 -3
- package/dist/graphql/queries/vault.queries.d.ts.map +1 -1
- package/dist/graphql/queries/vault.queries.js +38 -0
- package/dist/graphql/queries/vault.queries.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/services/analytics/risk.service.d.ts +52 -33
- package/dist/services/analytics/risk.service.d.ts.map +1 -1
- package/dist/services/analytics/risk.service.js +165 -155
- package/dist/services/analytics/risk.service.js.map +1 -1
- package/dist/tools/compare-vaults.d.ts.map +1 -1
- package/dist/tools/compare-vaults.js +50 -77
- package/dist/tools/compare-vaults.js.map +1 -1
- package/dist/tools/export-data.d.ts.map +1 -1
- package/dist/tools/export-data.js +10 -16
- package/dist/tools/export-data.js.map +1 -1
- package/dist/tools/get-asset.d.ts +17 -0
- package/dist/tools/get-asset.d.ts.map +1 -0
- package/dist/tools/get-asset.js +44 -0
- package/dist/tools/get-asset.js.map +1 -0
- package/dist/tools/get-curator.d.ts +13 -0
- package/dist/tools/get-curator.d.ts.map +1 -0
- package/dist/tools/get-curator.js +81 -0
- package/dist/tools/get-curator.js.map +1 -0
- package/dist/tools/get-global-tvl.d.ts +20 -0
- package/dist/tools/get-global-tvl.d.ts.map +1 -0
- package/dist/tools/get-global-tvl.js +38 -0
- package/dist/tools/get-global-tvl.js.map +1 -0
- package/dist/tools/get-historical-state.d.ts +22 -0
- package/dist/tools/get-historical-state.d.ts.map +1 -0
- package/dist/tools/get-historical-state.js +65 -0
- package/dist/tools/get-historical-state.js.map +1 -0
- package/dist/tools/get-indexing-status.d.ts +20 -0
- package/dist/tools/get-indexing-status.d.ts.map +1 -0
- package/dist/tools/get-indexing-status.js +38 -0
- package/dist/tools/get-indexing-status.js.map +1 -0
- package/dist/tools/get-price-history.d.ts.map +1 -1
- package/dist/tools/get-price-history.js +55 -63
- package/dist/tools/get-price-history.js.map +1 -1
- package/dist/tools/get-transactions.d.ts.map +1 -1
- package/dist/tools/get-transactions.js +3 -1
- package/dist/tools/get-transactions.js.map +1 -1
- package/dist/tools/list-chains.d.ts +16 -0
- package/dist/tools/list-chains.d.ts.map +1 -0
- package/dist/tools/list-chains.js +46 -0
- package/dist/tools/list-chains.js.map +1 -0
- package/dist/tools/list-curators.d.ts +18 -0
- package/dist/tools/list-curators.d.ts.map +1 -0
- package/dist/tools/list-curators.js +49 -0
- package/dist/tools/list-curators.js.map +1 -0
- package/dist/tools/optimize-portfolio.d.ts.map +1 -1
- package/dist/tools/optimize-portfolio.js +6 -17
- package/dist/tools/optimize-portfolio.js.map +1 -1
- package/dist/tools/predict-yield.d.ts.map +1 -1
- package/dist/tools/predict-yield.js +109 -11
- package/dist/tools/predict-yield.js.map +1 -1
- package/dist/tools/registry.d.ts.map +1 -1
- package/dist/tools/registry.js +83 -11
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/search-vaults.d.ts.map +1 -1
- package/dist/tools/search-vaults.js +9 -2
- package/dist/tools/search-vaults.js.map +1 -1
- package/dist/tools/simulate-vault.d.ts +1 -1
- package/dist/tools/user-portfolio.d.ts.map +1 -1
- package/dist/tools/user-portfolio.js +30 -51
- package/dist/tools/user-portfolio.js.map +1 -1
- package/dist/tools/vault-composition.d.ts +18 -15
- package/dist/tools/vault-composition.d.ts.map +1 -1
- package/dist/tools/vault-composition.js +71 -155
- package/dist/tools/vault-composition.js.map +1 -1
- package/dist/tools/vault-performance.d.ts.map +1 -1
- package/dist/tools/vault-performance.js +7 -19
- package/dist/tools/vault-performance.js.map +1 -1
- package/dist/types/generated.d.ts +1191 -21
- package/dist/types/generated.d.ts.map +1 -1
- package/dist/utils/comparison-metrics.d.ts +13 -1
- package/dist/utils/comparison-metrics.d.ts.map +1 -1
- package/dist/utils/comparison-metrics.js +29 -4
- package/dist/utils/comparison-metrics.js.map +1 -1
- package/dist/utils/composition-metrics.d.ts +42 -0
- package/dist/utils/composition-metrics.d.ts.map +1 -0
- package/dist/utils/composition-metrics.js +50 -0
- package/dist/utils/composition-metrics.js.map +1 -0
- package/dist/utils/csv-generator.d.ts +4 -1
- package/dist/utils/csv-generator.d.ts.map +1 -1
- package/dist/utils/csv-generator.js +8 -4
- package/dist/utils/csv-generator.js.map +1 -1
- package/dist/utils/fee-formatting.d.ts +41 -0
- package/dist/utils/fee-formatting.d.ts.map +1 -0
- package/dist/utils/fee-formatting.js +57 -0
- package/dist/utils/fee-formatting.js.map +1 -0
- package/dist/utils/operational-signals.d.ts +55 -0
- package/dist/utils/operational-signals.d.ts.map +1 -0
- package/dist/utils/operational-signals.js +105 -0
- package/dist/utils/operational-signals.js.map +1 -0
- package/dist/utils/tool-error-handler.d.ts.map +1 -1
- package/dist/utils/tool-error-handler.js +8 -6
- package/dist/utils/tool-error-handler.js.map +1 -1
- package/dist/utils/validators.d.ts +112 -3
- package/dist/utils/validators.d.ts.map +1 -1
- package/dist/utils/validators.js +108 -4
- package/dist/utils/validators.js.map +1 -1
- package/dist/utils/yield-prediction.d.ts +3 -0
- package/dist/utils/yield-prediction.d.ts.map +1 -1
- package/dist/utils/yield-prediction.js +13 -1
- package/dist/utils/yield-prediction.js.map +1 -1
- package/package.json +2 -2
- package/dist/graphql/fragments.d.ts +0 -183
- package/dist/graphql/fragments.d.ts.map +0 -1
- package/dist/graphql/fragments.js +0 -297
- package/dist/graphql/fragments.js.map +0 -1
- package/dist/graphql/queries/period-summaries.d.ts +0 -15
- package/dist/graphql/queries/period-summaries.d.ts.map +0 -1
- package/dist/graphql/queries/period-summaries.js +0 -24
- package/dist/graphql/queries/period-summaries.js.map +0 -1
- package/dist/services/analytics/protocol-overview.service.d.ts +0 -61
- package/dist/services/analytics/protocol-overview.service.d.ts.map +0 -1
- package/dist/services/analytics/protocol-overview.service.js +0 -182
- package/dist/services/analytics/protocol-overview.service.js.map +0 -1
- package/dist/tools/index.d.ts +0 -26
- package/dist/tools/index.d.ts.map +0 -1
- package/dist/tools/index.js +0 -32
- package/dist/tools/index.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-vaults.js","sourceRoot":"","sources":["../../src/tools/search-vaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAsBrD;;;GAGG;AACH,SAAS,mBAAmB,CAAC,OAAqC;IAChE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,cAAc,GAA4B,EAAE,CAAC;IAEnD,yDAAyD;IACzD,MAAM,aAAa,GAAG;QACpB,gBAAgB;QAChB,gBAAgB;QAChB,YAAY;QACZ,YAAY;QACZ,YAAY;QACZ,YAAY;QACZ,qBAAqB;QACrB,yBAAyB;QACzB,cAAc;QACd,YAAY;QACZ,YAAY;QACZ,WAAW;QACX,WAAW;QACX,iBAAiB;QACjB,iBAAiB;KACT,CAAC;IAEX,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,GAAG,IAAI,OAAO,IAAI,OAAO,CAAC,GAA2B,CAAC,KAAK,SAAS,EAAE,CAAC;YACzE,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAA2B,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,OAAqC;IACxD,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IAMD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SACvC,IAAI,EAAE;SACN,MAAM,CAAqD,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvE,MAAM,QAAQ,GAAG,GAAgB,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,mFAAmF;YAClF,GAAkC,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QACxD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;
|
|
1
|
+
{"version":3,"file":"search-vaults.js","sourceRoot":"","sources":["../../src/tools/search-vaults.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAGH,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAE/E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAsBrD;;;GAGG;AACH,SAAS,mBAAmB,CAAC,OAAqC;IAChE,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,cAAc,GAA4B,EAAE,CAAC;IAEnD,yDAAyD;IACzD,MAAM,aAAa,GAAG;QACpB,gBAAgB;QAChB,gBAAgB;QAChB,YAAY;QACZ,YAAY;QACZ,YAAY;QACZ,YAAY;QACZ,qBAAqB;QACrB,yBAAyB;QACzB,cAAc;QACd,YAAY;QACZ,YAAY;QACZ,WAAW;QACX,WAAW;QACX,iBAAiB;QACjB,iBAAiB;KACT,CAAC;IAEX,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAChC,IAAI,GAAG,IAAI,OAAO,IAAI,OAAO,CAAC,GAA2B,CAAC,KAAK,SAAS,EAAE,CAAC;YACzE,cAAc,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAA2B,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;IAED,OAAO,cAAc,CAAC;AACxB,CAAC;AAED;;;GAGG;AACH,SAAS,WAAW,CAAC,OAAqC;IACxD,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC;IACjB,CAAC;IAMD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;SACvC,IAAI,EAAE;SACN,MAAM,CAAqD,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvE,MAAM,QAAQ,GAAG,GAAgB,CAAC;QAClC,MAAM,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;QAChC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;YACxB,mFAAmF;YAClF,GAAkC,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QACxD,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,EAAE,EAAE,CAAC,CAAC;IAET,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAeD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAA2B;IAE3B,OAAO,KAAK,EAAE,KAAwB,EAA2B,EAAE;QACjE,kFAAkF;QAClF,MAAM,cAAc,GAAG,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,GAAG,CAAC;QAC1F,MAAM,UAAU,GAAG;YACjB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,kBAAkB;YACxD,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC;SAC1C,CAAC;QAEF,4BAA4B;QAC5B,MAAM,cAAc,GAClB,KAAK,CAAC,cAAc,KAAK,SAAS;YAChC,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,KAAK,CAAC,cAAc,KAAK,MAAM;gBAC/B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,MAAM,CAAC;QAEf,wEAAwE;QACxE,mEAAmE;QACnE,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,MAAM,SAAS,GACb,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;YAC3C,CAAC,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE;YAC9C,CAAC,CAAC,EAAE,CAAC;QACT,MAAM,QAAQ,GAAG,GAAG,SAAS,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAC,IAAI,UAAU,CAAC,KAAK,IAAI,UAAU,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,cAAc,IAAI,cAAc,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;QAEzL,uCAAuC;QACvC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QAEhE,6DAA6D;QAC7D,MAAM,KAAK,GAAW,uBAAuB,CAAC,cAAc,CAAC,CAAC;QAE9D,MAAM,QAAQ,GAAG,oBAAoB,CAInC;YACA,SAAS;YACT,QAAQ,EAAE,GAAG,EAAE,CAAC,QAAQ;YACxB,QAAQ,EAAE,QAAQ,CAAC,aAAa;YAChC,KAAK;YACL,SAAS,EAAE,GAAG,EAAE;gBACd,MAAM,WAAW,GAAG,mBAAmB,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvD,OAAO;oBACL,KAAK,EAAE,UAAU,CAAC,KAAK;oBACvB,IAAI,EAAE,UAAU,CAAC,IAAI;oBACrB,uEAAuE;oBACvE,qDAAqD;oBACrD,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,gBAAgB;oBAC1C,cAAc,EAAE,KAAK,CAAC,cAAc,IAAI,MAAM;oBAC9C,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS;oBACpE,MAAM,EAAE,KAAK,CAAC,MAAM;oBACpB,SAAS,EAAE,KAAK,CAAC,SAAS;iBAC3B,CAAC;YACJ,CAAC;YACD,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE;gBACvB,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAChE,OAAO;oBACL,KAAK,EAAE,OAAO;oBACd,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,kDAAkD;oBACjF,OAAO,EAAE,CAAC,OAAO;iBAClB,CAAC;YACJ,CAAC;YACD,QAAQ,EAAE,eAAe;SAC1B,CAAC,CAAC;QAEH,gBAAgB;QAChB,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,CAAC,CAAC;QAErC,+EAA+E;QAC/E,4DAA4D;QAC5D,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1D,IAAI,CAAC;gBACH,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAErD,CAAC;gBACF,IAAI,YAAY,CAAC,MAAM,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC3E,6DAA6D;oBAC7D,MAAM,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC;oBACzC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;wBACvB,IAAI,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,CAAC;4BACpB,8DAA8D;4BAC9D,uFAAuF;4BACtF,KAAyC,CAAC,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;4BAE5E,wDAAwD;4BACxD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gCAClB,MAAM,aAAa,GAAG,gBAAgB,CAAC,QAAQ,CAAC,KAAK,EAAE;oCACrD,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC;oCAC9B,OAAO,EAAE,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;iCAChC,CAAC,CAAC;gCACH,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,CAAC;4BAChE,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CAAC;oBAEH,+CAA+C;oBAC/C,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;gBACxD,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,8DAA8D;gBAC9D,sCAAsC;YACxC,CAAC;QACH,CAAC;QAED,iCAAiC;QACjC,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;YAC1D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;QACvF,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -38,8 +38,8 @@ export declare const simulateVaultInputSchema: z.ZodObject<{
|
|
|
38
38
|
}, "strip", z.ZodTypeAny, {
|
|
39
39
|
vaultAddress: string;
|
|
40
40
|
chainId: number;
|
|
41
|
-
settleDeposit: boolean;
|
|
42
41
|
newTotalAssets: string;
|
|
42
|
+
settleDeposit: boolean;
|
|
43
43
|
includeAPRCalculations: boolean;
|
|
44
44
|
}, {
|
|
45
45
|
vaultAddress: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-portfolio.d.ts","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"user-portfolio.d.ts","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAc/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAqSxD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,gBAAgB,GAC1B,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,cAAc,CAAC,CAgJ3D"}
|
|
@@ -19,39 +19,28 @@
|
|
|
19
19
|
* - Cache tags: [CacheTag.PORTFOLIO] for invalidation
|
|
20
20
|
*/
|
|
21
21
|
import { getToolDisclaimer } from '../utils/disclaimers.js';
|
|
22
|
+
import { calculateHHI, getDiversificationLevel, } from '../utils/composition-metrics.js';
|
|
22
23
|
import { createGetUserPortfolioQuery, SINGLE_VAULT_COMPOSITION_QUERY, } from '../graphql/queries/portfolio.queries.js';
|
|
23
24
|
import { executeToolWithCache } from '../utils/execute-tool-with-cache.js';
|
|
24
25
|
import { CacheTag } from '../core/cache-invalidation.js';
|
|
25
26
|
import { cacheKeys, cacheTTL, generateCacheKey } from '../cache/index.js';
|
|
26
27
|
import { rateLimitedMap } from '../utils/rate-limiter.js';
|
|
27
28
|
/**
|
|
28
|
-
* Transform
|
|
29
|
-
*
|
|
29
|
+
* Transform typed CompositionData into the portfolio-aggregation
|
|
30
|
+
* ProcessedProtocolSummary shape. Backend already provides repartition
|
|
31
|
+
* (percentage) and sorts by it desc — no client-side normalization needed.
|
|
30
32
|
*/
|
|
31
|
-
function
|
|
32
|
-
if (!
|
|
33
|
+
function transformCompositionToProtocols(composition) {
|
|
34
|
+
if (!composition || composition.compositions.length === 0)
|
|
33
35
|
return [];
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
.map(([key, protocol]) => ({
|
|
42
|
-
protocolKey: key,
|
|
43
|
-
protocolName: protocol.name,
|
|
44
|
-
valueUsd: parseFloat(protocol.value),
|
|
45
|
-
percentage: 0, // Calculate after total
|
|
36
|
+
return composition.compositions
|
|
37
|
+
.filter((p) => p.valueInUsd > 0)
|
|
38
|
+
.map((p) => ({
|
|
39
|
+
protocolKey: p.protocol,
|
|
40
|
+
protocolName: p.protocol,
|
|
41
|
+
valueUsd: p.valueInUsd,
|
|
42
|
+
percentage: p.repartition,
|
|
46
43
|
}));
|
|
47
|
-
// Calculate percentages
|
|
48
|
-
const totalValue = protocols.reduce((sum, p) => sum + p.valueUsd, 0);
|
|
49
|
-
protocols.forEach((p) => {
|
|
50
|
-
p.percentage = totalValue > 0 ? (p.valueUsd / totalValue) * 100 : 0;
|
|
51
|
-
});
|
|
52
|
-
// Sort by value descending
|
|
53
|
-
protocols.sort((a, b) => b.valueUsd - a.valueUsd);
|
|
54
|
-
return protocols;
|
|
55
44
|
}
|
|
56
45
|
/**
|
|
57
46
|
* Aggregate composition data across all portfolio positions
|
|
@@ -100,27 +89,12 @@ function aggregatePortfolioComposition(vaultCompositions, totalPortfolioValue) {
|
|
|
100
89
|
vaultCount: data.vaultAddresses.length,
|
|
101
90
|
}))
|
|
102
91
|
.sort((a, b) => b.repartition - a.repartition);
|
|
103
|
-
//
|
|
104
|
-
|
|
105
|
-
const
|
|
106
|
-
// Recalculate percentages for DeFi-only (for HHI)
|
|
107
|
-
const defiTotalValue = defiExposures.reduce((sum, e) => sum + e.valueUsd, 0);
|
|
108
|
-
const defiExposuresForHHI = defiExposures.map((e) => ({
|
|
109
|
-
...e,
|
|
110
|
-
repartition: defiTotalValue > 0 ? (e.valueUsd / defiTotalValue) * 100 : 0,
|
|
111
|
-
}));
|
|
112
|
-
// Calculate portfolio-level HHI (excluding wallet)
|
|
113
|
-
const portfolioHHI = defiExposuresForHHI.reduce((sum, e) => sum + Math.pow(e.repartition / 100, 2), 0);
|
|
114
|
-
// Determine diversification level
|
|
115
|
-
const diversificationLevel = portfolioHHI < 0.15 ? 'High' : portfolioHHI < 0.25 ? 'Medium' : 'Low';
|
|
116
|
-
// Calculate idle assets percentage
|
|
117
|
-
const idleAssetsPercent = walletExposure?.repartition || 0;
|
|
92
|
+
// The v0.6+ typed CompositionData doesn't surface a "Wallet" / idle-assets
|
|
93
|
+
// entry — see docs/agent-notes.md gotcha #8. HHI walks every entry.
|
|
94
|
+
const portfolioHHI = calculateHHI(allExposures.map((e) => e.repartition));
|
|
118
95
|
// Detect accidental concentration (same protocol in 3+ vaults with >20% total exposure)
|
|
119
96
|
const accidentalConcentration = [];
|
|
120
97
|
for (const [protocolKey, data] of protocolExposureMap.entries()) {
|
|
121
|
-
// Skip wallet for concentration warnings
|
|
122
|
-
if (protocolKey === 'wallet')
|
|
123
|
-
continue;
|
|
124
98
|
const totalExposure = totalPortfolioValue > 0 ? (data.valueUsd / totalPortfolioValue) * 100 : 0;
|
|
125
99
|
if (data.vaultAddresses.length >= 3 && totalExposure >= 20) {
|
|
126
100
|
accidentalConcentration.push({
|
|
@@ -133,12 +107,11 @@ function aggregatePortfolioComposition(vaultCompositions, totalPortfolioValue) {
|
|
|
133
107
|
}
|
|
134
108
|
}
|
|
135
109
|
return {
|
|
136
|
-
protocolExposure: allExposures.slice(0, 10),
|
|
137
|
-
portfolioHHI
|
|
138
|
-
diversificationLevel,
|
|
139
|
-
topProtocol:
|
|
140
|
-
topProtocolPercent:
|
|
141
|
-
idleAssetsPercent: parseFloat(idleAssetsPercent.toFixed(2)),
|
|
110
|
+
protocolExposure: allExposures.slice(0, 10),
|
|
111
|
+
portfolioHHI,
|
|
112
|
+
diversificationLevel: getDiversificationLevel(portfolioHHI, allExposures.length === 0),
|
|
113
|
+
topProtocol: allExposures[0]?.protocolName || null,
|
|
114
|
+
topProtocolPercent: allExposures[0]?.repartition || null,
|
|
142
115
|
accidentalConcentration,
|
|
143
116
|
};
|
|
144
117
|
}
|
|
@@ -219,7 +192,10 @@ export function createExecuteGetUserPortfolio(container) {
|
|
|
219
192
|
const hasData = !!(data.users.items && data.users.items.length > 0);
|
|
220
193
|
return {
|
|
221
194
|
valid: hasData,
|
|
222
|
-
|
|
195
|
+
// Echo the validated user address (not the response object, which
|
|
196
|
+
// stringifies to "[object Object]" — pre-existing bug surfaced by
|
|
197
|
+
// the smoke harness).
|
|
198
|
+
message: hasData ? undefined : `No portfolio data found for user: ${input.userAddress}`,
|
|
223
199
|
isError: !hasData,
|
|
224
200
|
};
|
|
225
201
|
},
|
|
@@ -260,8 +236,11 @@ export function createExecuteGetUserPortfolio(container) {
|
|
|
260
236
|
// Rate limited to prevent 429 errors from GraphQL API
|
|
261
237
|
const compositionResults = await rateLimitedMap(positions, async (position) => {
|
|
262
238
|
try {
|
|
263
|
-
const compResponse = await container.graphqlClient.request(SINGLE_VAULT_COMPOSITION_QUERY, {
|
|
264
|
-
|
|
239
|
+
const compResponse = await container.graphqlClient.request(SINGLE_VAULT_COMPOSITION_QUERY, {
|
|
240
|
+
address: position.vaultAddress,
|
|
241
|
+
chainId: Number(position.vault.chain?.id ?? 0),
|
|
242
|
+
});
|
|
243
|
+
const protocols = transformCompositionToProtocols(compResponse.vaultByAddress?.composition ?? null);
|
|
265
244
|
if (protocols.length > 0) {
|
|
266
245
|
return {
|
|
267
246
|
vaultAddress: position.vaultAddress,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"user-portfolio.js","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"user-portfolio.js","sourceRoot":"","sources":["../../src/tools/user-portfolio.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* get_vault_composition Tool
|
|
3
3
|
*
|
|
4
|
-
* Fetch vault protocol composition
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Fetch a vault's DeFi protocol composition with diversification analysis.
|
|
5
|
+
* Backed by the typed `Vault.composition: CompositionData` field — v0.6+
|
|
6
|
+
* replacement for the retired `vaultComposition(walletAddress)` JSONObject
|
|
7
|
+
* query.
|
|
7
8
|
*
|
|
8
9
|
* Use cases:
|
|
9
10
|
* - Understanding vault DeFi protocol exposure
|
|
10
11
|
* - Analyzing diversification levels via HHI score
|
|
11
12
|
* - Identifying concentration risks across protocols
|
|
12
|
-
* - Tracking idle assets (wallet protocol)
|
|
13
13
|
* - Portfolio composition visualization
|
|
14
14
|
*
|
|
15
|
+
* Migration notes (vs. the deprecated query):
|
|
16
|
+
* - Now requires `chainId` (the deprecated query merged chains silently,
|
|
17
|
+
* producing wrong totals for the same address on multiple chains).
|
|
18
|
+
* - `repartition` is pre-computed by the backend — no client-side
|
|
19
|
+
* percentage calculation.
|
|
20
|
+
* - The "Wallet" / `idleAssetsPercent` field is GONE — the typed API doesn't
|
|
21
|
+
* surface idle assets. See docs/agent-notes.md gotcha #8.
|
|
22
|
+
* - `positionTypes` is GONE — per-chain protocol-position categorization
|
|
23
|
+
* isn't exposed in the typed shape.
|
|
24
|
+
*
|
|
15
25
|
* Response formats (for token optimization):
|
|
16
|
-
* - summary:
|
|
17
|
-
* - protocols:
|
|
18
|
-
* - full: All
|
|
26
|
+
* - summary: Top protocols + analysis (~100 tokens)
|
|
27
|
+
* - protocols: All non-zero protocols + analysis (~200-500 tokens)
|
|
28
|
+
* - full: All data including tokenCompositions (~600-1000 tokens)
|
|
19
29
|
*
|
|
20
30
|
* Cache strategy:
|
|
21
31
|
* - 15-minute TTL aligned with vault data freshness
|
|
22
|
-
* - Cache key: composition:{address}
|
|
23
|
-
* - Full data cached, format filtering applied at response time
|
|
32
|
+
* - Cache key: composition:{address}:{chainId}
|
|
24
33
|
*/
|
|
25
34
|
import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
26
35
|
import { GetVaultCompositionInput } from '../utils/validators.js';
|
|
27
36
|
import { ServiceContainer } from '../core/container.js';
|
|
28
|
-
/**
|
|
29
|
-
* Create the executeGetVaultComposition function with DI container
|
|
30
|
-
*
|
|
31
|
-
* @param container - Service container with dependencies
|
|
32
|
-
* @returns Configured tool executor function
|
|
33
|
-
*/
|
|
34
37
|
export declare function createExecuteGetVaultComposition(container: ServiceContainer): (input: GetVaultCompositionInput) => Promise<CallToolResult>;
|
|
35
38
|
//# sourceMappingURL=vault-composition.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-composition.d.ts","sourceRoot":"","sources":["../../src/tools/vault-composition.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vault-composition.d.ts","sourceRoot":"","sources":["../../src/tools/vault-composition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAKlE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAmKxD,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,gBAAgB,GAC1B,CAAC,KAAK,EAAE,wBAAwB,KAAK,OAAO,CAAC,cAAc,CAAC,CAqE9D"}
|
|
@@ -1,26 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* get_vault_composition Tool
|
|
3
3
|
*
|
|
4
|
-
* Fetch vault protocol composition
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Fetch a vault's DeFi protocol composition with diversification analysis.
|
|
5
|
+
* Backed by the typed `Vault.composition: CompositionData` field — v0.6+
|
|
6
|
+
* replacement for the retired `vaultComposition(walletAddress)` JSONObject
|
|
7
|
+
* query.
|
|
7
8
|
*
|
|
8
9
|
* Use cases:
|
|
9
10
|
* - Understanding vault DeFi protocol exposure
|
|
10
11
|
* - Analyzing diversification levels via HHI score
|
|
11
12
|
* - Identifying concentration risks across protocols
|
|
12
|
-
* - Tracking idle assets (wallet protocol)
|
|
13
13
|
* - Portfolio composition visualization
|
|
14
14
|
*
|
|
15
|
+
* Migration notes (vs. the deprecated query):
|
|
16
|
+
* - Now requires `chainId` (the deprecated query merged chains silently,
|
|
17
|
+
* producing wrong totals for the same address on multiple chains).
|
|
18
|
+
* - `repartition` is pre-computed by the backend — no client-side
|
|
19
|
+
* percentage calculation.
|
|
20
|
+
* - The "Wallet" / `idleAssetsPercent` field is GONE — the typed API doesn't
|
|
21
|
+
* surface idle assets. See docs/agent-notes.md gotcha #8.
|
|
22
|
+
* - `positionTypes` is GONE — per-chain protocol-position categorization
|
|
23
|
+
* isn't exposed in the typed shape.
|
|
24
|
+
*
|
|
15
25
|
* Response formats (for token optimization):
|
|
16
|
-
* - summary:
|
|
17
|
-
* - protocols:
|
|
18
|
-
* - full: All
|
|
26
|
+
* - summary: Top protocols + analysis (~100 tokens)
|
|
27
|
+
* - protocols: All non-zero protocols + analysis (~200-500 tokens)
|
|
28
|
+
* - full: All data including tokenCompositions (~600-1000 tokens)
|
|
19
29
|
*
|
|
20
30
|
* Cache strategy:
|
|
21
31
|
* - 15-minute TTL aligned with vault data freshness
|
|
22
|
-
* - Cache key: composition:{address}
|
|
23
|
-
* - Full data cached, format filtering applied at response time
|
|
32
|
+
* - Cache key: composition:{address}:{chainId}
|
|
24
33
|
*/
|
|
25
34
|
import { getToolDisclaimer } from '../utils/disclaimers.js';
|
|
26
35
|
import { GET_VAULT_COMPOSITION_QUERY } from '../graphql/queries/index.js';
|
|
@@ -28,220 +37,127 @@ import { executeToolWithCache } from '../utils/execute-tool-with-cache.js';
|
|
|
28
37
|
import { CacheTag } from '../core/cache-invalidation.js';
|
|
29
38
|
import { cacheKeys, cacheTTL } from '../cache/index.js';
|
|
30
39
|
import { createSuccessResponse } from '../utils/tool-response.js';
|
|
40
|
+
import { calculateHHI, getDiversificationLevel, } from '../utils/composition-metrics.js';
|
|
31
41
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* HHI ranges (using market concentration thresholds):
|
|
36
|
-
* - < 0.15: High diversification (well-diversified)
|
|
37
|
-
* - 0.15 - 0.25: Moderate concentration
|
|
38
|
-
* - > 0.25: High concentration
|
|
39
|
-
*
|
|
40
|
-
* Note: "wallet" protocol (idle assets) is EXCLUDED from HHI calculation
|
|
41
|
-
* as it represents undeployed capital, not DeFi protocol concentration.
|
|
42
|
-
*
|
|
43
|
-
* @param protocols - Array of protocol summaries with percentage values (excluding wallet)
|
|
44
|
-
* @returns HHI score between 0 and 1
|
|
45
|
-
*/
|
|
46
|
-
function calculateHHI(protocols) {
|
|
47
|
-
if (protocols.length === 0)
|
|
48
|
-
return 0;
|
|
49
|
-
// HHI = sum of squared market shares (percentage/100 to get decimal)
|
|
50
|
-
return protocols.reduce((sum, p) => sum + Math.pow(p.percentage / 100, 2), 0);
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Get diversification level label based on HHI score
|
|
42
|
+
* Transform the typed `Vault.composition` payload into the analyst-friendly
|
|
43
|
+
* `FullCompositionData` shape. Returns an empty analysis (with
|
|
44
|
+
* `diversificationLevel: 'Unknown'`) when composition is null/empty.
|
|
54
45
|
*/
|
|
55
|
-
function
|
|
56
|
-
if (
|
|
57
|
-
return 'High';
|
|
58
|
-
if (hhi < 0.25)
|
|
59
|
-
return 'Medium';
|
|
60
|
-
return 'Low';
|
|
61
|
-
}
|
|
62
|
-
/**
|
|
63
|
-
* Extract position types from a protocol's chain data
|
|
64
|
-
*
|
|
65
|
-
* @param protocol - Protocol composition data
|
|
66
|
-
* @returns Array of unique position type names (e.g., ["LENDING", "YIELD"])
|
|
67
|
-
*/
|
|
68
|
-
function extractPositionTypes(protocol) {
|
|
69
|
-
const positionTypes = new Set();
|
|
70
|
-
for (const chainData of Object.values(protocol.chains)) {
|
|
71
|
-
if (chainData.protocolPositions) {
|
|
72
|
-
for (const positionKey of Object.keys(chainData.protocolPositions)) {
|
|
73
|
-
positionTypes.add(positionKey);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return Array.from(positionTypes);
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Transform raw Octav API response into structured protocol composition data
|
|
81
|
-
*
|
|
82
|
-
* @param raw - Raw VaultCompositionFullResponse with assetByProtocols
|
|
83
|
-
* @param vaultAddress - Vault address for reference
|
|
84
|
-
* @returns Full composition data with protocol-based analysis
|
|
85
|
-
*/
|
|
86
|
-
function transformRawComposition(raw, vaultAddress) {
|
|
87
|
-
// Handle null/empty response
|
|
88
|
-
if (!raw || !raw.assetByProtocols || Object.keys(raw.assetByProtocols).length === 0) {
|
|
46
|
+
function transformTypedComposition(composition, vaultAddress) {
|
|
47
|
+
if (!composition || composition.compositions.length === 0) {
|
|
89
48
|
return {
|
|
90
49
|
vaultAddress,
|
|
91
|
-
|
|
92
|
-
rawData: raw || { address: vaultAddress, networth: '0', assetByProtocols: {}, chains: {} },
|
|
50
|
+
totalValueInUsd: composition?.totalValueInUsd ?? 0,
|
|
93
51
|
protocols: [],
|
|
52
|
+
tokenCompositions: composition?.tokenCompositions ?? [],
|
|
94
53
|
analysis: {
|
|
95
|
-
totalValueUsd: 0,
|
|
96
|
-
|
|
54
|
+
totalValueUsd: composition?.totalValueInUsd ?? 0,
|
|
55
|
+
protocolCount: 0,
|
|
97
56
|
topProtocol: null,
|
|
98
57
|
hhi: 0,
|
|
99
|
-
diversificationLevel: '
|
|
100
|
-
idleAssetsPercent: 0,
|
|
58
|
+
diversificationLevel: 'Unknown',
|
|
101
59
|
},
|
|
102
60
|
};
|
|
103
61
|
}
|
|
104
|
-
//
|
|
105
|
-
const
|
|
106
|
-
.
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
.map(([key, protocol]) => ({
|
|
111
|
-
protocolKey: key,
|
|
112
|
-
protocolName: protocol.name,
|
|
113
|
-
valueUsd: parseFloat(protocol.value),
|
|
114
|
-
percentage: 0, // Calculate after total
|
|
115
|
-
positionTypes: extractPositionTypes(protocol),
|
|
116
|
-
chainCount: Object.keys(protocol.chains).length,
|
|
62
|
+
// Backend returns entries sorted by repartition desc — preserve that order.
|
|
63
|
+
const protocols = composition.compositions.map((p) => ({
|
|
64
|
+
protocol: p.protocol,
|
|
65
|
+
valueUsd: p.valueInUsd,
|
|
66
|
+
percentage: p.repartition,
|
|
67
|
+
logoUrl: p.logoUrl ?? null,
|
|
117
68
|
}));
|
|
118
|
-
|
|
119
|
-
const totalValueUsd = allProtocols.reduce((sum, p) => sum + p.valueUsd, 0);
|
|
120
|
-
// 3. Calculate percentages for all protocols
|
|
121
|
-
allProtocols.forEach((p) => {
|
|
122
|
-
p.percentage = totalValueUsd > 0 ? (p.valueUsd / totalValueUsd) * 100 : 0;
|
|
123
|
-
});
|
|
124
|
-
// 4. Sort by value descending
|
|
125
|
-
allProtocols.sort((a, b) => b.valueUsd - a.valueUsd);
|
|
126
|
-
// 5. Separate wallet (idle assets) from DeFi protocols for HHI calculation
|
|
127
|
-
const walletProtocol = allProtocols.find((p) => p.protocolKey === 'wallet');
|
|
128
|
-
const defiProtocols = allProtocols.filter((p) => p.protocolKey !== 'wallet');
|
|
129
|
-
// 6. Recalculate percentages for DeFi protocols only (for HHI)
|
|
130
|
-
const defiTotalValue = defiProtocols.reduce((sum, p) => sum + p.valueUsd, 0);
|
|
131
|
-
const defiProtocolsForHHI = defiProtocols.map((p) => ({
|
|
132
|
-
...p,
|
|
133
|
-
// Recalculate percentage based on DeFi-only total for HHI
|
|
134
|
-
percentage: defiTotalValue > 0 ? (p.valueUsd / defiTotalValue) * 100 : 0,
|
|
135
|
-
}));
|
|
136
|
-
// 7. Calculate HHI (excluding wallet)
|
|
137
|
-
const hhi = calculateHHI(defiProtocolsForHHI);
|
|
138
|
-
// 8. Calculate idle assets percentage
|
|
139
|
-
const idleAssetsPercent = walletProtocol
|
|
140
|
-
? totalValueUsd > 0
|
|
141
|
-
? (walletProtocol.valueUsd / totalValueUsd) * 100
|
|
142
|
-
: 0
|
|
143
|
-
: 0;
|
|
69
|
+
const hhi = calculateHHI(composition.compositions.map((p) => p.repartition));
|
|
144
70
|
return {
|
|
145
71
|
vaultAddress,
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
72
|
+
totalValueInUsd: composition.totalValueInUsd ?? 0,
|
|
73
|
+
protocols,
|
|
74
|
+
tokenCompositions: composition.tokenCompositions,
|
|
149
75
|
analysis: {
|
|
150
|
-
totalValueUsd:
|
|
151
|
-
|
|
152
|
-
topProtocol:
|
|
153
|
-
hhi
|
|
76
|
+
totalValueUsd: composition.totalValueInUsd ?? 0,
|
|
77
|
+
protocolCount: protocols.length,
|
|
78
|
+
topProtocol: protocols[0] ?? null,
|
|
79
|
+
hhi,
|
|
154
80
|
diversificationLevel: getDiversificationLevel(hhi),
|
|
155
|
-
idleAssetsPercent: parseFloat(idleAssetsPercent.toFixed(2)),
|
|
156
81
|
},
|
|
157
82
|
};
|
|
158
83
|
}
|
|
159
|
-
/**
|
|
160
|
-
* Filter full data based on requested response format
|
|
161
|
-
*
|
|
162
|
-
* @param data - Full composition data
|
|
163
|
-
* @param format - Requested response format
|
|
164
|
-
* @returns Filtered response based on format
|
|
165
|
-
*/
|
|
166
84
|
function filterByFormat(data, format) {
|
|
167
85
|
switch (format) {
|
|
168
86
|
case 'summary':
|
|
169
87
|
return {
|
|
170
88
|
vaultAddress: data.vaultAddress,
|
|
171
89
|
analysis: data.analysis,
|
|
172
|
-
topProtocols: data.protocols.slice(0, 5),
|
|
90
|
+
topProtocols: data.protocols.slice(0, 5),
|
|
173
91
|
};
|
|
174
92
|
case 'protocols':
|
|
175
93
|
return {
|
|
176
94
|
vaultAddress: data.vaultAddress,
|
|
177
|
-
protocols: data.protocols,
|
|
95
|
+
protocols: data.protocols,
|
|
178
96
|
analysis: data.analysis,
|
|
179
97
|
};
|
|
180
98
|
case 'full':
|
|
181
99
|
default:
|
|
182
100
|
return {
|
|
183
101
|
vaultAddress: data.vaultAddress,
|
|
184
|
-
|
|
185
|
-
rawData: data.rawData,
|
|
102
|
+
totalValueInUsd: data.totalValueInUsd,
|
|
186
103
|
protocols: data.protocols,
|
|
104
|
+
tokenCompositions: data.tokenCompositions,
|
|
187
105
|
analysis: data.analysis,
|
|
188
106
|
};
|
|
189
107
|
}
|
|
190
108
|
}
|
|
191
|
-
/**
|
|
192
|
-
* Create the executeGetVaultComposition function with DI container
|
|
193
|
-
*
|
|
194
|
-
* @param container - Service container with dependencies
|
|
195
|
-
* @returns Configured tool executor function
|
|
196
|
-
*/
|
|
197
109
|
export function createExecuteGetVaultComposition(container) {
|
|
198
110
|
return async (input) => {
|
|
199
111
|
const responseFormat = (input.responseFormat ?? 'summary');
|
|
200
112
|
const vaultAddress = input.vaultAddress;
|
|
201
|
-
|
|
202
|
-
const fragmentCacheKey = cacheKeys.composition(vaultAddress);
|
|
113
|
+
const chainId = input.chainId;
|
|
114
|
+
const fragmentCacheKey = cacheKeys.composition(vaultAddress, chainId);
|
|
203
115
|
const cachedComposition = container.cache.get(fragmentCacheKey);
|
|
204
116
|
if (cachedComposition) {
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
117
|
+
const filtered = filterByFormat(cachedComposition, responseFormat);
|
|
118
|
+
const result = createSuccessResponse(filtered);
|
|
119
|
+
// Disclaimer parity with the cache-miss path below (Copilot review #1).
|
|
120
|
+
if (result.content[0]?.type === 'text') {
|
|
121
|
+
result.content[0].text = result.content[0].text + getToolDisclaimer('vault_composition');
|
|
122
|
+
}
|
|
123
|
+
return result;
|
|
208
124
|
}
|
|
209
|
-
// Cache miss - execute GraphQL query with standard caching
|
|
210
125
|
const executor = executeToolWithCache({
|
|
211
126
|
container,
|
|
212
127
|
cacheKey: () => fragmentCacheKey,
|
|
213
128
|
cacheTTL: cacheTTL.composition,
|
|
214
129
|
query: GET_VAULT_COMPOSITION_QUERY,
|
|
215
|
-
variables: () => ({
|
|
216
|
-
walletAddress: vaultAddress,
|
|
217
|
-
}),
|
|
130
|
+
variables: () => ({ address: vaultAddress, chainId }),
|
|
218
131
|
validateResult: (data) => {
|
|
219
|
-
|
|
132
|
+
if (!data.vaultByAddress) {
|
|
133
|
+
return {
|
|
134
|
+
valid: false,
|
|
135
|
+
message: `Vault not found at ${vaultAddress} on chain ${chainId}`,
|
|
136
|
+
isError: false,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
220
139
|
return {
|
|
221
140
|
valid: true,
|
|
222
|
-
message: data.
|
|
141
|
+
message: data.vaultByAddress.composition
|
|
223
142
|
? undefined
|
|
224
|
-
: 'No composition data available for this vault',
|
|
225
|
-
isError: false,
|
|
143
|
+
: 'No composition data available for this vault (Octav has not been queried yet)',
|
|
226
144
|
};
|
|
227
145
|
},
|
|
228
|
-
transformResult: (data) =>
|
|
146
|
+
transformResult: (data) => transformTypedComposition(data.vaultByAddress?.composition ?? null, vaultAddress),
|
|
229
147
|
toolName: 'get_vault_composition',
|
|
230
148
|
});
|
|
231
|
-
// Register cache tags for invalidation
|
|
232
149
|
container.cacheInvalidator.register(fragmentCacheKey, [CacheTag.VAULT]);
|
|
233
150
|
const result = await executor(input);
|
|
234
|
-
// If successful, apply format filtering to the response
|
|
235
151
|
if (!result.isError && result.content[0]?.type === 'text') {
|
|
236
152
|
try {
|
|
237
153
|
const fullData = JSON.parse(result.content[0].text);
|
|
238
|
-
const
|
|
239
|
-
result.content[0].text = JSON.stringify(
|
|
154
|
+
const filtered = filterByFormat(fullData, responseFormat);
|
|
155
|
+
result.content[0].text = JSON.stringify(filtered, null, 2);
|
|
240
156
|
}
|
|
241
157
|
catch {
|
|
242
|
-
// If parsing fails, leave
|
|
158
|
+
// If parsing fails (e.g., "not found" message), leave the response
|
|
159
|
+
// text as-is so the user still sees the validation message.
|
|
243
160
|
}
|
|
244
|
-
// Add legal disclaimer to output
|
|
245
161
|
result.content[0].text = result.content[0].text + getToolDisclaimer('vault_composition');
|
|
246
162
|
}
|
|
247
163
|
return result;
|