@fangorn-network/westmarch 2026.10.29 → 2026.11.4-dev
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 +5 -5
- package/docs/app-to-agent.md +61 -625
- package/package.json +12 -17
- package/site/dist/assets/__vite-browser-external-D2U8RZpp.js +1 -0
- package/site/dist/assets/embed.worker-CmS57Zti.js +1 -0
- package/site/dist/assets/index-Djs8f08m.js +8 -0
- package/site/dist/assets/rolldown-runtime-COiEfhsA.js +1 -0
- package/site/dist/assets/{transformers.web-BTyOEJ0C.js → transformers.web-CwR_IYQV.js} +1 -1
- package/site/dist/index.html +3 -4
- package/site/worker.js +115 -338
- package/src/agent/agent-card.js +33 -45
- package/src/agent/mcp.js +168 -371
- package/src/agent/tools.js +2 -1
- package/src/agent/view-tools.js +4 -56
- package/src/agent/x402.js +182 -369
- package/src/core/roles.js +6 -6
- package/src/core/shard.js +4 -4
- package/src/discover/apps.js +67 -81
- package/src/discover/directory.js +2 -2
- package/src/market/reactions.js +21 -15
- package/src/publish/devnet.js +69 -18
- package/src/publish/init.js +1 -1
- package/src/publish/ship.js +74 -275
- package/src/publish/view.js +52 -53
- package/template/README.md +9 -11
- package/template/package.json +1 -1
- package/plugin/scripts/fx.mjs +0 -266
- package/site/dist/assets/AccountNotFoundScreen-C4njXc69-DyVH4CEz.js +0 -1
- package/site/dist/assets/AddFundsSelectionScreen-RAoCn7ej-Dz1--SS9.js +0 -31
- package/site/dist/assets/Address-H8kD1d9O-BdFZmRwI.js +0 -17
- package/site/dist/assets/AffirmativeConsentScreen-BG0MJxku-CxaCAisL.js +0 -6
- package/site/dist/assets/AllowlistRejectionScreen-Cae6e1Od-JGk7vndN.js +0 -1
- package/site/dist/assets/ApiController-CTLbMCcH.js +0 -5
- package/site/dist/assets/ArrowsRightLeftIcon-B8g9adpz.js +0 -1
- package/site/dist/assets/AuthenticateWithWalletScreen-CU6hIcFT-CXD9_OP8.js +0 -1
- package/site/dist/assets/AwaitingEvmToSolBridgingScreen-D0e_sZMS-BtJCglvU.js +0 -1
- package/site/dist/assets/AwaitingExternalEthereumTransferScreen-ur5HL4R7-BgC2TsqH.js +0 -1
- package/site/dist/assets/AwaitingPasswordlessCodeScreen-DRHz76mM-B9OzLeEO.js +0 -103
- package/site/dist/assets/AwaitingSolToEvmBridgingScreen-CdLRrGD2-C7r5snUL.js +0 -1
- package/site/dist/assets/BridgeNetworkSelectionView-CFGjB2nO-BTV0NRio.js +0 -68
- package/site/dist/assets/CaptchaScreen-DbpvkIGx-7rSZIuM-.js +0 -1
- package/site/dist/assets/CheckCircleIcon-B1l17ioc.js +0 -1
- package/site/dist/assets/CheckCircleIcon-BGSI8nKf.js +0 -1
- package/site/dist/assets/Checkbox-D1EDeo41-BUfq0w99.js +0 -52
- package/site/dist/assets/ChevronDownIcon-B6uJvPHu.js +0 -1
- package/site/dist/assets/Chip-CZKIKt9K-r9Nk__0-.js +0 -26
- package/site/dist/assets/CoinbaseOnrampStatusScreen-BbyCJDXL-DWWNHxmR.js +0 -16
- package/site/dist/assets/ConnectEmailForm-B-VRE0MN-CRQwS0Xu.js +0 -3
- package/site/dist/assets/ConnectLedgerScreen-DWHABGot-CZcCt31O.js +0 -10
- package/site/dist/assets/ConnectOnlyLandingScreen-CZYx9Bmp-C5IOf-SQ.js +0 -1
- package/site/dist/assets/ConnectOnlyStatusScreen-DCRzjxHx-cwg74F3A.js +0 -1
- package/site/dist/assets/ConnectOrCreateScreen-CUUYUO07-D28oeK6b.js +0 -1
- package/site/dist/assets/ConnectPhoneForm-Dek5xn4C-EEdkKeTp.js +0 -95
- package/site/dist/assets/ConnectWalletView-DqI-PTvX-C2mEzukj.js +0 -74
- package/site/dist/assets/ConnectionStatusScreen-fUfROm9m-CH_7r8iV.js +0 -7
- package/site/dist/assets/ConnectionStatusScreen-fUfROm9m-Z33kis0B.js +0 -1
- package/site/dist/assets/ConnectorUtil-DH4NePk5.js +0 -21
- package/site/dist/assets/ConstantsUtil-DmLsRHAl.js +0 -198
- package/site/dist/assets/CopyToClipboard-i_OQSBJr-_G88JCVR.js +0 -39
- package/site/dist/assets/CopyableText-CQapvaMr-CGGfc_zM.js +0 -28
- package/site/dist/assets/CrossAppAuthScreen-CLw7ymZq-C9Okoc0V.js +0 -1
- package/site/dist/assets/CustomLandingScreenView-Cm_MBSyX-D2l6hdSl.js +0 -22
- package/site/dist/assets/DelegatedActionsConsentScreen-DYF2U4y5-Dda3KKqS.js +0 -1
- package/site/dist/assets/DelegatedActionsRevokeScreen-bPp6Uwyh-DG8kJPt1.js +0 -1
- package/site/dist/assets/DepositAddressAddressStepView-4vdkb55L-CcOUfn6f.js +0 -187
- package/site/dist/assets/DepositAddressScreen-DBLRs7aI-DeituDNh.js +0 -8
- package/site/dist/assets/DepositAddressV3Screen-CDqIEMQw-FDg6K14-.js +0 -1
- package/site/dist/assets/EmailInputForm-Cqo1mda8-BmbxvPHC.js +0 -124
- package/site/dist/assets/EmbeddedWalletConnectingScreen-D4T7DUzs-B05CQ9rx.js +0 -1
- package/site/dist/assets/EmbeddedWalletCreatedScreen-D7WhW5ve-Cxd1b9XH.js +0 -1
- package/site/dist/assets/EmbeddedWalletKeyExportScreen-CqV4NYQ3-CrJy0ViX.js +0 -23
- package/site/dist/assets/EmbeddedWalletOnAccountCreateScreen-BoKb3Q2S-Bakaa3zu.js +0 -1
- package/site/dist/assets/EmbeddedWalletPasswordUpdateScreen-D3rMlqS7-j78vKrcj.js +0 -1
- package/site/dist/assets/EmbeddedWalletPasswordUpdateSplashScreen-BPFkWJeE-D3dr7W9_.js +0 -1
- package/site/dist/assets/EnrollTotp-Dibew4dp-BXbYV8nI.js +0 -66
- package/site/dist/assets/EnvelopeIcon-DjPofnRI.js +0 -1
- package/site/dist/assets/ErrorBanner-BcpGRt0h-BhH6_V-9.js +0 -21
- package/site/dist/assets/ErrorMessage-D8VaAP5m-Bs7uX2a9.js +0 -8
- package/site/dist/assets/ErrorScreen-DipdTWzE-BgPRgnOb.js +0 -4
- package/site/dist/assets/ErrorScreen-DipdTWzE-CvxXC6pz.js +0 -1
- package/site/dist/assets/ExclamationCircleIcon-BE-WGrut.js +0 -1
- package/site/dist/assets/ExclamationTriangleIcon-Ca1Xlc_f.js +0 -1
- package/site/dist/assets/FarcasterConnectStatusScreen-51tjUxqq-De2JvZdV.js +0 -75
- package/site/dist/assets/FarcasterSignerStatusScreen-6x-Uh95G-bLp3hXoO.js +0 -28
- package/site/dist/assets/FiatOnrampScreen-BAhYeiTI-Jr6D6JiZ.js +0 -491
- package/site/dist/assets/FingerPrintIcon-DOCbS93y.js +0 -1
- package/site/dist/assets/FundSolWalletWithExternalSolanaWallet-WtLwYaOl-A_G5kfa1.js +0 -1
- package/site/dist/assets/FundWalletMethodHeader-BWNkokCT-LPv35wkD.js +0 -1
- package/site/dist/assets/FundWithBankDepositScreen-DajkHxBD-0hfGrfvf.js +0 -58
- package/site/dist/assets/FundingEditAmountScreen-CpvpiO4M-Dz0s_NWR.js +0 -1
- package/site/dist/assets/FundingMethodSelectionScreen-Db7vhRlE-ZGm-3-Io.js +0 -1
- package/site/dist/assets/GlobeAltIcon-BBRl2MMn.js +0 -1
- package/site/dist/assets/GooglePay-B53WnudL-BGiVpB8y.js +0 -1
- package/site/dist/assets/HCaptchaWrapper-CUi9LJsp-CHdfIeD_.js +0 -4
- package/site/dist/assets/InAppBrowserLoginNotPossible-BMR9br1T-Cgoiow3m.js +0 -1
- package/site/dist/assets/InfoBanner-Cb3p1z12-_YqQmRiu.js +0 -22
- package/site/dist/assets/InjectedWalletIcon-DLcYOGDj-tuIrKQHH.js +0 -1
- package/site/dist/assets/InstallWalletScreen-DTA8dwLv-BMU_wa61.js +0 -1
- package/site/dist/assets/JsonTree-BHzNC-ic-DcVr0YF0.js +0 -34
- package/site/dist/assets/LabelXs-oqZNqbm_-CNprGVQM.js +0 -6
- package/site/dist/assets/LandingScreen-CGWUoSUG-fH6rsQen.js +0 -1
- package/site/dist/assets/Layouts-BMRfo5hw-e-sepi6F.js +0 -77
- package/site/dist/assets/Link-BdDilT2T-BdwlRJch.js +0 -40
- package/site/dist/assets/LinkConflictScreen-C3ZEPsgl-BXKN2Qm5.js +0 -77
- package/site/dist/assets/LinkEmailScreen-dKo9frwc-Cyn7Q8p1.js +0 -1
- package/site/dist/assets/LinkPasskeyScreen-zbrl_AI_-CWiqnwLM.js +0 -117
- package/site/dist/assets/LinkPasskeyScreen-zbrl_AI_-YmDevJzf.js +0 -1
- package/site/dist/assets/LinkPhoneScreen-oIUpfj0w-h7shW-Ay.js +0 -1
- package/site/dist/assets/Loader-UAZqxsnw-DJEVblm1.js +0 -62
- package/site/dist/assets/LoadingSkeleton-BMsgO5PV-D2atjsP5.js +0 -17
- package/site/dist/assets/LockClosedIcon-9EFzWK1C.js +0 -1
- package/site/dist/assets/LoginFailedScreen-CN0dJV6U-By3Si77a.js +0 -1
- package/site/dist/assets/ManualTransferScreen-CHqcuqbs-BAHPY8rs.js +0 -1
- package/site/dist/assets/MfaAuthEnrollmentFlowScreen-Dj7gPTRC-CLjffFG1.js +0 -1
- package/site/dist/assets/MfaAuthVerifyFlowScreen-DbFpyWMy-BmQg1Y61.js +0 -1
- package/site/dist/assets/MfaEnrollmentFlowScreen-DhLnGgnr-DmBtTtlw.js +0 -1
- package/site/dist/assets/MfaVerifyFlowScreen-C_XPjMRP-4a683Bmf.js +0 -1
- package/site/dist/assets/ModalFooter-BCuEK_nz-C_71qsaz.js +0 -403
- package/site/dist/assets/MoonpayStatusScreen-CzTUtokc-DEHHcEf8.js +0 -16
- package/site/dist/assets/OAuthStatusScreen-ufbOa-da-BjAb_WsY.js +0 -1
- package/site/dist/assets/OpenLink-CUpJ1mOr-BLWFsPOW.js +0 -39
- package/site/dist/assets/PasskeySelectSignupOrLogin-xh2ScC_l-2PJTJxX-.js +0 -1
- package/site/dist/assets/PasskeyStatusScreen-Bla8MaOk-DCEg761l.js +0 -6
- package/site/dist/assets/PasswordRecoveryScreen-awGXZkQk-8nVjNc8k.js +0 -20
- package/site/dist/assets/PhArrowCircleDown-D97G-BOA.js +0 -14
- package/site/dist/assets/PhArrowClockwise-DVgyFuez.js +0 -14
- package/site/dist/assets/PhArrowDown-87b1BizM.js +0 -14
- package/site/dist/assets/PhArrowLeft-Da0MfnbK.js +0 -14
- package/site/dist/assets/PhArrowRight-AdrIL4DW.js +0 -14
- package/site/dist/assets/PhArrowSquareOut-Bk2CMG3I.js +0 -14
- package/site/dist/assets/PhArrowUp-4sgyKPGx.js +0 -14
- package/site/dist/assets/PhArrowUpRight-BNghD2zq.js +0 -14
- package/site/dist/assets/PhArrowsClockwise-BXRn1GEl.js +0 -14
- package/site/dist/assets/PhArrowsDownUp-DM09Jo_3.js +0 -14
- package/site/dist/assets/PhArrowsLeftRight-MuKBLUoF.js +0 -14
- package/site/dist/assets/PhBank-fHbgCqqZ.js +0 -14
- package/site/dist/assets/PhBrowser-2-9m-AkM.js +0 -14
- package/site/dist/assets/PhCaretDown-BDNabFuL.js +0 -14
- package/site/dist/assets/PhCaretLeft-CI460R-A.js +0 -14
- package/site/dist/assets/PhCaretRight-D7ZS3Ls8.js +0 -14
- package/site/dist/assets/PhCaretUp-C-iIfyvO.js +0 -14
- package/site/dist/assets/PhCheck-DxQXn57r.js +0 -14
- package/site/dist/assets/PhCircleHalf-MJZeRBGF.js +0 -14
- package/site/dist/assets/PhClock-x3MS3Mwi.js +0 -14
- package/site/dist/assets/PhCompass-hYn3HhGN.js +0 -14
- package/site/dist/assets/PhCopy-CWNYcABI.js +0 -14
- package/site/dist/assets/PhCreditCard-Fy4pzwtt.js +0 -14
- package/site/dist/assets/PhCurrencyDollar-BgiaenCi.js +0 -14
- package/site/dist/assets/PhDesktop-CxrzCSv5.js +0 -14
- package/site/dist/assets/PhDeviceMobile-CsyA5Goi.js +0 -14
- package/site/dist/assets/PhDotsThree-D-k1BiYg.js +0 -14
- package/site/dist/assets/PhEnvelope-D8kzeNox.js +0 -14
- package/site/dist/assets/PhFunnelSimple-CfQs5DAW.js +0 -14
- package/site/dist/assets/PhGlobe-DvmSc9_A.js +0 -14
- package/site/dist/assets/PhIdentificationCard-CfkZm-5K.js +0 -14
- package/site/dist/assets/PhImage-Cf0J2ZfJ.js +0 -14
- package/site/dist/assets/PhInfo-Bwi51-2X.js +0 -14
- package/site/dist/assets/PhLightbulb-C4FZV7Es.js +0 -14
- package/site/dist/assets/PhMagnifyingGlass-C9u8jSCJ.js +0 -14
- package/site/dist/assets/PhPaperPlaneRight-zxQVvPLX.js +0 -14
- package/site/dist/assets/PhPlus-C4UoW-2n.js +0 -14
- package/site/dist/assets/PhPower-CFyWDmgD.js +0 -14
- package/site/dist/assets/PhPuzzlePiece-BjoNVfST.js +0 -14
- package/site/dist/assets/PhQrCode-CP3tFauY.js +0 -14
- package/site/dist/assets/PhQuestion-wOWJBd3G.js +0 -14
- package/site/dist/assets/PhQuestionMark-CV0k9C0Y.js +0 -14
- package/site/dist/assets/PhSealCheck-vIKzREuN.js +0 -14
- package/site/dist/assets/PhSignOut-CxELV-i0.js +0 -14
- package/site/dist/assets/PhSpinner-CGDmbzUd.js +0 -14
- package/site/dist/assets/PhTrash-C9PD0SAt.js +0 -14
- package/site/dist/assets/PhUser-0sWNXQeZ.js +0 -14
- package/site/dist/assets/PhVault-6JTskUcC.js +0 -14
- package/site/dist/assets/PhWarning-CoKs3gz6.js +0 -14
- package/site/dist/assets/PhWarningCircle-BXHw1fCt.js +0 -14
- package/site/dist/assets/PhX-DX0SFIqC.js +0 -14
- package/site/dist/assets/PhoneIcon-CZ47md80.js +0 -1
- package/site/dist/assets/PinInput-DbZ0b1i1-BrTXu3Km.js +0 -247
- package/site/dist/assets/PrivyPluginContext-DA-yS5vO-CY60yubk.js +0 -1
- package/site/dist/assets/QrCode-DbnZwlkH-CcMrWV5D.js +0 -22
- package/site/dist/assets/RecoveryOAuthStatusScreen-CsgtTI2x-DgeDnHOK.js +0 -1
- package/site/dist/assets/RecoveryPasswordCreateScreen-Be-qJ-LU-CvJJwLhK.js +0 -1
- package/site/dist/assets/RecoverySelectionScreen-D1iGtpmi-CADtGtSV.js +0 -7
- package/site/dist/assets/SIWXUtil-Cpiv91-M.js +0 -1
- package/site/dist/assets/Screen-D30meWsY-vEusJ7KX.js +0 -175
- package/site/dist/assets/ScreenHeader-CHmc4-Lu-BvGTLg53.js +0 -31
- package/site/dist/assets/ScreenLayout-OwaQQcxH-cfOTmyl0.js +0 -1
- package/site/dist/assets/SelectSourceAsset-CWFog6gm-DxYklZYs.js +0 -140
- package/site/dist/assets/SetAutomaticRecoveryScreen-BO_OEqAZ-oeqeo05x.js +0 -14
- package/site/dist/assets/SetWalletPasswordForm-DwCTVtAh-BxFee9UA.js +0 -11
- package/site/dist/assets/ShieldCheckIcon-eFjsosCA.js +0 -1
- package/site/dist/assets/SignRequestScreen-BHKv32KR-z8ixfIma.js +0 -26
- package/site/dist/assets/SolanaWalletConnector-C7Lqk-Wz-Bc_lvdiF.js +0 -1
- package/site/dist/assets/StackedContainer-B2vaEl56-Do5dXB8-.js +0 -24
- package/site/dist/assets/StandardSignAndSendTransactionScreen-CfhIXVtd-DudetZAc.js +0 -20
- package/site/dist/assets/Subtitle-CV-2yKE4-DV0o1av3.js +0 -13
- package/site/dist/assets/TelegramAuthScreen-UL9zLfO8-Bo3sONvf.js +0 -1
- package/site/dist/assets/Title-BnzYV3Is-C3qOPnO_.js +0 -7
- package/site/dist/assets/TodoList-DnyULl18-BvxvubbF.js +0 -36
- package/site/dist/assets/TransactionDetails-e9nesl30-WWflkOIi.js +0 -109
- package/site/dist/assets/TransactionErrorView-BDBNqA_f-CotYKcgf.js +0 -178
- package/site/dist/assets/TransferFromWalletScreen-Qvn1Yuno-sVFlWqa8.js +0 -31
- package/site/dist/assets/TransferOrBridgeLoadingScreen-Dl1I_iIz-CV2-mY19.js +0 -6
- package/site/dist/assets/TurnstileWrapper-B7sNddys-oPbuMTQt.js +0 -1
- package/site/dist/assets/UpdateEmailScreen-DVOhPV0H-D_mjSpAy.js +0 -1
- package/site/dist/assets/UpdatePhoneScreen-CXRswTNZ-6RLG0ahv.js +0 -1
- package/site/dist/assets/UserLimitReachedScreen-5we2DHn8-CaVN0bti.js +0 -1
- package/site/dist/assets/Value-DTgR824E-Bp6WGZZm.js +0 -27
- package/site/dist/assets/WalletCards-DH1rqayz-D3cOTb9x.js +0 -1
- package/site/dist/assets/WalletIcon-DOIZhb2l.js +0 -1
- package/site/dist/assets/WalletInfoCard-sq_2wgFg-bOqfl5MA.js +0 -29
- package/site/dist/assets/WalletInterstitialScreen-Sh7LfsAh-DWaVkMCA.js +0 -1
- package/site/dist/assets/WalletLink-DK5LB5Ha-DjUZvqs-.js +0 -20
- package/site/dist/assets/WalletOverflowButton-bfCnp-9T-B6P7DQXA.js +0 -1
- package/site/dist/assets/WarningBanner-ZZqCEtZK-Bc2YKZb7.js +0 -21
- package/site/dist/assets/__vite-browser-external-NciY4Vu1.js +0 -1
- package/site/dist/assets/_esm-BZP3cXTv.js +0 -1
- package/site/dist/assets/_esm-ZmzBJpEs.js +0 -6
- package/site/dist/assets/accounts-D4AXF17G.js +0 -1
- package/site/dist/assets/accounts-IkdFx9nq.js +0 -1
- package/site/dist/assets/analytics-mkkvFRju-BRBcadka.js +0 -1
- package/site/dist/assets/baseSepolia-Bn1j1Ysw.js +0 -1
- package/site/dist/assets/basic-Cz1YiCSk.js +0 -1575
- package/site/dist/assets/capitalizeFirstLetter-DmLYqXsO-DtOXx-2n.js +0 -1
- package/site/dist/assets/ccip-B1J3oTZx.js +0 -7
- package/site/dist/assets/ccip-Bd7261zy.js +0 -1
- package/site/dist/assets/ccip-D6EHKpjI.js +0 -1
- package/site/dist/assets/chain-scefkYIH.js +0 -5
- package/site/dist/assets/check-DHnllI8N.js +0 -1
- package/site/dist/assets/chevron-down-1y-r4bGO.js +0 -1
- package/site/dist/assets/circle-alert-OwxamXUX.js +0 -1
- package/site/dist/assets/circle-check-big-3sZGVC10.js +0 -1
- package/site/dist/assets/circle-x-DQjNUV9J.js +0 -1
- package/site/dist/assets/client-B-BpRtwY.js +0 -1
- package/site/dist/assets/client-BfIR1FvH.js +0 -9
- package/site/dist/assets/coinbase-DCPC2L_R-YEuIn3jh.js +0 -3
- package/site/dist/assets/copy-DMOX_yn7.js +0 -1
- package/site/dist/assets/core-GIEmxmAa.js +0 -12
- package/site/dist/assets/createLucideIcon-BsERoFTA.js +0 -1
- package/site/dist/assets/defineChain-B-SQDLTG.js +0 -1
- package/site/dist/assets/dijkstra-CY95afk4.js +0 -1
- package/site/dist/assets/dist-CoS6E-3x.js +0 -1
- package/site/dist/assets/dist-Cp6IXeJd.js +0 -1
- package/site/dist/assets/dist-CrNxmdZj.js +0 -1
- package/site/dist/assets/dist-DYGtf4F0.js +0 -16
- package/site/dist/assets/embed.worker-Cnl4VGr3.js +0 -1
- package/site/dist/assets/errors-BQ3N-RVt-CZPAWCgC.js +0 -1
- package/site/dist/assets/esm-C3DslVJx.js +0 -1
- package/site/dist/assets/esm-Ci1ogKuK.js +0 -1
- package/site/dist/assets/esm-Co94ENUV.js +0 -37
- package/site/dist/assets/esm-bb8SANZh.js +0 -1
- package/site/dist/assets/esm-n2lWo7kz.js +0 -1
- package/site/dist/assets/ethers-zTjbodk5-Cs648CnD.js +0 -1
- package/site/dist/assets/eventemitter3-Dzc_0Uq2.js +0 -1
- package/site/dist/assets/external-link-BBPG3rG7.js +0 -1
- package/site/dist/assets/farcaster-DPlSjvF5-CzBCmgyL.js +0 -1
- package/site/dist/assets/features-CuiHbgEJ.js +0 -2
- package/site/dist/assets/fingerprint-pattern-CjLtyIxB.js +0 -1
- package/site/dist/assets/floating-ui.react-DmaCfayr.js +0 -1
- package/site/dist/assets/floating-ui.react-dom-CaoMF8mP.js +0 -1
- package/site/dist/assets/formatErc20TokenAmount-BuPk9xcy-BVqOKQif.js +0 -1
- package/site/dist/assets/formatter-CVbp4SlJ.js +0 -1
- package/site/dist/assets/get-entropy-details-for-user-dHRH5Gpi-BNiOFXbK.js +0 -1
- package/site/dist/assets/getChainName-DjpPdUSc-DUyKDrnp.js +0 -1
- package/site/dist/assets/getErc20Balance-jXNpFf0N-q4bV8kQq.js +0 -1
- package/site/dist/assets/getErc20TokenInfo-BNTrzLMP-DcnTFrXN.js +0 -1
- package/site/dist/assets/getFormattedUsdFromLamports-De3U9GlO-Gx4_wxON.js +0 -1
- package/site/dist/assets/getUsdcMintAddress-BVgm9GRo-r2UnDeEy.js +0 -1
- package/site/dist/assets/guards-BIW-GiMJ-D3tWTQAR.js +0 -1
- package/site/dist/assets/hooks.module-BYZGfwDl.js +0 -1
- package/site/dist/assets/hourglass-D_GfQdJr.js +0 -1
- package/site/dist/assets/id-UqEwL2BI-CTlvRMA5.js +0 -1
- package/site/dist/assets/index-BdEw5wyl-kLbhqLbv.js +0 -1
- package/site/dist/assets/index-C2h3EneX.js +0 -8
- package/site/dist/assets/index-CWARkn2w-DxuckIFn.js +0 -61
- package/site/dist/assets/index-DvMddJcd-CNBb4VUn.js +0 -12
- package/site/dist/assets/index-YiCw0Y_x-Czl0tWfF.js +0 -436
- package/site/dist/assets/index.browser-B-i-Lj3J.js +0 -1
- package/site/dist/assets/index.browser-BMmUcykv.js +0 -1
- package/site/dist/assets/index.es-Crd0TyUS.js +0 -2
- package/site/dist/assets/index.es-DQbup1WG.js +0 -3
- package/site/dist/assets/isPaymentRequestAvailable-Bq1cemEn-Cjf3l05I.js +0 -1
- package/site/dist/assets/jsx-runtime-CndCZlyt.js +0 -1
- package/site/dist/assets/landmark-BZPqMFEf.js +0 -1
- package/site/dist/assets/lib-DGtzi2DK.js +0 -1
- package/site/dist/assets/localBatchGatewayRequest-B71J8sQ9.js +0 -29
- package/site/dist/assets/lock-DyN_c-ud.js +0 -1
- package/site/dist/assets/logger-CsXm3oIv-B0UYpNFI.js +0 -1
- package/site/dist/assets/mail-V_mcPb64.js +0 -1
- package/site/dist/assets/modal-context-CwmSeFcv-DPWNJrfK.js +0 -1
- package/site/dist/assets/native-BKj27wfc.js +0 -1
- package/site/dist/assets/ofetch.CWycOUEr-Duby3iHT.js +0 -1
- package/site/dist/assets/parseAbi-Csg-8t59.js +0 -2
- package/site/dist/assets/parseAbiParameters-BWbIMYe4.js +0 -1
- package/site/dist/assets/parseEther-CHS0GNkM.js +0 -1
- package/site/dist/assets/pkce-DXF0yKjP-7_VY-d83.js +0 -1
- package/site/dist/assets/preload-helper-CRzLMJPS.js +0 -1
- package/site/dist/assets/privy-context-81KmsBw2-DiR6-Yq8.js +0 -2
- package/site/dist/assets/property-DuZ9DLP4.js +0 -3
- package/site/dist/assets/react-BfYA1q0G.js +0 -1
- package/site/dist/assets/react-CK2HRI1t.js +0 -1
- package/site/dist/assets/react-DxGeY8B8.js +0 -1
- package/site/dist/assets/react-auth-sHnipzbS.js +0 -1
- package/site/dist/assets/react-dom-BI2Koe4o.js +0 -1
- package/site/dist/assets/reservoir-x-nGuZkT-BguVFH3D.js +0 -1
- package/site/dist/assets/rolldown-runtime-Bjp52BOI.js +0 -1
- package/site/dist/assets/safe-url-D7SRPu33-CkMedGro.js +0 -1
- package/site/dist/assets/secp256k1-BeYL8aZl.js +0 -1
- package/site/dist/assets/secp256k1-Bh4MSkhz.js +0 -1
- package/site/dist/assets/secp256k1-Ci4cqHl0.js +0 -1
- package/site/dist/assets/secp256k1-DsxXqbXv.js +0 -1
- package/site/dist/assets/secp256k1-N9RUmafO.js +0 -1
- package/site/dist/assets/serializeAuthorizationList-DGMik9Wx.js +0 -1
- package/site/dist/assets/serializeSignature-CWKpxoab.js +0 -2
- package/site/dist/assets/sha2-C6s7zZmb.js +0 -1
- package/site/dist/assets/shared-DRZUmnL5-BewE5wK8.js +0 -193
- package/site/dist/assets/shared-FM0rljBt-CxLACri_.js +0 -21
- package/site/dist/assets/shouldProceedtoEmbeddedWalletCreationFlow-B3vyavrh-BkAKsRNi.js +0 -1
- package/site/dist/assets/simulateTransaction-CfuOrae4-PjA_tGjX.js +0 -1
- package/site/dist/assets/smartphone-3p8nFSTE.js +0 -1
- package/site/dist/assets/src-BBjkfi-Q.js +0 -1
- package/site/dist/assets/storage-Ufl800Ne-1qCR2JMO.js +0 -8
- package/site/dist/assets/stringify-DqUj9VzO.js +0 -20
- package/site/dist/assets/stripe.esm-DEi2D291.js +0 -2
- package/site/dist/assets/styles-BsotlekN-Aq27nZGc.js +0 -9
- package/site/dist/assets/styles-Cm9H63WO-p_ic_dxE.js +0 -92
- package/site/dist/assets/styles-DVyDvTdj-CjsWqAld.js +0 -74
- package/site/dist/assets/styles-hslXy6xG-D5QHIrJU.js +0 -164
- package/site/dist/assets/telegram-B-JqnkqZ-Dqkm4rDn.js +0 -1
- package/site/dist/assets/to-ui-error-DWe-qwS3-Bi1HUQI9.js +0 -4
- package/site/dist/assets/toViemAccount-B5iDGq1b-CdFZwv07.js +0 -2
- package/site/dist/assets/transaction-BNTP-bFm-M5tJx8vY.js +0 -1
- package/site/dist/assets/transfer-6YztDh-t-BVQkTvG-.js +0 -1
- package/site/dist/assets/triangle-alert-BG3Qw-Hq.js +0 -1
- package/site/dist/assets/twitch-5IOe4sIQ-CaXHFlAu.js +0 -1
- package/site/dist/assets/types-4CuOD23i.js +0 -1
- package/site/dist/assets/use-headless-crypto-deposit-Yn-QRLB3-CQqeyhGY.js +0 -1
- package/site/dist/assets/use-unlink-wallet-BKK4_5Ur-C0xQN_Lp.js +0 -1
- package/site/dist/assets/useActiveWallet-B-yZYGc6-BkK6rFBm.js +0 -123
- package/site/dist/assets/useGetSolPrice-x7gfUIHJ-CLVXqv6I.js +0 -1
- package/site/dist/assets/useGetTokenPrice-CaoUkb79-DAXXs3rs.js +0 -1
- package/site/dist/assets/useI18n-C-5n_noF-CGpkgIVy.js +0 -1
- package/site/dist/assets/useWalletBalance-CZnP5f_f-Cfd64m4n.js +0 -1
- package/site/dist/assets/useWallets-X1ndvJ_U-CAYqg7Za.js +0 -1
- package/site/dist/assets/utils-BkR7EQjg.js +0 -1
- package/site/dist/assets/utils-DJhBNOZA.js +0 -1
- package/site/dist/assets/utils-DdckVfQr.js +0 -1
- package/site/dist/assets/w3m-modal-B4H_uiPH.js +0 -1174
- package/site/dist/assets/wallet-BNI12IYk.js +0 -1
- package/site/dist/assets/wallet-CITSaPlB.js +0 -2
- package/site/dist/assets/wallet-connect-BvJtUsDt-CVlSNIXP.js +0 -1
- package/site/dist/assets/walletconnect-registry-xxG8XLCb-BpzpBq5s.js +0 -1
- package/site/dist/assets/walletconnect-v2-3frQFwbg-CzZ6oybX.js +0 -12
- package/site/dist/assets/wui-ux-by-reown-XyHdtV1O.js +0 -1147
- package/site/dist/assets/x-gjDrY2rk.js +0 -1
- package/src/discover/explore.js +0 -291
- package/src/market/settle.js +0 -165
- package/src/market/terms.js +0 -200
- package/src/publish/cli.js +0 -336
- package/src/publish/envelope.js +0 -185
- package/src/publish/manifest.js +0 -142
package/src/core/roles.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
// on the next — which is exactly what happened the first time the probe was
|
|
6
6
|
// pointed at a second bundle.
|
|
7
7
|
//
|
|
8
|
-
// The answer is already baked. A
|
|
8
|
+
// The answer is already baked. A view's domain manifest carries `role_map`
|
|
9
9
|
// (which field is the title, the subtitle, the tags, the prose to search, the
|
|
10
10
|
// measures, the location, the link) and `presentation` (an icon, an accent and a
|
|
11
11
|
// singular/plural name per entity type, plus per-type external URL templates).
|
|
@@ -158,7 +158,7 @@ export function rolesFrom(manifests = [], sample = []) {
|
|
|
158
158
|
/**
|
|
159
159
|
* Which collection a row belongs to.
|
|
160
160
|
*
|
|
161
|
-
* `entityType` is
|
|
161
|
+
* `entityType` is the view's own convention — every row carries it, and
|
|
162
162
|
* the manifest's `entity_types` counts are keyed by it — so this is the one
|
|
163
163
|
* field name the format actually fixes. `kind` is the older spelling and is
|
|
164
164
|
* still on-chain in sond3r's vertices, hence the fallback.
|
|
@@ -249,7 +249,7 @@ export const isLocked = (field, roles) =>
|
|
|
249
249
|
/** Is this row part of the corpus's free sample — the deterministic slice a
|
|
250
250
|
* paywalled bake hands over whole so a buyer can read before paying?
|
|
251
251
|
*
|
|
252
|
-
* The bake picks it by hashing the row's own id (
|
|
252
|
+
* The bake picks it by hashing the row's own id (`inSample`),
|
|
253
253
|
* which is what stops a seller putting its best rows in the shop window. That
|
|
254
254
|
* only holds if someone CHECKS, and the check is this function: anyone can
|
|
255
255
|
* recompute which rows should be free and see whether the shard agrees. */
|
|
@@ -460,9 +460,9 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
|
|
|
460
460
|
if (gatesOf(rolesFrom([places])).length) throw new Error("an ungated view must report no gates");
|
|
461
461
|
if (isLocked("text", rolesFrom([places]))) throw new Error("nothing is locked in an ungated view");
|
|
462
462
|
|
|
463
|
-
// The free sample, recomputed. Must agree with
|
|
464
|
-
//
|
|
465
|
-
//
|
|
463
|
+
// The free sample, recomputed. Must agree with the bake's sample byte for byte or
|
|
464
|
+
// the check that keeps a seller honest checks nothing — these ids and their
|
|
465
|
+
// verdicts are pinned.
|
|
466
466
|
for (const [id, yes] of [["row-47", true], ["row-169", true], ["row-0", false], ["row-3", false], ["row-19", false]]) {
|
|
467
467
|
if (await inSample(id, 0.01) !== yes) throw new Error(`inSample must match the bake: ${id}`);
|
|
468
468
|
}
|
package/src/core/shard.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// Reading a
|
|
1
|
+
// Reading a VIEW's Semantic CDN shards (view.js's layout), in the consumer's own process.
|
|
2
2
|
//
|
|
3
3
|
// One view → one manifest per watched (owner, namespace) domain → N gzipped
|
|
4
4
|
// NDJSON shards, downloaded once, kept in memory, ranked locally — no index
|
|
@@ -139,7 +139,7 @@ export function setDomains(only) {
|
|
|
139
139
|
const wanted = (name) => !_only || _only.some((e) =>
|
|
140
140
|
name === e || name.split("/").pop() === e || name.startsWith(e));
|
|
141
141
|
|
|
142
|
-
const NO_VIEW = "no
|
|
142
|
+
const NO_VIEW = "no view configured — pass a view base, or wire one with configure({ resolveView })";
|
|
143
143
|
|
|
144
144
|
/** Fetch + parse a view's shards. Cached PER VIEW; concurrent callers share one
|
|
145
145
|
* fetch. Keyed by the resolved base, so two apps on screen in one session can't
|
|
@@ -347,7 +347,7 @@ async function load(view, onRows) {
|
|
|
347
347
|
// A view with nothing baked yet is the normal state of a brand-new one, not an
|
|
348
348
|
// error. Say which it is, or "search finds nothing" is indistinguishable from
|
|
349
349
|
// a URL pointing at the wrong view.
|
|
350
|
-
if (!domains.length) console.warn(`shard:
|
|
350
|
+
if (!domains.length) console.warn(`shard: view ${cdn} has no baked domains yet — nothing to read until its indexer bakes one.`);
|
|
351
351
|
|
|
352
352
|
const byId = new Map();
|
|
353
353
|
const dead = new Set();
|
|
@@ -666,7 +666,7 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
|
|
|
666
666
|
}
|
|
667
667
|
|
|
668
668
|
// ── the bake's packed vector (`v`), the form shipped today ──
|
|
669
|
-
// Pinned
|
|
669
|
+
// Pinned: [0,1,-1] -> "AH+B" (packVec in embed.js writes it). A
|
|
670
670
|
// drift here is not a crash, it is cosine ranking on noise.
|
|
671
671
|
{
|
|
672
672
|
await serveView({ d0: [[{ track_id: "p1", owner: "0xa", v: "AH+B", fields: { entityType: "file", name: "packed.md", path: "packed.md" } },
|
package/src/discover/apps.js
CHANGED
|
@@ -1,20 +1,15 @@
|
|
|
1
|
-
// The index of apps
|
|
1
|
+
// The index of apps, read off the chain.
|
|
2
2
|
//
|
|
3
|
-
// An app
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
// fetches the card and checks it names that app and is still the one bound on
|
|
8
|
-
// chain. The card then says where the data is (`views`) and where it starts
|
|
9
|
-
// (`fromBlock`).
|
|
3
|
+
// An app is a publisher's repo whose `@card` record points at an agent card that points back.
|
|
4
|
+
// So the directory is `repos()` (one scan of the update log), each repo's `@card` (one read
|
|
5
|
+
// per repo, cached by head), and `discoverCard` on each card found, which checks the binding.
|
|
6
|
+
// No registry, no relay, nobody's server in the loop.
|
|
10
7
|
//
|
|
11
|
-
// `fangorn` is an SDK client, passed in rather than imported, so this module
|
|
12
|
-
//
|
|
13
|
-
// Reads only: a reader can create one with a throwaway key.
|
|
8
|
+
// `fangorn` is an SDK client, passed in rather than imported, so this module stays usable
|
|
9
|
+
// where the SDK is not installed, and testable without a chain.
|
|
14
10
|
//
|
|
15
|
-
// ponytail: one flat list, no ranking
|
|
16
|
-
//
|
|
17
|
-
// fetching them all.
|
|
11
|
+
// ponytail: one flat list, no ranking, every card fetched. Past a few hundred apps, rank by
|
|
12
|
+
// the cards' own coverage instead.
|
|
18
13
|
|
|
19
14
|
/**
|
|
20
15
|
* A pointer someone else wrote, and following it is the one place a reader
|
|
@@ -29,9 +24,9 @@ function safeView(url) {
|
|
|
29
24
|
} catch { return null; }
|
|
30
25
|
}
|
|
31
26
|
|
|
32
|
-
/** The SDK's
|
|
27
|
+
/** The SDK's FANGORN_REPO_EXTENSION. Copied so this file needs no SDK;
|
|
33
28
|
* src/agent/agent-card.js's self-check fails if the two drift. */
|
|
34
|
-
export const APP_EXTENSION = "https://fangorn.network/a2a/
|
|
29
|
+
export const APP_EXTENSION = "https://fangorn.network/a2a/repo/v1";
|
|
35
30
|
|
|
36
31
|
/** The app's agent skill, `{url, sha256}`, when its card names one well-formed; else null. */
|
|
37
32
|
export const skillOf = (ext) => {
|
|
@@ -47,16 +42,19 @@ export const pluginOf = (ext) => {
|
|
|
47
42
|
return p && PLUGIN_MARKETPLACE.test(p.marketplace ?? "") && PLUGIN_NAME.test(p.name ?? "") ? { marketplace: p.marketplace, name: p.name } : null;
|
|
48
43
|
};
|
|
49
44
|
|
|
50
|
-
/** A verified card → an app entry. `views`
|
|
51
|
-
export function toApp({ card,
|
|
52
|
-
const
|
|
53
|
-
const views = (Array.isArray(
|
|
54
|
-
const
|
|
55
|
-
const paid = p && /^https?:\/\//.test(p.url ?? "") && p.url.includes("{id}") && /^\d+$/.test(String(p.price)) ? p : null;
|
|
45
|
+
/** A verified card (`discoverCard`'s result) → an app entry. `views` etc. are westmarch's params; the SDK ignores them. */
|
|
46
|
+
export function toApp({ card, publisher, repo }, cardUrl) {
|
|
47
|
+
const p = card.capabilities.extensions.find((e) => e.uri === APP_EXTENSION)?.params ?? {};
|
|
48
|
+
const views = (Array.isArray(p.views) ? p.views : []).map(safeView).filter(Boolean);
|
|
49
|
+
const paid = p.paid && /^https?:\/\//.test(p.paid.url ?? "") && p.paid.url.includes("{id}") ? { url: p.paid.url } : null;
|
|
56
50
|
return {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
51
|
+
id: `${publisher}:${repo}`, publisher, repo, card: cardUrl,
|
|
52
|
+
fromBlock: /^\d+$/.test(String(p.fromBlock)) ? BigInt(p.fromBlock) : null,
|
|
53
|
+
repos: Array.isArray(p.repos) ? p.repos.filter((r) => typeof r === "string") : [],
|
|
54
|
+
views, paid, skill: skillOf({ params: p }), plugin: pluginOf({ params: p }),
|
|
55
|
+
mcp: safeView(p.mcp),
|
|
56
|
+
tools: (card.skills ?? []).map((k) => k.id),
|
|
57
|
+
name: card.name ?? repo,
|
|
60
58
|
desc: card.description ?? "",
|
|
61
59
|
url: safeView(card.url),
|
|
62
60
|
};
|
|
@@ -80,29 +78,23 @@ export async function cachedLogs(store, key, start, head, read) {
|
|
|
80
78
|
}
|
|
81
79
|
|
|
82
80
|
/**
|
|
83
|
-
* Every app with a bound, verifiable card. The ones that fail are reported
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
* An app that cleared its uri (bound to "") is skipped. It is not an error.
|
|
88
|
-
*
|
|
89
|
-
* With a `store` (see cachedLogs) and `toBlock`, the logs read before are not
|
|
90
|
-
* read again; the cards are still all verified.
|
|
81
|
+
* Every app with a bound, verifiable card. The ones that fail are reported with the reason,
|
|
82
|
+
* not dropped: a card that is down and a card that lies look the same from outside, and an
|
|
83
|
+
* agent should see both. `store` ({ get, set }) caches each repo's card URL by head.
|
|
91
84
|
*/
|
|
92
|
-
export async function listApps(fangorn, { fromBlock,
|
|
93
|
-
|
|
94
|
-
const read = (from, to) => fangorn.getAppRegistry().getAppAgentLogs({ fromBlock: from, toBlock: to });
|
|
95
|
-
const logs = store && toBlock != null
|
|
96
|
-
? await cachedLogs(store, `AppAgentChanged:${fromBlock}`, BigInt(fromBlock), BigInt(toBlock), read)
|
|
97
|
-
: await read(BigInt(fromBlock), toBlock);
|
|
98
|
-
// Oldest first, so the last write wins. discoverApp re-reads the binding,
|
|
99
|
-
// so a stale uri here is caught there, not trusted.
|
|
100
|
-
const latest = new Map(logs.map((l) => [l.appId, l.agentUri]));
|
|
85
|
+
export async function listApps(fangorn, { fromBlock, store } = {}) {
|
|
86
|
+
const repos = await fangorn.repos(fromBlock == null ? {} : { fromBlock: BigInt(fromBlock) });
|
|
101
87
|
const apps = [], rejected = [];
|
|
102
|
-
await Promise.all(
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
88
|
+
await Promise.all(repos.map(async ({ owner, repo, root }) => {
|
|
89
|
+
const key = `card:${owner.toLowerCase()}/${repo}@${root}`;
|
|
90
|
+
let url = store?.get(key);
|
|
91
|
+
if (url === undefined) {
|
|
92
|
+
try { url = (await fangorn.cardOf(owner, repo)) ?? null; } catch { return; } // unreadable now: not cached, tried next time
|
|
93
|
+
store?.set(key, url);
|
|
94
|
+
}
|
|
95
|
+
if (!url) return;
|
|
96
|
+
try { apps.push(toApp(await fangorn.discoverCard(url), url)); }
|
|
97
|
+
catch (e) { rejected.push({ publisher: owner, repo, card: url, why: e?.message ?? String(e) }); }
|
|
106
98
|
}));
|
|
107
99
|
apps.sort((a, b) => a.name.localeCompare(b.name));
|
|
108
100
|
return { apps, rejected };
|
|
@@ -112,52 +104,46 @@ export async function listApps(fangorn, { fromBlock, toBlock, store } = {}) {
|
|
|
112
104
|
if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/apps.js")) {
|
|
113
105
|
const j = (x) => JSON.stringify(x, (_, v) => (typeof v === "bigint" ? `${v}n` : v));
|
|
114
106
|
const eq = (a, b, m) => { if (j(a) !== j(b)) throw new Error(`${m}: ${j(a)} != ${j(b)}`); };
|
|
115
|
-
const
|
|
116
|
-
const card = (
|
|
117
|
-
{ uri: "https://other/ext", params: {
|
|
118
|
-
{ uri:
|
|
107
|
+
const P = "0x" + "11".repeat(20), Q = "0x" + "22".repeat(20);
|
|
108
|
+
const card = (publisher, repo, name, views) => ({ name, description: `${name}!`, url: "https://x.test/", capabilities: { extensions: [
|
|
109
|
+
{ uri: "https://other/ext", params: { views: ["https://evil.test/"] } },
|
|
110
|
+
{ uri: APP_EXTENSION, params: { publisher, repo, fromBlock: "7", repos: ["n"], views } },
|
|
119
111
|
] } });
|
|
120
112
|
const cards = {
|
|
121
|
-
"https://a.test/card": card(
|
|
122
|
-
"https://
|
|
123
|
-
"https://b.test/card": card(B, "Alpha", []),
|
|
113
|
+
"https://a.test/card": card(P, "beta", "Beta", ["https://a.test/q/v1/stream", "javascript:alert(1)"]),
|
|
114
|
+
"https://b.test/card": card(Q, "alpha", "Alpha", []),
|
|
124
115
|
};
|
|
125
|
-
|
|
116
|
+
const bound = { [`${P}/beta`]: "https://a.test/card", [`${Q}/alpha`]: "https://b.test/card", [`${Q}/liar`]: "https://liar.test/card" };
|
|
117
|
+
let cardReads = 0;
|
|
126
118
|
const fangorn = {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
{
|
|
134
|
-
])) }),
|
|
135
|
-
discoverApp: async (uri) => {
|
|
136
|
-
if (uri === "https://liar.test/card") throw new Error("not bound to app");
|
|
137
|
-
const c = cards[uri];
|
|
138
|
-
return { card: c, appId: c.capabilities.extensions[1].params.appId, fromBlock: 7n, repos: ["n"] };
|
|
119
|
+
repos: async () => [{ owner: P, repo: "beta", root: "0x1" }, { owner: Q, repo: "alpha", root: "0x2" },
|
|
120
|
+
{ owner: Q, repo: "plain", root: "0x3" }, { owner: Q, repo: "liar", root: "0x4" }],
|
|
121
|
+
cardOf: async (o, r) => (cardReads++, bound[`${o}/${r}`]),
|
|
122
|
+
discoverCard: async (url) => {
|
|
123
|
+
if (url === "https://liar.test/card") throw new Error("not bound");
|
|
124
|
+
const c = cards[url], p = c.capabilities.extensions[1].params;
|
|
125
|
+
return { card: c, publisher: p.publisher, repo: p.repo };
|
|
139
126
|
},
|
|
140
127
|
};
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
eq(apps.map((a) => a.name), ["Alpha", "Beta"], "one entry per
|
|
128
|
+
const m = new Map(), store = { get: (k) => m.get(k), set: (k, v) => m.set(k, v) };
|
|
129
|
+
const { apps, rejected } = await listApps(fangorn, { store });
|
|
130
|
+
eq(apps.map((a) => a.name), ["Alpha", "Beta"], "one entry per carded repo, sorted, repos with no card skipped");
|
|
144
131
|
const beta = apps[1];
|
|
145
132
|
eq(beta.views, ["https://a.test/q/v1"], "views from the fangorn extension only, trimmed, non-http dropped");
|
|
146
|
-
eq([beta.
|
|
147
|
-
eq(rejected.map((r) => r.why), ["not bound
|
|
148
|
-
|
|
133
|
+
eq([beta.id, beta.card, beta.url, beta.fromBlock, beta.repos, beta.desc], [`${P}:beta`, "https://a.test/card", "https://x.test", 7n, ["n"], "Beta!"], "entry fields");
|
|
134
|
+
eq(rejected.map((r) => r.why), ["not bound"], "a card that fails verification is reported");
|
|
135
|
+
eq(cardReads, 4, "one @card read per repo");
|
|
136
|
+
await listApps(fangorn, { store });
|
|
137
|
+
eq(cardReads, 4, "an unchanged head is not read again");
|
|
149
138
|
|
|
150
|
-
const
|
|
139
|
+
const asked = [];
|
|
151
140
|
const chain = [{ blockNumber: 10n, n: 1 }, { blockNumber: 150n, n: 2 }, { blockNumber: 190n, n: 3 }];
|
|
152
141
|
const read = async (from, to) => (asked.push([from, to]), chain.filter((l) => l.blockNumber >= from && l.blockNumber <= to));
|
|
153
|
-
|
|
154
|
-
eq(
|
|
155
|
-
eq(
|
|
156
|
-
eq((await cachedLogs(
|
|
142
|
+
const lm = new Map(), ls = { get: (k) => lm.get(k), set: (k, v) => lm.set(k, v) };
|
|
143
|
+
eq((await cachedLogs(ls, "k", 5n, 200n, read)).map((l) => l.n), [1, 2, 3], "first call reads it all");
|
|
144
|
+
eq(lm.get("k").to, 136n, "stores only what is settled");
|
|
145
|
+
eq((await cachedLogs(ls, "k", 5n, 210n, read)).map((l) => l.n), [1, 2, 3], "second call: same logs, no duplicates");
|
|
157
146
|
eq(asked, [[5n, 200n], [137n, 210n]], "second call reads only from the settled point");
|
|
158
|
-
asked.length = 0;
|
|
159
|
-
await cachedLogs(store, "k", 5n, 146n, read);
|
|
160
|
-
eq(asked, [], "head at the stored point: no read");
|
|
161
147
|
|
|
162
|
-
console.log("apps.js self-check ok —
|
|
148
|
+
console.log("apps.js self-check ok — an app is a repo whose card verifies, cards read once per head, failures reported, views gated to http(s)");
|
|
163
149
|
}
|
|
@@ -62,7 +62,7 @@ export async function survey(sources = [], { timeoutMs = 8000 } = {}) {
|
|
|
62
62
|
for (const d of cat.domains ?? []) {
|
|
63
63
|
corpora.push({
|
|
64
64
|
view,
|
|
65
|
-
publisher: typeof src === "string" ? null : (src.name ?? src.
|
|
65
|
+
publisher: typeof src === "string" ? null : (src.name ?? src.id ?? null),
|
|
66
66
|
owner: typeof src === "string" ? null : (src.owner ?? null),
|
|
67
67
|
domain: d.name,
|
|
68
68
|
description: d.description || "",
|
|
@@ -164,7 +164,7 @@ export async function findCorpora(query, { sources = [], embed, model, limit = 1
|
|
|
164
164
|
* modules to run a survey. Rejected cards come back beside the sources. */
|
|
165
165
|
export async function sourcesFromChain(fangorn, opts) {
|
|
166
166
|
const { apps, rejected } = await listApps(fangorn, opts);
|
|
167
|
-
return { sources: apps.flatMap((a) => a.views.map((view) => ({ view, name: a.name,
|
|
167
|
+
return { sources: apps.flatMap((a) => a.views.map((view) => ({ view, name: a.name, id: a.id }))), rejected };
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// ── self-check: `node src/discover/directory.js` ─────────────────────────────────
|
package/src/market/reactions.js
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
// ------------------------------------------------------
|
|
17
17
|
// A reaction's vector is the vector of the row reacted to, which the reader
|
|
18
18
|
// already downloaded in order to react to it. So a reaction corpus needs no
|
|
19
|
-
// model, no GPU, no bake
|
|
19
|
+
// model, no GPU, no bake — the vectors are copied, not computed.
|
|
20
20
|
// The only thing that has to be fitted locally is `coverage`, which is eight
|
|
21
21
|
// centroids and is the function below. A consumer becoming a publisher is
|
|
22
22
|
// therefore not a tier you upgrade into; it is this file and a price.
|
|
@@ -51,7 +51,24 @@
|
|
|
51
51
|
// hat, and a reader with nine reactions is exactly who most needs this to hold.
|
|
52
52
|
|
|
53
53
|
import { EMBED_MODEL, packVec } from "../core/embed.js";
|
|
54
|
-
|
|
54
|
+
|
|
55
|
+
const ADDR = /^0x[0-9a-fA-F]{40}$/;
|
|
56
|
+
/** What a publisher owes upstream for one resource, in bps of its share. Deduped by payee:
|
|
57
|
+
* the same source cited twice is one debt, not two, which can't be gamed by repeating an entry. */
|
|
58
|
+
function lineage(entries = []) {
|
|
59
|
+
const by = new Map();
|
|
60
|
+
for (const e of entries) {
|
|
61
|
+
const to = String(e.to ?? "").toLowerCase();
|
|
62
|
+
if (!ADDR.test(to)) throw new Error(`not an address: ${e.to}`);
|
|
63
|
+
const b = BigInt(e.bps ?? 0);
|
|
64
|
+
if (b < 0n || b > 10000n) throw new Error(`lineage bps must be 0..10000, got ${e.bps}`);
|
|
65
|
+
by.set(to, { to, bps: (by.get(to)?.bps ?? 0n) + b, note: e.note ?? by.get(to)?.note ?? "" });
|
|
66
|
+
}
|
|
67
|
+
const out = [...by.values()];
|
|
68
|
+
const total = out.reduce((s, e) => s + e.bps, 0n);
|
|
69
|
+
if (total > 10000n) throw new Error(`lineage owes ${total} bps of the publisher's share — more than all of it`);
|
|
70
|
+
return out.map((e) => ({ to: e.to, bps: String(e.bps), ...(e.note ? { note: e.note } : {}) }));
|
|
71
|
+
}
|
|
55
72
|
|
|
56
73
|
// 32, not 8: on Kingsfoil the top 3 of 23 views held 92% of the true top 10 with 32
|
|
57
74
|
// centroids and 86% with 8, and 8 missed whole topics (ALS → neurology).
|
|
@@ -68,7 +85,7 @@ const dot = (a, b) => { let s = 0, n = Math.min(a.length, b.length); for (let i
|
|
|
68
85
|
* Spherical k-means over the corpus's own vectors — the routing summary that
|
|
69
86
|
* lets a buyer rank this corpus WITHOUT downloading it.
|
|
70
87
|
*
|
|
71
|
-
*
|
|
88
|
+
* The view's coverage: fit at full width, truncate to `dim`
|
|
72
89
|
* leading components (Matryoshka), then RENORMALIZE, because a truncated unit
|
|
73
90
|
* vector is not unit and the client compares against a truncated query it
|
|
74
91
|
* renormalizes too. Get that order wrong and routing degrades silently.
|
|
@@ -238,7 +255,6 @@ export function reactionCorpus(events = [], {
|
|
|
238
255
|
|
|
239
256
|
// ── self-check: `node src/market/reactions.js` ────────────────────────────────
|
|
240
257
|
if (typeof process !== "undefined" && import.meta.url === `file://${process.argv[1]}` && process.argv[1].endsWith("/reactions.js")) {
|
|
241
|
-
const { splitPayment } = await import("./terms.js");
|
|
242
258
|
const A = (n) => `0x${String(n).repeat(40).slice(0, 40)}`;
|
|
243
259
|
const vec = (a, b) => { const v = new Float32Array(256); v[0] = a; v[1] = b; return v; };
|
|
244
260
|
|
|
@@ -321,16 +337,6 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
|
|
|
321
337
|
if (bps["archive-films"] !== 1500 || bps.games !== 500) throw new Error(`upstream must follow contribution: ${JSON.stringify(bps)}`);
|
|
322
338
|
if (up.reduce((s, e) => s + Number(e.bps), 0) !== 2000) throw new Error("the declared upstream total must be exact, not a basis point short");
|
|
323
339
|
|
|
324
|
-
// …and it reconciles against a real sale. This is the claim: the corpora that
|
|
325
|
-
// produced the attention are paid when the attention sells.
|
|
326
|
-
const TERMS = { appId: "fangorn.tv", owner: A(9), appBps: 1000 };
|
|
327
|
-
const pay = splitPayment(300000n, { terms: TERMS, publisher: A(3), lineage: up });
|
|
328
|
-
const got = Object.fromEntries(pay.map((p) => [p.to, p.amount]));
|
|
329
|
-
if (got[A(9)] !== 30000n) throw new Error("the app's cut comes off the top and never moves");
|
|
330
|
-
if (got[A(1)] !== 40500n || got[A(2)] !== 13500n) throw new Error(`upstream is paid from the publisher's share: ${JSON.stringify(got, (k, v) => typeof v === "bigint" ? String(v) : v)}`);
|
|
331
|
-
if (got[A(3)] !== 216000n) throw new Error("the reader keeps the rest");
|
|
332
|
-
if (pay.reduce((s, p) => s + p.amount, 0n) !== 300000n) throw new Error("money is neither invented nor destroyed");
|
|
333
|
-
|
|
334
340
|
// A reader who cites a corpus nobody registered simply owes it nothing.
|
|
335
341
|
const orphan = reactionCorpus(EV, { publisher: A(3), sources: { games: A(2) } });
|
|
336
342
|
if (orphan.lineage.length !== 1 || Number(orphan.lineage[0].bps) !== 2000) throw new Error("an unregistered corpus cannot be paid, and its share does not vanish");
|
|
@@ -341,5 +347,5 @@ if (typeof process !== "undefined" && import.meta.url === `file://${process.argv
|
|
|
341
347
|
|
|
342
348
|
console.log("reactions.js self-check ok — reactions become a corpus with no model, coverage is deterministic and renormalized after truncation, "
|
|
343
349
|
+ "the free index ranks on centroids alone, publishes no per-row vector to join against and no paid string anywhere including its own keys, "
|
|
344
|
-
+ "time is coarse, upstream follows contribution exactly
|
|
350
|
+
+ "time is coarse, upstream follows contribution exactly");
|
|
345
351
|
}
|
package/src/publish/devnet.js
CHANGED
|
@@ -4,23 +4,56 @@
|
|
|
4
4
|
// scripts/e2e-worker.mjs run an app against, with nothing leaving the machine.
|
|
5
5
|
//
|
|
6
6
|
// Needs forge and anvil, and the contracts' source (FANGORN_CONTRACTS_DIR, default
|
|
7
|
-
// ../contracts
|
|
7
|
+
// ../contracts next to westmarch). USDC and Semaphore are the contracts' mocks: payments
|
|
8
|
+
// aren't checked and any proof is accepted.
|
|
9
|
+
//
|
|
10
|
+
// The services a deployment runs are here too, each its own Worker under `wrangler dev`, wired
|
|
11
|
+
// to this chain: `keyServer()` and `relay()` from the webworker checkout (FANGORN_WEBWORKER_DIR,
|
|
12
|
+
// default ../webworker), and `worker()` for any other, such as an app's.
|
|
8
13
|
|
|
9
14
|
import { spawn, spawnSync } from "node:child_process";
|
|
10
15
|
import { createServer } from "node:http";
|
|
11
|
-
import { readFileSync } from "node:fs";
|
|
16
|
+
import { mkdtempSync, readFileSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
12
18
|
import { createRequire } from "node:module";
|
|
13
|
-
import { dirname, resolve } from "node:path";
|
|
19
|
+
import { dirname, join, resolve } from "node:path";
|
|
14
20
|
import { fileURLToPath } from "node:url";
|
|
15
21
|
import { createTestClient, encodeFunctionData, getAddress, http, parseEther, publicActions, walletActions } from "viem";
|
|
16
22
|
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
17
|
-
import {
|
|
23
|
+
import { bytesToHex } from "viem";
|
|
24
|
+
import { DATA_REGISTRY_ABI, SETTLEMENT_REGISTRY_ABI, Fangorn, FangornConfig } from "@fangorn-network/sdk";
|
|
18
25
|
|
|
19
26
|
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
20
27
|
const ADMIN_KEY = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; // anvil's first account
|
|
28
|
+
/**
|
|
29
|
+
* The Worker in `dir` under `wrangler dev` with `vars`, on a free port: `{ url, kill }` once `probe`
|
|
30
|
+
* answers. Its own process group, so `kill` takes workerd down with wrangler. Local bindings only.
|
|
31
|
+
*/
|
|
32
|
+
export async function wranglerDev(dir, vars = {}, { config, probe = "/", name = dir, log = () => {} } = {}) {
|
|
33
|
+
const free = () => new Promise((ok) => { const s = createServer().listen(0, "127.0.0.1", () => { const p = s.address().port; s.close(() => ok(p)); }); });
|
|
34
|
+
// Its own inspector port too: two workers started at once both take wrangler's default (9229), and one dies.
|
|
35
|
+
const [port, inspector] = await Promise.all([free(), free()]);
|
|
36
|
+
const w = spawn("npx", ["wrangler", "dev", ...(config ? ["--config", config] : []), "--port", String(port), "--inspector-port", String(inspector), "--ip", "127.0.0.1",
|
|
37
|
+
"--persist-to", mkdtempSync(join(tmpdir(), "devnet-wrangler-")), ...Object.entries(vars).flatMap(([k, v]) => ["--var", `${k}:${v}`])],
|
|
38
|
+
{ cwd: dir, detached: true, stdio: ["ignore", "pipe", "pipe"], env: { ...process.env, NO_D1_WARNING: "true" } });
|
|
39
|
+
let out = "";
|
|
40
|
+
w.stdout.on("data", (c) => { out += c; }); w.stderr.on("data", (c) => { out += c; });
|
|
41
|
+
const kill = () => { try { process.kill(-w.pid); } catch { /* gone */ } };
|
|
42
|
+
process.on("exit", kill);
|
|
43
|
+
const url = `http://127.0.0.1:${port}`;
|
|
44
|
+
for (const t0 = Date.now(); ; await new Promise((r) => setTimeout(r, 500))) {
|
|
45
|
+
if (w.exitCode !== null) throw new Error(`${name}: wrangler dev exited\n${out.slice(-2000)}`);
|
|
46
|
+
if (Date.now() - t0 > 120_000) { kill(); throw new Error(`${name}: no answer at ${url}${probe} in 2 minutes\n${out.slice(-2000)}`); }
|
|
47
|
+
if (await fetch(`${url}${probe}`).then(() => true, () => false)) break;
|
|
48
|
+
}
|
|
49
|
+
log(`${name} at ${url}`);
|
|
50
|
+
return { url, kill };
|
|
51
|
+
}
|
|
52
|
+
|
|
21
53
|
const listen = (server) => new Promise((ok) => server.listen(0, "127.0.0.1", () => ok(`http://127.0.0.1:${server.address().port}`)));
|
|
22
54
|
|
|
23
|
-
export async function devnet({ contracts = process.env.FANGORN_CONTRACTS_DIR ?? resolve(HERE, "../../../contracts
|
|
55
|
+
export async function devnet({ contracts = process.env.FANGORN_CONTRACTS_DIR ?? resolve(HERE, "../../../contracts"),
|
|
56
|
+
webworker = process.env.FANGORN_WEBWORKER_DIR ?? resolve(HERE, "../../../webworker"), log = () => {} } = {}) {
|
|
24
57
|
const kids = [], servers = [];
|
|
25
58
|
const stop = () => { for (const k of kids) k.kill(); for (const s of servers) s.close(); };
|
|
26
59
|
process.on("exit", stop);
|
|
@@ -32,17 +65,18 @@ export async function devnet({ contracts = process.env.FANGORN_CONTRACTS_DIR ??
|
|
|
32
65
|
const rpcUrl = await new Promise((ok) => { let out = ""; anvil.stdout.on("data", (c) => { out += c; const m = /Listening on (\S+)/.exec(out); if (m) ok(`http://${m[1]}`); }); });
|
|
33
66
|
const chain = createTestClient({ mode: "anvil", chain: FangornConfig.chain, transport: http(rpcUrl) }).extend(publicActions).extend(walletActions);
|
|
34
67
|
const admin = privateKeyToAccount(ADMIN_KEY);
|
|
35
|
-
|
|
36
|
-
const
|
|
68
|
+
// `file`: the .sol it is in, when that isn't `n`.sol.
|
|
69
|
+
const artifact = (n, file = n) => { const j = JSON.parse(readFileSync(`${contracts}/out/${file}.sol/${n}.json`, "utf8")); return { abi: j.abi, bytecode: j.bytecode.object }; };
|
|
70
|
+
const deploy = async (n, args, file) => getAddress((await chain.waitForTransactionReceipt({ hash: await chain.deployContract({ account: admin, ...artifact(n, file), args }) })).contractAddress);
|
|
37
71
|
const proxied = async (n, init) => deploy("ERC1967Proxy", [await deploy(n, []), init]);
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
const
|
|
41
|
-
|
|
72
|
+
const data = await proxied("DataRegistry", encodeFunctionData({ abi: DATA_REGISTRY_ABI, functionName: "initialize", args: [admin.address] }));
|
|
73
|
+
const usdc = await deploy("MockUSDC", [], "Mocks");
|
|
74
|
+
const settlement = await proxied("SettlementRegistry", encodeFunctionData({ abi: SETTLEMENT_REGISTRY_ABI, functionName: "initialize",
|
|
75
|
+
args: [admin.address, usdc, await deploy("MockSemaphore", [], "Mocks")] }));
|
|
42
76
|
// As a Worker's CONFIG.deployment takes it: strings, no BigInt.
|
|
43
|
-
const deployment = {
|
|
44
|
-
const config = { ...FangornConfig, ...deployment,
|
|
45
|
-
log(`anvil ${rpcUrl},
|
|
77
|
+
const deployment = { dataRegistryContractAddress: data, settlementRegistryContractAddress: settlement, fromBlock: "0" };
|
|
78
|
+
const config = { ...FangornConfig, ...deployment, fromBlock: 0n, rpcUrl };
|
|
79
|
+
log(`anvil ${rpcUrl}, DataRegistry ${data}, SettlementRegistry ${settlement}`);
|
|
46
80
|
|
|
47
81
|
// ── storage: a content-addressed store, and the gateway that serves it ────
|
|
48
82
|
// multiformats, from the SDK's own dependencies.
|
|
@@ -65,10 +99,10 @@ export async function devnet({ contracts = process.env.FANGORN_CONTRACTS_DIR ??
|
|
|
65
99
|
servers.push(gateway);
|
|
66
100
|
const gatewayUrl = await listen(gateway);
|
|
67
101
|
|
|
68
|
-
/** A funded
|
|
69
|
-
const client = async (
|
|
102
|
+
/** A funded client. */
|
|
103
|
+
const client = async (privateKey = generatePrivateKey()) => {
|
|
70
104
|
await chain.setBalance({ address: privateKeyToAccount(privateKey).address, value: parseEther("1") });
|
|
71
|
-
return Fangorn.create({ privateKey, config,
|
|
105
|
+
return Fangorn.create({ privateKey, config, storage: { backend } });
|
|
72
106
|
};
|
|
73
107
|
|
|
74
108
|
/** An encoder on localhost that answers as the AI binding does: POST {text} → {data}; GET → the embedder it is. */
|
|
@@ -91,5 +125,22 @@ export async function devnet({ contracts = process.env.FANGORN_CONTRACTS_DIR ??
|
|
|
91
125
|
return listen(server);
|
|
92
126
|
};
|
|
93
127
|
|
|
94
|
-
|
|
128
|
+
// ── Workers, wired to this chain ─────────────────────────────────────────
|
|
129
|
+
const worker = (dir, vars, opts) => wranglerDev(dir, vars, { log, ...opts }).then(({ url, kill }) => (kids.push({ kill }), url));
|
|
130
|
+
|
|
131
|
+
/** The key server (fangorn-access-worker), with a fresh X25519 secret. */
|
|
132
|
+
const keyServer = () => worker(join(webworker, "fangorn-access-worker"),
|
|
133
|
+
{ WORKER_X25519_SECRET: bytesToHex(crypto.getRandomValues(new Uint8Array(32))), SETTLEMENT_REGISTRY: settlement, RPC_URL: rpcUrl },
|
|
134
|
+
{ probe: "/pubkey", name: "key server" });
|
|
135
|
+
|
|
136
|
+
/** Barliman, paying gas from a funded treasury key; `treasury` is the referrer on every register. */
|
|
137
|
+
const relay = async (treasury = privateKeyToAccount(generatePrivateKey()).address) => {
|
|
138
|
+
const key = generatePrivateKey();
|
|
139
|
+
await chain.setBalance({ address: privateKeyToAccount(key).address, value: parseEther("10") });
|
|
140
|
+
const url = await worker(join(webworker, "barliman"), { TREASURY_KEY: key, TREASURY: treasury, RPC_URL: rpcUrl,
|
|
141
|
+
DATA_REGISTRY: data, SETTLEMENT_REGISTRY: settlement }, { probe: "/supported", name: "relay (Barliman)" });
|
|
142
|
+
return { url, treasury };
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
return { rpcUrl, deployment, config, chain, usdc, backend, gatewayUrl, client, encoder, worker, keyServer, relay, stop, kids };
|
|
95
146
|
}
|
package/src/publish/init.js
CHANGED
|
@@ -41,7 +41,7 @@ export function init(app, dir = app, { install = true, log = console.log } = {})
|
|
|
41
41
|
}
|
|
42
42
|
log(`${app} is in ${dir}. Next:
|
|
43
43
|
1. app.json: the description, and the type's fields (role_map)
|
|
44
|
-
2. npx westmarch-ship app.json #
|
|
44
|
+
2. npx westmarch-ship app.json # creates the repo ${app}, deploys the Worker, registers its agent`);
|
|
45
45
|
return dir;
|
|
46
46
|
}
|
|
47
47
|
|